3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-07-06 07:16:13 +00:00
* reorg sls

* sls

* na

* split into base and plugin

* move sat_params to params directory, add op_def repair options

* move sat_ddfw to sls, initiate sls-bv-plugin

* porting bv-sls

* adding basic plugin

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add sls-sms solver

* bv updates

* updated dependencies

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* updated dependencies

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* use portable ptr-initializer

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* move definitions to cpp

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* use template<> syntax

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix compiler errors for gcc

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Bump docker/build-push-action from 6.0.0 to 6.1.0 (#7265)

Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.0.0 to 6.1.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6.0.0...v6.1.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* set clean shutdown for local search and re-enable local search when it parallelizes with PB solver

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Bump docker/build-push-action from 6.1.0 to 6.2.0 (#7269)

Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6.1.0...v6.2.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Fix a comment for Z3_solver_from_string (#7271)

Z3_solver_from_string accepts a string buffer with solver
assertions, not a string buffer with filename.

* trigger the build with a comment change

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* remove macro distinction #7270

* fix #7268

* kludge to address #7232, probably superseeded by planned revision to setup/pypi

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add new ema invariant (#7288)

* Bump docker/build-push-action from 6.2.0 to 6.3.0 (#7280)

Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.2.0 to 6.3.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6.2.0...v6.3.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* merge

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix unit test build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove shared attribute

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove stale files

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix build of unit test

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes and rename sls-cc to sls-euf-plugin

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* testing / debugging arithmetic

* updates to repair logic, mainly arithmetic

* fixes to sls

* evolve sls arith

* bugfixes in sls-arith

* fix typo

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* bug fixes

* Update sls_test.cpp

* fixes

* fixes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* refactor basic plugin and clause generation

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes to ite and other

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* updates

* update

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix division by 0

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disable fail restart

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disable tabu when using reset moves

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* update sls_test

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add factoring

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes to semantics

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* re-add tabu override

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* generalize factoring

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix bug

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove restart

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disable tabu in fallback modes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* localize impact of factoring

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* delay factoring

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* flatten products

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* perform lookahead update + nested mul

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disable nested mul

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disable nested mul, use non-lookahead

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* make reset updates recursive

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* include linear moves

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* include 5% reset probability

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* separate linear update

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* separate linear update remove 20% threshold

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove linear opt

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* enable multiplier expansion, enable linear move

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* use unit coefficients for muls

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disable non-tabu version of find_nl_moves

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove coefficient from multiplication definition

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* reorg monomials

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add smt params to path

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* avoid negative reward

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* use reward as proxy for score

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* use reward as proxy for score

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* use exponential decay with breaks

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* use std::pow

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes to bv

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes to fixed

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixup repairs

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* reserve for multiplication

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixing repair

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* include bounds checks in set random

* na

* fixes to mul

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix mul inverse

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes to handling signed operators

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* logging and fixes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* gcm

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* peli

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Add .env to gitignore to prevent environment files from being tracked

* Add m_num_pelis counter to stats in sls_context

* Remove m_num_pelis member from stats struct in sls_context

* Enhance bv_sls_eval with improved repair and logging, refine is_bv_predicate in sls_bv_plugin

* Remove verbose logging in register_term function of sls_basic_plugin and fix formatting in sls_context

* Rename source files for consistency in `src/ast/sls` directory

* Refactor bv_sls files to sls_bv with namespace and class name adjustments

* Remove typename from member declarations in bv_fixed class

* fixing conca

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Add initial implementation of bit-vector SLS evaluation module in bv_sls_eval.cpp

* Remove bv_sls_eval.cpp as part of code cleanup and refactoring

* Refactor alignment of member variables in bv_plugin of sls namespace

* Rename SLS engine related files to reflect their specific use for bit-vectors

* Refactor SLS engine and evaluator components for bit-vector specifics and adjust memory manager alignment

* Enhance bv_eval with use_current, lookahead strategies, and randomization improvements in SLS module

* Refactor verbose logging and fix logic in range adjustment functions in sls bv modules

* Remove commented verbose output in sls_bv_plugin.cpp during repair process

* Add early return after setting fixed subterms in sls_bv_fixed.cpp

* Remove redundant return statement in sls_bv_fixed.cpp

* fixes to new value propagation

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Refactor sls bv evaluation and fix logic checks for bit operations

* Add array plugin support and update bv_eval in ast_sls module

* Add array, model value, and user sort plugins to SLS module with enhancements in array propagation logic

* Refactor array_plugin in sls to improve handling of select expressions with multiple arguments

* Enhance array plugin with early termination and propagation verification, and improve euf and user sort plugins with propagation adjustments and debugging enhancements

* Add support for handling 'distinct' expressions in SLS context and user sort plugin

* Remove model value and user sort plugins from SLS theory

* replace user plugin by euf plugin

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove extra file

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Refactor handling of term registration and enhance distinct handling in sls_euf_plugin

* Add TODO list for enhancements in sls_euf_plugin.cpp

* add incremental mode

* updated package

* fix sls build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* break sls build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix build

* break build again

* fix build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixing incremental

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* avoid units

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixup handling of disequality propagation

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fx

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* recover shift-weight loop

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* alternate

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* throttle save model

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* allow for alternating

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix test for new signature of flip

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* bug fixes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* restore use of value_hash

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* adding dt plugin

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* adt

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* dt updates

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* added cycle detection

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* updated sls-datatype

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Refactor context management, improve datatype handling, and enhance logging in sls plugins.

* axiomatize dt

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add missing factory plugins to model

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixup finite domain search

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixup finite domain search

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* redo dfs

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixing model construction for underspecified operators

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes to occurs check

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixup interpretation building

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* saturate worklist

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* delay distinct axiom

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* adding model-based sls for datatatypes

* update the interface in sls_solver to transfer phase between SAT and SLS

* add value transfer option

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* rename aux functions

* Track shared variables using a unit set

* debugging parallel integration

* fix dirty flag setting

* update log level

* add plugin to smt_context, factor out sls_smt_plugin functionality.

* bug fixes

* fixes

* use common infrastructure for sls-smt

* fix build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove declaration of context

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add virtual destructor

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* build warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* reorder inclusion order to define smt_context before theory_sls

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* change namespace for single threaded

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* check delayed eqs before nla

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* use independent completion flag for sls to avoid conflating with genuine cancelation

* validate sls-arith lemmas

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* bugfixes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add intblast to legacy SMT solver

* fixup model generation for theory_intblast

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* mk_value needs to accept more cases where integer expression doesn't evalate

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* use th-axioms to track origins of assertions

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add missing operator handling for bitwise operators

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add missing operator handling for bitwise operators

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* normalizing inequality

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add virtual destructor

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* rework elim_unconstrained

* fix non-termination

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* use glue as computed without adjustment

* update model generation to fix model bug

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes to model construction

* remove package and package lock

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix build warning

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* use original gai

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

---------

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sergey Bronnikov <estetus@gmail.com>
Co-authored-by: Lev Nachmanson <levnach@hotmail.com>
Co-authored-by: LiviaSun <33578456+ChuyueSun@users.noreply.github.com>
This commit is contained in:
Nikolaj Bjorner 2024-11-02 12:32:48 -07:00 committed by GitHub
parent ecdfab81a6
commit 91dc02d862
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
120 changed files with 11172 additions and 4148 deletions

View file

@ -22,6 +22,10 @@ Author:
namespace intblast {
void translator_trail::push(push_back_vector<expr_ref_vector> const& c) { ctx.push(c); }
void translator_trail::push(push_back_vector<ptr_vector<app>> const& c) { ctx.push(c); }
void translator_trail::push_idx(set_vector_idx_trail<expr_ref_vector> const& c) { ctx.push(c); }
solver::solver(euf::solver& ctx) :
th_euf_solver(ctx, symbol("intblast"), ctx.get_manager().get_family_id("bv")),
ctx(ctx),
@ -29,9 +33,8 @@ namespace intblast {
m(ctx.get_manager()),
bv(m),
a(m),
m_translate(m),
m_args(m),
m_pinned(m)
trail(ctx),
m_translator(m, trail)
{}
euf::theory_var solver::mk_var(euf::enode* n) {
@ -85,49 +88,22 @@ namespace intblast {
SASSERT(!n->is_attached_to(get_id()));
mk_var(n);
SASSERT(n->is_attached_to(get_id()));
internalize_bv(a);
m_translator.internalize_bv(a);
return true;
}
void solver::eq_internalized(euf::enode* n) {
expr* e = n->get_expr();
expr* x = nullptr, * y = nullptr;
VERIFY(m.is_eq(n->get_expr(), x, y));
SASSERT(bv.is_bv(x));
if (!is_translated(e)) {
ensure_translated(x);
ensure_translated(y);
m_args.reset();
m_args.push_back(a.mk_sub(translated(x), translated(y)));
set_translated(e, m.mk_eq(umod(x, 0), a.mk_int(0)));
}
m_preds.push_back(e);
TRACE("bv", tout << mk_pp(e, m) << " " << mk_pp(translated(e), m) << "\n");
ctx.push(push_back_vector(m_preds));
}
void solver::set_translated(expr* e, expr* r) {
SASSERT(r);
SASSERT(!is_translated(e));
m_translate.setx(e->get_id(), r);
ctx.push(set_vector_idx_trail(m_translate, e->get_id()));
}
void solver::internalize_bv(app* e) {
ensure_translated(e);
if (m.is_bool(e)) {
m_preds.push_back(e);
ctx.push(push_back_vector(m_preds));
}
m_translator.translate_eq(n->get_expr());
}
bool solver::add_bound_axioms() {
if (m_vars_qhead == m_vars.size())
auto const& vars = m_translator.vars();
if (m_vars_qhead == vars.size())
return false;
ctx.push(value_trail(m_vars_qhead));
for (; m_vars_qhead < m_vars.size(); ++m_vars_qhead) {
auto v = m_vars[m_vars_qhead];
auto w = translated(v);
for (; m_vars_qhead < vars.size(); ++m_vars_qhead) {
auto v = vars[m_vars_qhead];
auto w = m_translator.translated(v);
auto sz = rational::power_of_two(bv.get_bv_size(v->get_sort()));
auto lo = ctx.mk_literal(a.mk_ge(w, a.mk_int(0)));
auto hi = ctx.mk_literal(a.mk_le(w, a.mk_int(sz - 1)));
@ -140,12 +116,13 @@ namespace intblast {
}
bool solver::add_predicate_axioms() {
if (m_preds_qhead == m_preds.size())
auto const& preds = m_translator.preds();
if (m_preds_qhead == preds.size())
return false;
ctx.push(value_trail(m_preds_qhead));
for (; m_preds_qhead < m_preds.size(); ++m_preds_qhead) {
expr* e = m_preds[m_preds_qhead];
expr_ref r(translated(e), m);
for (; m_preds_qhead < preds.size(); ++m_preds_qhead) {
expr* e = preds[m_preds_qhead];
expr_ref r(m_translator.translated(e), m);
ctx.get_rewriter()(r);
auto a = expr2literal(e);
auto b = mk_literal(r);
@ -158,31 +135,7 @@ namespace intblast {
bool solver::unit_propagate() {
return add_bound_axioms() || add_predicate_axioms();
}
void solver::ensure_translated(expr* e) {
if (m_translate.get(e->get_id(), nullptr))
return;
ptr_vector<expr> todo;
ast_fast_mark1 visited;
todo.push_back(e);
visited.mark(e);
for (unsigned i = 0; i < todo.size(); ++i) {
expr* e = todo[i];
if (!is_app(e))
continue;
app* a = to_app(e);
if (m.is_bool(e) && a->get_family_id() != bv.get_family_id())
continue;
for (auto arg : *a)
if (!visited.is_marked(arg) && !m_translate.get(arg->get_id(), nullptr)) {
visited.mark(arg);
todo.push_back(arg);
}
}
std::stable_sort(todo.begin(), todo.end(), [&](expr* a, expr* b) { return get_depth(a) < get_depth(b); });
for (expr* e : todo)
translate_expr(e);
}
}
lbool solver::check_axiom(sat::literal_vector const& lits) {
sat::literal_vector core;
@ -198,14 +151,10 @@ namespace intblast {
}
lbool solver::check_core(sat::literal_vector const& lits, euf::enode_pair_vector const& eqs) {
m_core.reset();
m_vars.reset();
m_is_plugin = false;
m_translator.reset(false);
m_solver = mk_smt2_solver(m, s.params(), symbol::null);
for (unsigned i = 0; i < m_translate.size(); ++i)
m_translate[i] = nullptr;
expr_ref_vector es(m), original_es(m);
for (auto lit : lits)
es.push_back(ctx.literal2expr(lit));
@ -222,8 +171,8 @@ namespace intblast {
translate(es);
for (auto e : m_vars) {
auto v = translated(e);
for (auto e : m_translator.vars()) {
auto v = m_translator.translated(e);
auto b = rational::power_of_two(bv.get_bv_size(e));
m_solver->assert_expr(a.mk_le(a.mk_int(0), v));
m_solver->assert_expr(a.mk_lt(v, a.mk_int(b)));
@ -331,8 +280,8 @@ namespace intblast {
translate(es);
for (auto e : m_vars) {
auto v = translated(e);
for (auto e : m_translator.vars()) {
auto v = m_translator.translated(e);
auto b = rational::power_of_two(bv.get_bv_size(e));
m_solver->assert_expr(a.mk_le(a.mk_int(0), v));
m_solver->assert_expr(a.mk_lt(v, a.mk_int(b)));
@ -377,7 +326,7 @@ namespace intblast {
void solver::sorted_subterms(expr_ref_vector& es, ptr_vector<expr>& sorted) {
expr_fast_mark1 visited;
for (expr* e : es) {
if (is_translated(e))
if (m_translator.is_translated(e))
continue;
if (visited.is_marked(e))
continue;
@ -389,7 +338,7 @@ namespace intblast {
if (is_app(e)) {
app* a = to_app(e);
for (expr* arg : *a) {
if (!visited.is_marked(arg) && !is_translated(arg)) {
if (!visited.is_marked(arg) && !m_translator.is_translated(arg)) {
visited.mark(arg);
sorted.push_back(arg);
}
@ -399,7 +348,7 @@ namespace intblast {
else if (is_quantifier(e)) {
quantifier* q = to_quantifier(e);
expr* b = q->get_expr();
if (!visited.is_marked(b) && !is_translated(b)) {
if (!visited.is_marked(b) && !m_translator.is_translated(b)) {
visited.mark(b);
sorted.push_back(b);
}
@ -414,20 +363,20 @@ namespace intblast {
sorted_subterms(es, todo);
for (expr* e : todo)
translate_expr(e);
m_translator.translate_expr(e);
TRACE("bv",
for (expr* e : es)
tout << mk_pp(e, m) << "\n->\n" << mk_pp(translated(e), m) << "\n";
tout << mk_pp(e, m) << "\n->\n" << mk_pp(m_translator.translated(e), m) << "\n";
);
for (unsigned i = 0; i < es.size(); ++i)
es[i] = translated(es.get(i));
es[i] = m_translator.translated(es.get(i));
}
sat::check_result solver::check() {
// ensure that bv2int is injective
for (auto e : m_bv2int) {
for (auto e : m_translator.bv2int()) {
euf::enode* n = expr2enode(e);
euf::enode* r1 = n->get_arg(0)->get_root();
for (auto sib : euf::enode_class(n)) {
@ -449,7 +398,7 @@ namespace intblast {
}
// ensure that int2bv respects values
// bv2int(int2bv(x)) = x mod N
for (auto e : m_int2bv) {
for (auto e : m_translator.int2bv()) {
auto n = expr2enode(e);
auto x = n->get_arg(0)->get_expr();
auto bv2int = bv.mk_bv2int(e);
@ -469,595 +418,12 @@ namespace intblast {
return sat::check_result::CR_DONE;
}
bool solver::is_bounded(expr* x, rational const& N) {
return any_of(m_vars, [&](expr* v) {
return is_translated(v) && translated(v) == x && bv_size(v) <= N;
});
}
bool solver::is_non_negative(expr* bv_expr, expr* e) {
auto N = rational::power_of_two(bv.get_bv_size(bv_expr));
rational r;
if (a.is_numeral(e, r))
return r >= 0;
if (is_bounded(e, N))
return true;
expr* x = nullptr, * y = nullptr;
if (a.is_mul(e, x, y))
return is_non_negative(bv_expr, x) && is_non_negative(bv_expr, y);
if (a.is_add(e, x, y))
return is_non_negative(bv_expr, x) && is_non_negative(bv_expr, y);
return false;
}
expr* solver::umod(expr* bv_expr, unsigned i) {
expr* x = arg(i);
rational N = bv_size(bv_expr);
return amod(bv_expr, x, N);
}
expr* solver::smod(expr* bv_expr, unsigned i) {
expr* x = arg(i);
auto N = bv_size(bv_expr);
auto shift = N / 2;
rational r;
if (a.is_numeral(x, r))
return a.mk_int(mod(r + shift, N));
return amod(bv_expr, add(x, a.mk_int(shift)), N);
}
expr_ref solver::mul(expr* x, expr* y) {
expr_ref _x(x, m), _y(y, m);
if (a.is_zero(x))
return _x;
if (a.is_zero(y))
return _y;
if (a.is_one(x))
return _y;
if (a.is_one(y))
return _x;
rational v1, v2;
if (a.is_numeral(x, v1) && a.is_numeral(y, v2))
return expr_ref(a.mk_int(v1 * v2), m);
_x = a.mk_mul(x, y);
return _x;
}
expr_ref solver::add(expr* x, expr* y) {
expr_ref _x(x, m), _y(y, m);
if (a.is_zero(x))
return _y;
if (a.is_zero(y))
return _x;
rational v1, v2;
if (a.is_numeral(x, v1) && a.is_numeral(y, v2))
return expr_ref(a.mk_int(v1 + v2), m);
_x = a.mk_add(x, y);
return _x;
}
/*
* Perform simplifications that are claimed sound when the bit-vector interpretations of
* mod/div always guard the mod and dividend to be non-zero.
* Potentially shady area is for arithmetic expressions created by int2bv.
* They will be guarded by a modulus which does not disappear.
*/
expr* solver::amod(expr* bv_expr, expr* x, rational const& N) {
rational v;
expr* r = nullptr, *c = nullptr, * t = nullptr, * e = nullptr;
if (m.is_ite(x, c, t, e))
r = m.mk_ite(c, amod(bv_expr, t, N), amod(bv_expr, e, N));
else if (a.is_idiv(x, t, e) && a.is_numeral(t, v) && 0 <= v && v < N && is_non_negative(bv_expr, e))
r = x;
else if (a.is_mod(x, t, e) && a.is_numeral(t, v) && 0 <= v && v < N)
r = x;
else if (a.is_numeral(x, v))
r = a.mk_int(mod(v, N));
else if (is_bounded(x, N))
r = x;
else
r = a.mk_mod(x, a.mk_int(N));
return r;
}
rational solver::bv_size(expr* bv_expr) {
return rational::power_of_two(bv.get_bv_size(bv_expr->get_sort()));
}
void solver::translate_expr(expr* e) {
if (is_quantifier(e))
translate_quantifier(to_quantifier(e));
else if (is_var(e))
translate_var(to_var(e));
else {
app* ap = to_app(e);
if (m_is_plugin && ap->get_family_id() == basic_family_id && m.is_bool(ap)) {
set_translated(e, e);
return;
}
m_args.reset();
for (auto arg : *ap)
m_args.push_back(translated(arg));
if (ap->get_family_id() == basic_family_id)
translate_basic(ap);
else if (ap->get_family_id() == bv.get_family_id())
translate_bv(ap);
else
translate_app(ap);
}
}
void solver::translate_quantifier(quantifier* q) {
if (m_is_plugin) {
set_translated(q, q);
return;
}
if (is_lambda(q))
throw default_exception("lambdas are not supported in intblaster");
expr* b = q->get_expr();
unsigned nd = q->get_num_decls();
ptr_vector<sort> sorts;
for (unsigned i = 0; i < nd; ++i) {
auto s = q->get_decl_sort(i);
if (bv.is_bv_sort(s)) {
NOT_IMPLEMENTED_YET();
sorts.push_back(a.mk_int());
}
else
sorts.push_back(s);
}
b = translated(b);
// TODO if sorts contain integer, then created bounds variables.
set_translated(q, m.update_quantifier(q, b));
}
void solver::translate_var(var* v) {
if (bv.is_bv_sort(v->get_sort()))
set_translated(v, m.mk_var(v->get_idx(), a.mk_int()));
else
set_translated(v, v);
}
// Translate functions that are not built-in or bit-vectors.
// Base method uses fresh functions.
// Other method could use bv2int, int2bv axioms and coercions.
// f(args) = bv2int(f(int2bv(args'))
//
void solver::translate_app(app* e) {
if (m_is_plugin && m.is_bool(e)) {
set_translated(e, e);
return;
}
bool has_bv_sort = bv.is_bv(e);
func_decl* f = e->get_decl();
for (unsigned i = 0; i < m_args.size(); ++i)
if (bv.is_bv(e->get_arg(i)))
m_args[i] = bv.mk_int2bv(bv.get_bv_size(e->get_arg(i)), m_args.get(i));
if (has_bv_sort)
m_vars.push_back(e);
if (m_is_plugin) {
expr* r = m.mk_app(f, m_args);
if (has_bv_sort) {
ctx.push(push_back_vector(m_vars));
r = bv.mk_bv2int(r);
}
set_translated(e, r);
return;
}
else if (has_bv_sort) {
if (f->get_family_id() != null_family_id)
throw default_exception("conversion for interpreted functions is not supported by intblast solver");
func_decl* g = nullptr;
if (!m_new_funs.find(f, g)) {
g = m.mk_fresh_func_decl(e->get_decl()->get_name(), symbol("bv"), f->get_arity(), f->get_domain(), a.mk_int());
m_new_funs.insert(f, g);
}
f = g;
m_pinned.push_back(f);
}
set_translated(e, m.mk_app(f, m_args));
}
void solver::translate_bv(app* e) {
auto bnot = [&](expr* e) {
return a.mk_sub(a.mk_int(-1), e);
};
auto band = [&](expr_ref_vector const& args) {
expr* r = arg(0);
for (unsigned i = 1; i < args.size(); ++i)
r = a.mk_band(bv.get_bv_size(e), r, arg(i));
return r;
};
auto rotate_left = [&](unsigned n) {
auto sz = bv.get_bv_size(e);
n = n % sz;
expr* r = arg(0);
if (n != 0 && sz != 1) {
// r[sz - n - 1 : 0] ++ r[sz - 1 : sz - n]
// r * 2^(sz - n) + (r div 2^n) mod 2^(sz - n)???
// r * A + (r div B) mod A
auto N = bv_size(e);
auto A = rational::power_of_two(sz - n);
auto B = rational::power_of_two(n);
auto hi = mul(r, a.mk_int(A));
auto lo = amod(e, a.mk_idiv(umod(e, 0), a.mk_int(B)), A);
r = add(hi, lo);
}
return r;
};
expr* bv_expr = e;
expr_ref r(m);
auto const& args = m_args;
switch (e->get_decl_kind()) {
case OP_BADD:
r = a.mk_add(args);
break;
case OP_BSUB:
r = a.mk_sub(args.size(), args.data());
break;
case OP_BMUL:
r = a.mk_mul(args);
break;
case OP_ULEQ:
bv_expr = e->get_arg(0);
r = a.mk_le(umod(bv_expr, 0), umod(bv_expr, 1));
break;
case OP_UGEQ:
bv_expr = e->get_arg(0);
r = a.mk_ge(umod(bv_expr, 0), umod(bv_expr, 1));
break;
case OP_ULT:
bv_expr = e->get_arg(0);
r = a.mk_lt(umod(bv_expr, 0), umod(bv_expr, 1));
break;
case OP_UGT:
bv_expr = e->get_arg(0);
r = a.mk_gt(umod(bv_expr, 0), umod(bv_expr, 1));
break;
case OP_SLEQ:
bv_expr = e->get_arg(0);
r = a.mk_le(smod(bv_expr, 0), smod(bv_expr, 1));
break;
case OP_SGEQ:
bv_expr = e->get_arg(0);
r = a.mk_ge(smod(bv_expr, 0), smod(bv_expr, 1));
break;
case OP_SLT:
bv_expr = e->get_arg(0);
r = a.mk_lt(smod(bv_expr, 0), smod(bv_expr, 1));
break;
case OP_SGT:
bv_expr = e->get_arg(0);
r = a.mk_gt(smod(bv_expr, 0), smod(bv_expr, 1));
break;
case OP_BNEG:
r = a.mk_uminus(arg(0));
break;
case OP_CONCAT: {
unsigned sz = 0;
expr_ref new_arg(m);
for (unsigned i = args.size(); i-- > 0;) {
expr* old_arg = e->get_arg(i);
new_arg = umod(old_arg, i);
if (sz > 0) {
new_arg = mul(new_arg, a.mk_int(rational::power_of_two(sz)));
r = add(r, new_arg);
}
else
r = new_arg;
sz += bv.get_bv_size(old_arg->get_sort());
}
break;
}
case OP_EXTRACT: {
unsigned lo, hi;
expr* old_arg;
VERIFY(bv.is_extract(e, lo, hi, old_arg));
r = arg(0);
if (lo > 0)
r = a.mk_idiv(r, a.mk_int(rational::power_of_two(lo)));
break;
}
case OP_BV_NUM: {
rational val;
unsigned sz;
VERIFY(bv.is_numeral(e, val, sz));
r = a.mk_int(val);
break;
}
case OP_BUREM:
case OP_BUREM_I: {
expr* x = umod(e, 0), * y = umod(e, 1);
r = if_eq(y, 0, x, a.mk_mod(x, y));
break;
}
case OP_BUDIV:
case OP_BUDIV_I: {
expr* x = umod(e, 0), * y = umod(e, 1);
r = if_eq(y, 0, a.mk_int(-1), a.mk_idiv(x, y));
break;
}
case OP_BUMUL_NO_OVFL: {
bv_expr = e->get_arg(0);
r = a.mk_lt(mul(umod(bv_expr, 0), umod(bv_expr, 1)), a.mk_int(bv_size(bv_expr)));
break;
}
case OP_BSHL: {
if (!a.is_numeral(arg(0)) && !a.is_numeral(arg(1)))
r = a.mk_shl(bv.get_bv_size(e), arg(0),arg(1));
else {
expr* x = arg(0), * y = umod(e, 1);
r = a.mk_int(0);
IF_VERBOSE(2, verbose_stream() << "shl " << mk_bounded_pp(e, m) << " " << bv.get_bv_size(e) << "\n");
for (unsigned i = 0; i < bv.get_bv_size(e); ++i)
r = if_eq(y, i, mul(x, a.mk_int(rational::power_of_two(i))), r);
}
break;
}
case OP_BNOT:
r = bnot(arg(0));
break;
case OP_BLSHR:
if (!a.is_numeral(arg(0)) && !a.is_numeral(arg(1)))
r = a.mk_lshr(bv.get_bv_size(e), arg(0), arg(1));
else {
expr* x = arg(0), * y = umod(e, 1);
r = a.mk_int(0);
IF_VERBOSE(2, verbose_stream() << "lshr " << mk_bounded_pp(e, m) << " " << bv.get_bv_size(e) << "\n");
for (unsigned i = 0; i < bv.get_bv_size(e); ++i)
r = if_eq(y, i, a.mk_idiv(x, a.mk_int(rational::power_of_two(i))), r);
}
break;
case OP_BASHR:
if (!a.is_numeral(arg(1)))
r = a.mk_ashr(bv.get_bv_size(e), arg(0), arg(1));
else {
//
// ashr(x, y)
// if y = k & x >= 0 -> x / 2^k
// if y = k & x < 0 -> (x / 2^k) - 2^{N-k}
//
unsigned sz = bv.get_bv_size(e);
rational N = bv_size(e);
expr* x = umod(e, 0), *y = umod(e, 1);
expr* signx = a.mk_ge(x, a.mk_int(N / 2));
r = m.mk_ite(signx, a.mk_int(- 1), a.mk_int(0));
IF_VERBOSE(1, verbose_stream() << "ashr " << mk_bounded_pp(e, m) << " " << bv.get_bv_size(e) << "\n");
for (unsigned i = 0; i < sz; ++i) {
expr* d = a.mk_idiv(x, a.mk_int(rational::power_of_two(i)));
r = if_eq(y, i,
m.mk_ite(signx, add(d, a.mk_int(- rational::power_of_two(sz-i))), d),
r);
}
}
break;
case OP_BOR:
// p | q := (p + q) - band(p, q)
IF_VERBOSE(2, verbose_stream() << "bor " << mk_bounded_pp(e, m) << " " << bv.get_bv_size(e) << "\n");
r = arg(0);
for (unsigned i = 1; i < args.size(); ++i)
r = a.mk_sub(add(r, arg(i)), a.mk_band(bv.get_bv_size(e), r, arg(i)));
break;
case OP_BNAND:
r = bnot(band(args));
break;
case OP_BAND:
IF_VERBOSE(2, verbose_stream() << "band " << mk_bounded_pp(e, m) << " " << bv.get_bv_size(e) << "\n");
r = band(args);
break;
case OP_BXNOR:
case OP_BXOR: {
// p ^ q := (p + q) - 2*band(p, q);
unsigned sz = bv.get_bv_size(e);
IF_VERBOSE(2, verbose_stream() << "bxor " << bv.get_bv_size(e) << "\n");
r = arg(0);
for (unsigned i = 1; i < args.size(); ++i) {
expr* q = arg(i);
r = a.mk_sub(add(r, q), mul(a.mk_int(2), a.mk_band(sz, r, q)));
}
if (e->get_decl_kind() == OP_BXNOR)
r = bnot(r);
break;
}
case OP_ZERO_EXT:
bv_expr = e->get_arg(0);
r = umod(bv_expr, 0);
SASSERT(bv.get_bv_size(e) >= bv.get_bv_size(bv_expr));
break;
case OP_SIGN_EXT: {
bv_expr = e->get_arg(0);
r = umod(bv_expr, 0);
SASSERT(bv.get_bv_size(e) >= bv.get_bv_size(bv_expr));
unsigned arg_sz = bv.get_bv_size(bv_expr);
//unsigned sz = bv.get_bv_size(e);
// rational N = rational::power_of_two(sz);
rational M = rational::power_of_two(arg_sz);
expr* signbit = a.mk_ge(r, a.mk_int(M / 2));
r = m.mk_ite(signbit, a.mk_sub(r, a.mk_int(M)), r);
break;
}
case OP_INT2BV:
m_int2bv.push_back(e);
ctx.push(push_back_vector(m_int2bv));
r = arg(0);
break;
case OP_BV2INT:
m_bv2int.push_back(e);
ctx.push(push_back_vector(m_bv2int));
r = umod(e->get_arg(0), 0);
break;
case OP_BCOMP:
bv_expr = e->get_arg(0);
r = m.mk_ite(m.mk_eq(umod(bv_expr, 0), umod(bv_expr, 1)), a.mk_int(1), a.mk_int(0));
break;
case OP_BSMOD_I:
case OP_BSMOD: {
expr* x = umod(e, 0), *y = umod(e, 1);
rational N = bv_size(e);
expr* signx = a.mk_ge(x, a.mk_int(N/2));
expr* signy = a.mk_ge(y, a.mk_int(N/2));
expr* u = a.mk_mod(x, y);
// u = 0 -> 0
// y = 0 -> x
// x < 0, y < 0 -> -u
// x < 0, y >= 0 -> y - u
// x >= 0, y < 0 -> y + u
// x >= 0, y >= 0 -> u
r = a.mk_uminus(u);
r = m.mk_ite(m.mk_and(m.mk_not(signx), signy), add(u, y), r);
r = m.mk_ite(m.mk_and(signx, m.mk_not(signy)), a.mk_sub(y, u), r);
r = m.mk_ite(m.mk_and(m.mk_not(signx), m.mk_not(signy)), u, r);
r = if_eq(u, 0, a.mk_int(0), r);
r = if_eq(y, 0, x, r);
break;
}
case OP_BSDIV_I:
case OP_BSDIV: {
// d = udiv(abs(x), abs(y))
// y = 0, x > 0 -> 1
// y = 0, x <= 0 -> -1
// x = 0, y != 0 -> 0
// x > 0, y < 0 -> -d
// x < 0, y > 0 -> -d
// x > 0, y > 0 -> d
// x < 0, y < 0 -> d
expr* x = umod(e, 0), * y = umod(e, 1);
rational N = bv_size(e);
expr* signx = a.mk_ge(x, a.mk_int(N / 2));
expr* signy = a.mk_ge(y, a.mk_int(N / 2));
x = m.mk_ite(signx, a.mk_sub(a.mk_int(N), x), x);
y = m.mk_ite(signy, a.mk_sub(a.mk_int(N), y), y);
expr* d = a.mk_idiv(x, y);
r = m.mk_ite(m.mk_iff(signx, signy), d, a.mk_uminus(d));
r = if_eq(y, 0, m.mk_ite(signx, a.mk_int(1), a.mk_int(-1)), r);
break;
}
case OP_BSREM_I:
case OP_BSREM: {
// y = 0 -> x
// else x - sdiv(x, y) * y
expr* x = umod(e, 0), * y = umod(e, 1);
rational N = bv_size(e);
expr* signx = a.mk_ge(x, a.mk_int(N / 2));
expr* signy = a.mk_ge(y, a.mk_int(N / 2));
expr* absx = m.mk_ite(signx, a.mk_sub(a.mk_int(N), x), x);
expr* absy = m.mk_ite(signy, a.mk_sub(a.mk_int(N), y), y);
expr* d = a.mk_idiv(absx, absy);
d = m.mk_ite(m.mk_iff(signx, signy), d, a.mk_uminus(d));
r = a.mk_sub(x, mul(d, y));
r = if_eq(y, 0, x, r);
break;
}
case OP_ROTATE_LEFT: {
auto n = e->get_parameter(0).get_int();
r = rotate_left(n);
break;
}
case OP_ROTATE_RIGHT: {
unsigned sz = bv.get_bv_size(e);
auto n = e->get_parameter(0).get_int();
r = rotate_left(sz - n);
break;
}
case OP_EXT_ROTATE_LEFT: {
unsigned sz = bv.get_bv_size(e);
expr* y = umod(e, 1);
r = a.mk_int(0);
for (unsigned i = 0; i < sz; ++i)
r = if_eq(y, i, rotate_left(i), r);
break;
}
case OP_EXT_ROTATE_RIGHT: {
unsigned sz = bv.get_bv_size(e);
expr* y = umod(e, 1);
r = a.mk_int(0);
for (unsigned i = 0; i < sz; ++i)
r = if_eq(y, i, rotate_left(sz - i), r);
break;
}
case OP_REPEAT: {
unsigned n = e->get_parameter(0).get_int();
expr* x = umod(e->get_arg(0), 0);
r = x;
rational N = bv_size(e->get_arg(0));
rational N0 = N;
for (unsigned i = 1; i < n; ++i)
r = add(mul(a.mk_int(N), x), r), N *= N0;
break;
}
case OP_BREDOR: {
r = umod(e->get_arg(0), 0);
r = m.mk_not(m.mk_eq(r, a.mk_int(0)));
break;
}
case OP_BREDAND: {
rational N = bv_size(e->get_arg(0));
r = umod(e->get_arg(0), 0);
r = m.mk_not(m.mk_eq(r, a.mk_int(N - 1)));
break;
}
default:
verbose_stream() << mk_pp(e, m) << "\n";
NOT_IMPLEMENTED_YET();
}
set_translated(e, r);
}
expr_ref solver::if_eq(expr* n, unsigned k, expr* th, expr* el) {
rational r;
expr_ref _th(th, m), _el(el, m);
if (bv.is_numeral(n, r)) {
if (r == k)
return expr_ref(th, m);
else
return expr_ref(el, m);
}
return expr_ref(m.mk_ite(m.mk_eq(n, a.mk_int(k)), th, el), m);
}
void solver::translate_basic(app* e) {
if (m.is_eq(e)) {
bool has_bv_arg = any_of(*e, [&](expr* arg) { return bv.is_bv(arg); });
if (has_bv_arg) {
expr* bv_expr = e->get_arg(0);
rational N = rational::power_of_two(bv.get_bv_size(bv_expr));
if (a.is_numeral(arg(0)) || a.is_numeral(arg(1)) ||
is_bounded(arg(0), N) || is_bounded(arg(1), N)) {
set_translated(e, m.mk_eq(umod(bv_expr, 0), umod(bv_expr, 1)));
}
else {
m_args[0] = a.mk_sub(arg(0), arg(1));
set_translated(e, m.mk_eq(umod(bv_expr, 0), a.mk_int(0)));
}
}
else
set_translated(e, m.mk_eq(arg(0), arg(1)));
}
else if (m.is_ite(e))
set_translated(e, m.mk_ite(arg(0), arg(1), arg(2)));
else if (m_is_plugin)
set_translated(e, e);
else
set_translated(e, m.mk_app(e->get_decl(), m_args));
}
rational solver::get_value(expr* e) const {
SASSERT(bv.is_bv(e));
model_ref mdl;
m_solver->get_model(mdl);
expr_ref r(m);
r = translated(e);
r = m_translator.translated(e);
rational val;
if (!mdl->eval_expr(r, r, true))
return rational::zero();
@ -1099,7 +465,7 @@ namespace intblast {
}
rational r, N = rational::power_of_two(bv.get_bv_size(e));
expr* te = translated(e);
expr* te = m_translator.translated(e);
model_ref mdlr;
m_solver->get_model(mdlr);
expr_ref value(m);
@ -1126,14 +492,12 @@ namespace intblast {
else {
expr_ref bv2int(bv.mk_bv2int(n->get_expr()), m);
euf::enode* b2i = ctx.get_enode(bv2int);
if (!b2i) verbose_stream() << bv2int << "\n";
SASSERT(b2i);
VERIFY(b2i);
arith::arith_value av(ctx);
rational r;
VERIFY(av.get_value(b2i->get_expr(), r));
value = bv.mk_numeral(r, bv.get_bv_size(n->get_expr()));
verbose_stream() << ctx.bpp(n) << " := " << value << "\n";
}
values.set(n->get_root_id(), value);
TRACE("model", tout << "add_value " << ctx.bpp(n) << " := " << value << "\n");
@ -1143,11 +507,11 @@ namespace intblast {
return;
for (auto n : ctx.get_egraph().nodes()) {
auto e = n->get_expr();
if (!is_translated(e))
if (!m_translator.is_translated(e))
continue;
if (!bv.is_bv(e))
continue;
auto t = translated(e);
auto t = m_translator.translated(e);
expr_ref ei(bv.mk_bv2int(e), m);
expr_ref ti(a.mk_mod(t, a.mk_int(rational::power_of_two(bv.get_bv_size(e)))), m);