3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-03-01 19:26:53 +00:00
z3/src/ast/bv_decl_plugin.h
Nikolaj Bjorner 91dc02d862
Sls (#7439)
* 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>
2024-11-02 12:32:48 -07:00

625 lines
28 KiB
C++

/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
bv_decl_plugin.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-01-09.
Revision History:
--*/
#pragma once
#include "ast/ast.h"
enum bv_sort_kind {
BV_SORT
};
enum bv_op_kind {
OP_BV_NUM,
OP_BIT1,
OP_BIT0,
OP_BNEG,
OP_BADD,
OP_BSUB,
OP_BMUL,
OP_BSDIV,
OP_BUDIV,
OP_BSREM,
OP_BUREM,
OP_BSMOD,
// special functions to record the division by 0 cases
// these are internal functions
OP_BSDIV0,
OP_BUDIV0,
OP_BSREM0,
OP_BUREM0,
OP_BSMOD0,
// special functions where division by 0 has a fixed interpretation.
OP_BSDIV_I,
OP_BUDIV_I,
OP_BSREM_I,
OP_BUREM_I,
OP_BSMOD_I,
OP_ULEQ,
OP_SLEQ,
OP_UGEQ,
OP_SGEQ,
OP_ULT,
OP_SLT,
OP_UGT,
OP_SGT,
OP_BAND,
OP_BOR,
OP_BNOT,
OP_BXOR,
OP_BNAND,
OP_BNOR,
OP_BXNOR,
OP_CONCAT,
OP_SIGN_EXT,
OP_ZERO_EXT,
OP_EXTRACT,
OP_REPEAT,
OP_BREDOR,
OP_BREDAND,
OP_BCOMP,
OP_BSHL,
OP_BLSHR,
OP_BASHR,
OP_ROTATE_LEFT,
OP_ROTATE_RIGHT,
OP_EXT_ROTATE_LEFT,
OP_EXT_ROTATE_RIGHT,
OP_BUMUL_NO_OVFL, // no unsigned multiplication overflow predicate
OP_BSMUL_NO_OVFL, // no signed multiplication overflow predicate
OP_BSMUL_NO_UDFL, // no signed multiplication underflow predicate
OP_BUMUL_OVFL, // unsigned multiplication overflow predicate (negation of OP_BUMUL_NO_OVFL)
OP_BSMUL_OVFL, // signed multiplication over/underflow predicate
OP_BSDIV_OVFL, // signed division overflow predicate
OP_BNEG_OVFL, // negation overflow predicate
OP_BUADD_OVFL, // unsigned addition overflow predicate
OP_BSADD_OVFL, // signed addition overflow predicate
OP_BUSUB_OVFL, // unsigned subtraction overflow predicate
OP_BSSUB_OVFL, // signed subtraction overflow predicate
OP_BIT2BOOL, // predicate
OP_MKBV, // bools to bv
OP_INT2BV,
OP_BV2INT,
OP_CARRY,
OP_XOR3,
LAST_BV_OP
};
// Assume k is a "div" operator. It returns the div0 uninterpreted function that
// models the value of "div" it is underspecified (i.e., when the denominator is zero).
inline bv_op_kind get_div0_op(bv_op_kind k) {
switch (k) {
case OP_BSDIV: return OP_BSDIV0;
case OP_BUDIV: return OP_BUDIV0;
case OP_BSREM: return OP_BSREM0;
case OP_BUREM: return OP_BUREM0;
case OP_BSMOD: return OP_BSMOD0;
default: UNREACHABLE(); return LAST_BV_OP;
}
}
// Assume decl is the declaration of a "div" operator. It returns the div0 declaration that
// models the value of "div" it is underspecified (i.e., when the denominator is zero).
inline func_decl * get_div0_decl(ast_manager & m, func_decl * decl) {
return m.mk_func_decl(decl->get_family_id(), get_div0_op(static_cast<bv_op_kind>(decl->get_decl_kind())),
0, nullptr, 1, decl->get_domain());
}
class bv_decl_plugin : public decl_plugin {
friend class bv_util;
protected:
symbol m_bv_sym;
symbol m_concat_sym;
symbol m_sign_extend_sym;
symbol m_zero_extend_sym;
symbol m_extract_sym;
symbol m_rotate_left_sym;
symbol m_rotate_right_sym;
symbol m_repeat_sym;
symbol m_bit2bool_sym;
symbol m_mkbv_sym;
func_decl * m_bit0;
func_decl * m_bit1;
func_decl * m_carry;
func_decl * m_xor3;
ptr_vector<sort> m_bv_sorts;
sort * m_int_sort;
ptr_vector<func_decl> m_bv_neg;
ptr_vector<func_decl> m_bv_add;
ptr_vector<func_decl> m_bv_sub;
ptr_vector<func_decl> m_bv_mul;
ptr_vector<func_decl> m_bv_sdiv;
ptr_vector<func_decl> m_bv_udiv;
ptr_vector<func_decl> m_bv_srem;
ptr_vector<func_decl> m_bv_urem;
ptr_vector<func_decl> m_bv_smod;
ptr_vector<func_decl> m_bv_sdiv0;
ptr_vector<func_decl> m_bv_udiv0;
ptr_vector<func_decl> m_bv_srem0;
ptr_vector<func_decl> m_bv_urem0;
ptr_vector<func_decl> m_bv_smod0;
ptr_vector<func_decl> m_bv_sdiv_i;
ptr_vector<func_decl> m_bv_udiv_i;
ptr_vector<func_decl> m_bv_srem_i;
ptr_vector<func_decl> m_bv_urem_i;
ptr_vector<func_decl> m_bv_smod_i;
ptr_vector<func_decl> m_bv_uleq;
ptr_vector<func_decl> m_bv_sleq;
ptr_vector<func_decl> m_bv_ugeq;
ptr_vector<func_decl> m_bv_sgeq;
ptr_vector<func_decl> m_bv_ult;
ptr_vector<func_decl> m_bv_slt;
ptr_vector<func_decl> m_bv_ugt;
ptr_vector<func_decl> m_bv_sgt;
ptr_vector<func_decl> m_bv_and;
ptr_vector<func_decl> m_bv_or;
ptr_vector<func_decl> m_bv_not;
ptr_vector<func_decl> m_bv_xor;
ptr_vector<func_decl> m_bv_nand;
ptr_vector<func_decl> m_bv_nor;
ptr_vector<func_decl> m_bv_xnor;
ptr_vector<func_decl> m_bv_redor;
ptr_vector<func_decl> m_bv_redand;
ptr_vector<func_decl> m_bv_comp;
ptr_vector<func_decl> m_bv_mul_no_ovfl;
ptr_vector<func_decl> m_bv_smul_no_ovfl;
ptr_vector<func_decl> m_bv_smul_no_udfl;
ptr_vector<func_decl> m_bv_mul_ovfl;
ptr_vector<func_decl> m_bv_smul_ovfl;
ptr_vector<func_decl> m_bv_sdiv_ovfl;
ptr_vector<func_decl> m_bv_neg_ovfl;
ptr_vector<func_decl> m_bv_uadd_ovfl;
ptr_vector<func_decl> m_bv_sadd_ovfl;
ptr_vector<func_decl> m_bv_usub_ovfl;
ptr_vector<func_decl> m_bv_ssub_ovfl;
ptr_vector<func_decl> m_bv_shl;
ptr_vector<func_decl> m_bv_lshr;
ptr_vector<func_decl> m_bv_ashr;
ptr_vector<func_decl> m_ext_rotate_left;
ptr_vector<func_decl> m_ext_rotate_right;
ptr_vector<func_decl> m_bv2int;
ptr_vector<func_decl> m_int2bv;
vector<ptr_vector<func_decl> > m_bit2bool;
ptr_vector<func_decl> m_mkbv;
void set_manager(ast_manager * m, family_id id) override;
void mk_bv_sort(unsigned bv_size);
sort * get_bv_sort(unsigned bv_size);
func_decl * mk_func_decl(decl_kind k, unsigned bv_size);
func_decl * mk_binary(ptr_vector<func_decl> & decls, decl_kind k,
char const * name, unsigned bv_size, bool ac, bool idempotent = false);
func_decl * mk_unary(ptr_vector<func_decl> & decls, decl_kind k, char const * name, unsigned bv_size);
func_decl * mk_pred(ptr_vector<func_decl> & decls, decl_kind k,
char const * name, unsigned bv_size);
func_decl * mk_unary_pred(ptr_vector<func_decl> & decls, decl_kind k, char const * name, unsigned bv_size);
func_decl * mk_reduction(ptr_vector<func_decl> & decls, decl_kind k, char const * name, unsigned bv_size);
func_decl * mk_comp(unsigned bv_size);
bool get_bv_size(sort * t, int & result);
bool get_bv_size(expr * t, int & result);
bool get_concat_size(unsigned arity, sort * const * domain, int & result);
bool get_extend_size(unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, int & result);
bool get_extract_size(unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, int & result);
func_decl * mk_bv2int(unsigned bv_size, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain);
func_decl * mk_int2bv(unsigned bv_size, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain);
func_decl * mk_bit2bool(unsigned bv_size, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain);
func_decl * mk_mkbv(unsigned arity, sort * const * domain);
func_decl * mk_num_decl(unsigned num_parameters, parameter const * parameters, unsigned arity);
void get_offset_term(app * a, expr * & t, rational & offset) const;
public:
bv_decl_plugin();
void finalize() override;
decl_plugin * mk_fresh() override { return alloc(bv_decl_plugin); }
sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) override;
func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range) override;
func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned num_args, expr * const * args, sort * range) override;
bool is_value(app * e) const override;
bool is_unique_value(app * e) const override { return is_value(e); }
void get_op_names(svector<builtin_name> & op_names, symbol const & logic) override;
void get_sort_names(svector<builtin_name> & sort_names, symbol const & logic) override;
bool are_distinct(app* a, app* b) const override;
expr * get_some_value(sort * s) override;
bool get_int2bv_size(unsigned num_parameters, parameter const * parameters, int & result);
bool is_considered_uninterpreted(func_decl * f) override {
if (f->get_family_id() != get_family_id())
return false;
switch (f->get_decl_kind()) {
case OP_BSDIV0:
case OP_BUDIV0:
case OP_BSREM0:
case OP_BUREM0:
case OP_BSMOD0:
return true;
default:
return false;
}
return false;
}
};
class bv_recognizers {
family_id m_afid;
public:
bv_recognizers(family_id fid):m_afid(fid) {}
family_id get_fid() const { return m_afid; }
family_id get_family_id() const { return get_fid(); }
bool is_numeral(expr const * n, rational & val) const;
bool is_numeral(expr const * n, rational & val, unsigned & bv_size) const;
bool is_numeral(expr const * n) const { return is_app_of(n, get_fid(), OP_BV_NUM); }
bool is_allone(expr const * e) const;
bool is_zero(expr const * e) const;
bool is_one(expr const* e) const;
bool is_bv_sort(sort const * s) const;
bool is_bv(expr const* e) const { return is_bv_sort(e->get_sort()); }
bool is_concat(expr const * e) const { return is_app_of(e, get_fid(), OP_CONCAT); }
bool is_extract(func_decl const * f) const { return is_decl_of(f, get_fid(), OP_EXTRACT); }
bool is_extract(expr const * e) const { return is_app_of(e, get_fid(), OP_EXTRACT); }
unsigned get_extract_high(func_decl const * f) const { return f->get_parameter(0).get_int(); }
unsigned get_extract_low(func_decl const * f) const { return f->get_parameter(1).get_int(); }
unsigned get_extract_high(expr const * n) const { SASSERT(is_extract(n)); return get_extract_high(to_app(n)->get_decl()); }
unsigned get_extract_low(expr const * n) const { SASSERT(is_extract(n)); return get_extract_low(to_app(n)->get_decl()); }
bool is_extract(expr const * e, unsigned & low, unsigned & high, expr * & b) const;
bool is_repeat(expr const * e, expr*& arg, unsigned& n) const;
bool is_bv2int(expr const * e, expr * & r) const;
bool is_bv_add(expr const * e) const { return is_app_of(e, get_fid(), OP_BADD); }
bool is_bv_sub(expr const * e) const { return is_app_of(e, get_fid(), OP_BSUB); }
bool is_bv_mul(expr const * e) const { return is_app_of(e, get_fid(), OP_BMUL); }
bool is_bv_neg(expr const * e) const { return is_app_of(e, get_fid(), OP_BNEG); }
bool is_bv_sdiv(expr const * e) const { return is_app_of(e, get_fid(), OP_BSDIV); }
bool is_bv_udiv(expr const * e) const { return is_app_of(e, get_fid(), OP_BUDIV); }
bool is_bv_srem(expr const * e) const { return is_app_of(e, get_fid(), OP_BSREM); }
bool is_bv_urem(expr const * e) const { return is_app_of(e, get_fid(), OP_BUREM); }
bool is_bv_smod(expr const * e) const { return is_app_of(e, get_fid(), OP_BSMOD); }
bool is_bv_sdiv0(expr const * e) const { return is_app_of(e, get_fid(), OP_BSDIV0); }
bool is_bv_udiv0(expr const * e) const { return is_app_of(e, get_fid(), OP_BUDIV0); }
bool is_bv_srem0(expr const * e) const { return is_app_of(e, get_fid(), OP_BSREM0); }
bool is_bv_urem0(expr const * e) const { return is_app_of(e, get_fid(), OP_BUREM0); }
bool is_bv_smod0(expr const * e) const { return is_app_of(e, get_fid(), OP_BSMOD0); }
bool is_bv_sdivi(expr const * e) const { return is_app_of(e, get_fid(), OP_BSDIV_I); }
bool is_bv_udivi(expr const * e) const { return is_app_of(e, get_fid(), OP_BUDIV_I); }
bool is_bv_sremi(expr const * e) const { return is_app_of(e, get_fid(), OP_BSREM_I); }
bool is_bv_uremi(expr const * e) const { return is_app_of(e, get_fid(), OP_BUREM_I); }
bool is_bv_smodi(expr const * e) const { return is_app_of(e, get_fid(), OP_BSMOD_I); }
bool is_bv_and(expr const * e) const { return is_app_of(e, get_fid(), OP_BAND); }
bool is_bv_or(expr const * e) const { return is_app_of(e, get_fid(), OP_BOR); }
bool is_bv_xor(expr const * e) const { return is_app_of(e, get_fid(), OP_BXOR); }
bool is_bv_nand(expr const * e) const { return is_app_of(e, get_fid(), OP_BNAND); }
bool is_bv_nor(expr const * e) const { return is_app_of(e, get_fid(), OP_BNOR); }
bool is_bv_not(expr const * e) const { return is_app_of(e, get_fid(), OP_BNOT); }
bool is_bv_ule(expr const * e) const { return is_app_of(e, get_fid(), OP_ULEQ); }
bool is_bv_sle(expr const * e) const { return is_app_of(e, get_fid(), OP_SLEQ); }
bool is_ule(expr const * e) const { return is_app_of(e, get_fid(), OP_ULEQ); }
bool is_sle(expr const * e) const { return is_app_of(e, get_fid(), OP_SLEQ); }
bool is_ult(expr const * e) const { return is_app_of(e, get_fid(), OP_ULT); }
bool is_slt(expr const * e) const { return is_app_of(e, get_fid(), OP_SLT); }
bool is_ugt(expr const * e) const { return is_app_of(e, get_fid(), OP_UGT); }
bool is_sgt(expr const * e) const { return is_app_of(e, get_fid(), OP_SGT); }
bool is_uge(expr const * e) const { return is_app_of(e, get_fid(), OP_UGEQ); }
bool is_sge(expr const * e) const { return is_app_of(e, get_fid(), OP_SGEQ); }
bool is_bit2bool(expr const * e) const { return is_app_of(e, get_fid(), OP_BIT2BOOL); }
bool is_bv2int(expr const* e) const { return is_app_of(e, get_fid(), OP_BV2INT); }
bool is_int2bv(expr const* e) const { return is_app_of(e, get_fid(), OP_INT2BV); }
bool is_mkbv(expr const * e) const { return is_app_of(e, get_fid(), OP_MKBV); }
bool is_bv_ashr(expr const * e) const { return is_app_of(e, get_fid(), OP_BASHR); }
bool is_bv_lshr(expr const * e) const { return is_app_of(e, get_fid(), OP_BLSHR); }
bool is_bv_shl(expr const * e) const { return is_app_of(e, get_fid(), OP_BSHL); }
bool is_sign_ext(expr const * e) const { return is_app_of(e, get_fid(), OP_SIGN_EXT); }
bool is_bv_umul_no_ovfl(expr const* e) const { return is_app_of(e, get_fid(), OP_BUMUL_NO_OVFL); }
bool is_redand(expr const* e) const { return is_app_of(e, get_fid(), OP_BREDAND); }
bool is_redor(expr const* e) const { return is_app_of(e, get_fid(), OP_BREDOR); }
bool is_comp(expr const* e) const { return is_app_of(e, get_fid(), OP_BCOMP); }
bool is_rotate_left(expr const* e) const { return is_app_of(e, get_fid(), OP_ROTATE_LEFT); }
bool is_rotate_right(expr const* e) const { return is_app_of(e, get_fid(), OP_ROTATE_RIGHT); }
bool is_ext_rotate_left(expr const* e) const { return is_app_of(e, get_fid(), OP_EXT_ROTATE_LEFT); }
bool is_ext_rotate_right(expr const* e) const { return is_app_of(e, get_fid(), OP_EXT_ROTATE_RIGHT); }
bool is_rotate_left(expr const* e, unsigned& n, expr*& x) const {
return is_rotate_left(e) && (n = to_app(e)->get_parameter(0).get_int(), x = to_app(e)->get_arg(0), true);
}
bool is_rotate_right(expr const* e, unsigned& n, expr*& x) const {
return is_rotate_right(e) && (n = to_app(e)->get_parameter(0).get_int(), x = to_app(e)->get_arg(0), true);
}
bool is_int2bv(expr const* e, unsigned& n, expr*& x) const {
return is_int2bv(e) && (n = to_app(e)->get_parameter(0).get_int(), x = to_app(e)->get_arg(0), true);
}
MATCH_UNARY(is_bv_not);
MATCH_UNARY(is_redand);
MATCH_UNARY(is_redor);
MATCH_BINARY(is_ext_rotate_left);
MATCH_BINARY(is_ext_rotate_right);
MATCH_BINARY(is_comp);
MATCH_BINARY(is_bv_add);
MATCH_BINARY(is_bv_sub);
MATCH_BINARY(is_bv_mul);
MATCH_BINARY(is_bv_sle);
MATCH_BINARY(is_bv_ule);
MATCH_BINARY(is_ule);
MATCH_BINARY(is_sle);
MATCH_BINARY(is_ult);
MATCH_BINARY(is_slt);
MATCH_BINARY(is_uge);
MATCH_BINARY(is_sge);
MATCH_BINARY(is_ugt);
MATCH_BINARY(is_sgt);
MATCH_BINARY(is_bv_umul_no_ovfl);
MATCH_BINARY(is_bv_ashr);
MATCH_BINARY(is_bv_lshr);
MATCH_BINARY(is_bv_shl);
MATCH_BINARY(is_bv_urem);
MATCH_BINARY(is_bv_srem);
MATCH_BINARY(is_bv_sdiv);
MATCH_BINARY(is_bv_udiv);
MATCH_BINARY(is_bv_smod);
MATCH_BINARY(is_bv_and);
MATCH_BINARY(is_bv_or);
MATCH_BINARY(is_bv_xor);
MATCH_BINARY(is_bv_nand);
MATCH_BINARY(is_bv_nor);
MATCH_BINARY(is_concat);
MATCH_BINARY(is_bv_uremi);
MATCH_BINARY(is_bv_sremi);
MATCH_BINARY(is_bv_sdivi);
MATCH_BINARY(is_bv_udivi);
MATCH_BINARY(is_bv_smodi);
MATCH_BINARY(is_bv_urem0);
MATCH_BINARY(is_bv_srem0);
MATCH_BINARY(is_bv_sdiv0);
MATCH_BINARY(is_bv_udiv0);
MATCH_BINARY(is_bv_smod0);
MATCH_UNARY(is_bit2bool);
MATCH_UNARY(is_int2bv);
bool is_bit2bool(expr* e, expr*& bv, unsigned& idx) const;
rational norm(rational const & val, unsigned bv_size, bool is_signed) const ;
rational norm(rational const & val, unsigned bv_size) const { return norm(val, bv_size, false); }
bool has_sign_bit(rational const & n, unsigned bv_size) const;
};
class bv_util : public bv_recognizers {
ast_manager & m_manager;
bv_decl_plugin * m_plugin;
public:
bv_util(ast_manager & m);
ast_manager & get_manager() const { return m_manager; }
app * mk_numeral(rational const & val, sort* s) const;
app * mk_numeral(rational const & val, unsigned bv_size) const;
app * mk_numeral(uint64_t u, unsigned bv_size) const { return mk_numeral(rational(u, rational::ui64()), bv_size); }
app * mk_zero(sort* s) const { return mk_numeral(rational::zero(), s); }
app * mk_zero(unsigned bv_size) const { return mk_numeral(rational::zero(), bv_size); }
app * mk_one(sort* s) const { return mk_numeral(rational::one(), s); }
app * mk_one(unsigned bv_size) const { return mk_numeral(rational::one(), bv_size); }
sort * mk_sort(unsigned bv_size);
unsigned get_bv_size(sort const * s) const {
SASSERT(is_bv_sort(s));
return static_cast<unsigned>(s->get_parameter(0).get_int());
}
unsigned get_bv_size(expr const * n) const { return get_bv_size(n->get_sort()); }
unsigned get_int2bv_size(parameter const& p);
app * mk_ule(expr * arg1, expr * arg2) { return m_manager.mk_app(get_fid(), OP_ULEQ, arg1, arg2); }
app * mk_sle(expr * arg1, expr * arg2) { return m_manager.mk_app(get_fid(), OP_SLEQ, arg1, arg2); }
app * mk_slt(expr * arg1, expr * arg2) { return m_manager.mk_app(get_fid(), OP_SLT, arg1, arg2); }
app * mk_extract(unsigned high, unsigned low, expr * n) {
parameter params[2] = { parameter(high), parameter(low) };
return m_manager.mk_app(get_fid(), OP_EXTRACT, 2, params, 1, &n);
}
app * mk_concat(unsigned num, expr * const * args) { return m_manager.mk_app(get_fid(), OP_CONCAT, num, args); }
app * mk_concat(expr_ref_vector const& es) { return m_manager.mk_app(get_fid(), OP_CONCAT, es.size(), es.data()); }
app * mk_concat(expr_ref_buffer const& es) { return m_manager.mk_app(get_fid(), OP_CONCAT, es.size(), es.data()); }
app * mk_concat(ptr_buffer<expr> const& es) { return m_manager.mk_app(get_fid(), OP_CONCAT, es.size(), es.data()); }
app * mk_concat(ptr_vector<expr> const& es) { return m_manager.mk_app(get_fid(), OP_CONCAT, es.size(), es.data()); }
app * mk_bv_or(unsigned num, expr * const * args) { return m_manager.mk_app(get_fid(), OP_BOR, num, args); }
app * mk_bv_and(unsigned num, expr * const * args) { return m_manager.mk_app(get_fid(), OP_BAND, num, args); }
app * mk_bv_xor(unsigned num, expr * const * args) { return m_manager.mk_app(get_fid(), OP_BXOR, num, args); }
app * mk_concat(expr * arg1, expr * arg2) { expr * args[2] = { arg1, arg2 }; return mk_concat(2, args); }
app * mk_bv_and(expr* x, expr* y) { expr* args[2] = { x, y }; return mk_bv_and(2, args); }
app * mk_bv_or(expr* x, expr* y) { expr* args[2] = { x, y }; return mk_bv_or(2, args); }
app * mk_bv_xor(expr* x, expr* y) { expr* args[2] = { x, y }; return mk_bv_xor(2, args); }
app * mk_bv_not(expr * arg) { return m_manager.mk_app(get_fid(), OP_BNOT, arg); }
app * mk_bv_neg(expr * arg) { return m_manager.mk_app(get_fid(), OP_BNEG, arg); }
app * mk_bv_urem(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BUREM, arg1, arg2); }
app * mk_bv_srem(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BSREM, arg1, arg2); }
app * mk_bv_smod(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BSMOD, arg1, arg2); }
app * mk_bv_add(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BADD, arg1, arg2); }
app * mk_bv_add(ptr_buffer<expr> const & args) const { return m_manager.mk_app(get_fid(), OP_BADD, args.size(), args.data()); }
app * mk_bv_add(ptr_vector<expr> const & args) const { return m_manager.mk_app(get_fid(), OP_BADD, args.size(), args.data()); }
app * mk_bv_add(expr_ref_vector const & args) const { return m_manager.mk_app(get_fid(), OP_BADD, args.size(), args.data()); }
app * mk_bv_add(expr_ref_buffer const & args) const { return m_manager.mk_app(get_fid(), OP_BADD, args.size(), args.data()); }
app * mk_bv_sub(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BSUB, arg1, arg2); }
app * mk_bv_mul(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BMUL, arg1, arg2); }
app * mk_bv_mul(unsigned n, expr* const* args) const { return m_manager.mk_app(get_fid(), OP_BMUL, n, args); }
app* mk_bv_mul(ptr_buffer<expr> const& args) const { return m_manager.mk_app(get_fid(), OP_BMUL, args.size(), args.data()); }
app* mk_bv_mul(ptr_vector<expr> const& args) const { return m_manager.mk_app(get_fid(), OP_BMUL, args.size(), args.data()); }
app* mk_bv_mul(expr_ref_vector const& args) const { return m_manager.mk_app(get_fid(), OP_BMUL, args.size(), args.data()); }
app* mk_bv_mul(expr_ref_buffer const& args) const { return m_manager.mk_app(get_fid(), OP_BMUL, args.size(), args.data()); }
app * mk_bv_udiv(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BUDIV, arg1, arg2); }
app * mk_bv_udiv_i(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BUDIV_I, arg1, arg2); }
app * mk_bv_udiv0(expr * arg) const { return m_manager.mk_app(get_fid(), OP_BUDIV0, arg); }
app * mk_bv_sdiv(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BSDIV, arg1, arg2); }
app * mk_bv_sdiv_i(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BSDIV_I, arg1, arg2); }
app * mk_bv_sdiv0(expr * arg) const { return m_manager.mk_app(get_fid(), OP_BSDIV0, arg); }
app * mk_bv_srem_i(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BSREM_I, arg1, arg2); }
app * mk_bv_srem0(expr * arg) const { return m_manager.mk_app(get_fid(), OP_BSREM0, arg); }
app * mk_bv_urem_i(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BUREM_I, arg1, arg2); }
app * mk_bv_urem0(expr * arg) const { return m_manager.mk_app(get_fid(), OP_BUREM0, arg); }
app * mk_bv_smod_i(expr * arg1, expr * arg2) const { return m_manager.mk_app(get_fid(), OP_BSMOD_I, arg1, arg2); }
app * mk_bv_smod0(expr * arg) const { return m_manager.mk_app(get_fid(), OP_BSMOD0, arg); }
app * mk_zero_extend(unsigned n, expr* e) {
parameter p(n);
return m_manager.mk_app(get_fid(), OP_ZERO_EXT, 1, &p, 1, &e);
}
app * mk_sign_extend(unsigned n, expr* e) {
parameter p(n);
return m_manager.mk_app(get_fid(), OP_SIGN_EXT, 1, &p, 1, &e);
}
app * mk_bv_shl(expr* arg1, expr* arg2) { return m_manager.mk_app(get_fid(), OP_BSHL, arg1, arg2); }
app * mk_bv_ashr(expr* arg1, expr* arg2) { return m_manager.mk_app(get_fid(), OP_BASHR, arg1, arg2); }
app * mk_bv_lshr(expr* arg1, expr* arg2) { return m_manager.mk_app(get_fid(), OP_BLSHR, arg1, arg2); }
app * mk_bv2int(expr* e) const;
app * mk_int2bv(unsigned sz, expr* e) const;
app* mk_bv_rotate_left(expr* arg1, expr* arg2) { return m_manager.mk_app(get_fid(), OP_EXT_ROTATE_LEFT, arg1, arg2); }
app* mk_bv_rotate_right(expr* arg1, expr* arg2) { return m_manager.mk_app(get_fid(), OP_EXT_ROTATE_RIGHT, arg1, arg2); }
app* mk_bv_rotate_left(expr* arg, unsigned n);
app* mk_bv_rotate_right(expr* arg, unsigned n);
// TODO: all these binary ops commute (right?) but it'd be more logical to swap `n` & `m` in the `return`
app * mk_bvsmul_no_ovfl(expr* m, expr* n) { return m_manager.mk_app(get_fid(), OP_BSMUL_NO_OVFL, m, n); }
app * mk_bvsmul_no_udfl(expr* m, expr* n) { return m_manager.mk_app(get_fid(), OP_BSMUL_NO_UDFL, m, n); }
app * mk_bvumul_no_ovfl(expr* m, expr* n) { return m_manager.mk_app(get_fid(), OP_BUMUL_NO_OVFL, m, n); }
app * mk_bvsmul_ovfl(expr* m, expr* n) { return m_manager.mk_app(get_fid(), OP_BSMUL_OVFL, m, n); }
app * mk_bvumul_ovfl(expr* m, expr* n) { return m_manager.mk_app(get_fid(), OP_BUMUL_OVFL, m, n); }
app * mk_bvsdiv_ovfl(expr* m, expr* n) { return m_manager.mk_app(get_fid(), OP_BSDIV_OVFL, m, n); }
app * mk_bvneg_ovfl(expr* m) { return m_manager.mk_app(get_fid(), OP_BNEG_OVFL, m); }
app * mk_bvuadd_ovfl(expr* m, expr* n) { return m_manager.mk_app(get_fid(), OP_BUADD_OVFL, m, n); }
app * mk_bvsadd_ovfl(expr* m, expr* n) { return m_manager.mk_app(get_fid(), OP_BSADD_OVFL, m, n); }
app * mk_bvusub_ovfl(expr* m, expr* n) { return m_manager.mk_app(get_fid(), OP_BUSUB_OVFL, m, n); }
app * mk_bvssub_ovfl(expr* m, expr* n) { return m_manager.mk_app(get_fid(), OP_BSSUB_OVFL, m, n); }
app * mk_bit2bool(expr* e, unsigned idx) { parameter p(idx); return m_manager.mk_app(get_fid(), OP_BIT2BOOL, 1, &p, 1, &e); }
private:
void log_bv_from_exprs(app * r, unsigned n, expr* const* es) {
if (m_manager.has_trace_stream()) {
for (unsigned i = 0; i < n; ++i) {
if (!m_manager.is_true(es[i]) && !m_manager.is_false(es[i]))
return;
}
if (m_plugin->log_constant_meaning_prelude(r)) {
if (n % 4 == 0) {
m_manager.trace_stream() << " #x";
m_manager.trace_stream() << std::hex;
uint8_t hexDigit = 0;
unsigned curLength = (4 - n % 4) % 4;
for (unsigned i = 0; i < n; ++i) {
hexDigit <<= 1;
++curLength;
if (m_manager.is_true(es[i])) {
hexDigit |= 1;
}
if (curLength == 4) {
m_manager.trace_stream() << hexDigit;
hexDigit = 0;
}
}
m_manager.trace_stream() << std::dec;
} else {
m_manager.trace_stream() << " #b";
for (unsigned i = 0; i < n; ++i) {
m_manager.trace_stream() << (m_manager.is_true(es[i]) ? 1 : 0);
}
}
m_manager.trace_stream() << ")\n";
}
}
}
public:
app * mk_bv(unsigned n, expr* const* es) {
app * r = m_manager.mk_app(get_fid(), OP_MKBV, n, es);
log_bv_from_exprs(r, n, es);
return r;
}
};