mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Merge branch 'master' of https://github.com/z3prover/z3
This commit is contained in:
		
						commit
						ae5e39a8b8
					
				
					 20 changed files with 282 additions and 86 deletions
				
			
		| 
						 | 
				
			
			@ -266,6 +266,8 @@ The following useful options can be passed to CMake whilst configuring.
 | 
			
		|||
    Disabling this is useful for faster incremental builds. The documentation can be manually built by invoking the ``api_docs`` target.
 | 
			
		||||
* ``LINK_TIME_OPTIMIZATION`` - BOOL. If set to ``TRUE`` link time optimization will be enabled.
 | 
			
		||||
* ``API_LOG_SYNC`` - BOOL. If set to ``TRUE`` will enable experimental API log sync feature.
 | 
			
		||||
* ``WARNINGS_AS_ERRORS`` - STRING. If set to ``TRUE`` compiler warnings will be treated as errors. If set to ``False`` compiler warnings will not be treated as errors.
 | 
			
		||||
    If set to ``SERIOUS_ONLY`` a subset of compiler warnings will be treated as errors.
 | 
			
		||||
 | 
			
		||||
On the command line these can be passed to ``cmake`` using the ``-D`` option. In ``ccmake`` and ``cmake-gui`` these can be set in the user interface.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -381,3 +383,13 @@ It is tempting use file-globbing in ``CMakeLists.txt`` to find a set for files m
 | 
			
		|||
use them as the sources to build a target. This however is a bad idea because it prevents CMake from knowing when it needs to rerun itself. This is why source file names are explicitly listed in the ``CMakeLists.txt`` so that when changes are made the source files used to build a target automatically triggers a rerun of CMake.
 | 
			
		||||
 | 
			
		||||
Long story short. Don't use file globbing.
 | 
			
		||||
 | 
			
		||||
### Serious warning flags
 | 
			
		||||
 | 
			
		||||
By default the `WARNINGS_AS_ERRORS` flag is set to `SERIOUS_ONLY` which means
 | 
			
		||||
some warnings will be treated as errors. These warnings are controlled by the
 | 
			
		||||
relevant `*_WARNINGS_AS_ERRORS` list defined in
 | 
			
		||||
`cmake/compiler_warnings.cmake`.
 | 
			
		||||
 | 
			
		||||
Additional warnings should only be added here if the warnings has no false
 | 
			
		||||
positives.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,17 +1,61 @@
 | 
			
		|||
################################################################################
 | 
			
		||||
# Compiler warning flags
 | 
			
		||||
################################################################################
 | 
			
		||||
# These are passed to relevant compiler provided they are supported
 | 
			
		||||
set(GCC_AND_CLANG_WARNINGS
 | 
			
		||||
    "-Wall"
 | 
			
		||||
  "-Wall"
 | 
			
		||||
)
 | 
			
		||||
set(GCC_ONLY_WARNINGS "")
 | 
			
		||||
set(CLANG_ONLY_WARNINGS "")
 | 
			
		||||
set(MSVC_WARNINGS "/W3")
 | 
			
		||||
 | 
			
		||||
################################################################################
 | 
			
		||||
# Serious warnings
 | 
			
		||||
################################################################################
 | 
			
		||||
# This declares the flags that are passed to the compiler when
 | 
			
		||||
# `WARNINGS_AS_ERRORS` is set to `SERIOUS_ONLY`. Only flags that are supported
 | 
			
		||||
# by the compiler are used.
 | 
			
		||||
#
 | 
			
		||||
# In effect this a "whitelist" approach where we explicitly tell the compiler
 | 
			
		||||
# which warnings we want to be treated as errors. The alternative would be a
 | 
			
		||||
# "blacklist" approach where we ask the compiler to treat all warnings are
 | 
			
		||||
# treated as errors but then we explicitly list which warnings which should be
 | 
			
		||||
# allowed.
 | 
			
		||||
#
 | 
			
		||||
# The "whitelist" approach seems simpiler because we can incrementally add
 | 
			
		||||
# warnings we "think are serious".
 | 
			
		||||
 | 
			
		||||
# TODO: Add more warnings that are considered serious enough that we should
 | 
			
		||||
# treat them as errors.
 | 
			
		||||
set(GCC_AND_CLANG_WARNINGS_AS_ERRORS
 | 
			
		||||
  # https://clang.llvm.org/docs/DiagnosticsReference.html#wodr
 | 
			
		||||
  "-Werror=odr"
 | 
			
		||||
)
 | 
			
		||||
set(GCC_WARNINGS_AS_ERRORS
 | 
			
		||||
  ""
 | 
			
		||||
)
 | 
			
		||||
set(CLANG_WARNINGS_AS_ERRORS
 | 
			
		||||
  # https://clang.llvm.org/docs/DiagnosticsReference.html#wdelete-non-virtual-dtor
 | 
			
		||||
  "-Werror=delete-non-virtual-dtor"
 | 
			
		||||
  # https://clang.llvm.org/docs/DiagnosticsReference.html#woverloaded-virtual
 | 
			
		||||
  "-Werror=overloaded-virtual"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
################################################################################
 | 
			
		||||
# Test warning/error flags
 | 
			
		||||
################################################################################
 | 
			
		||||
set(WARNING_FLAGS_TO_CHECK "")
 | 
			
		||||
set(WARNING_AS_ERROR_FLAGS_TO_CHECK "")
 | 
			
		||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
 | 
			
		||||
  list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
 | 
			
		||||
  list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_ONLY_WARNINGS})
 | 
			
		||||
  list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS_AS_ERRORS})
 | 
			
		||||
  list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${GCC_WARNINGS_AS_ERRORS})
 | 
			
		||||
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
 | 
			
		||||
  list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
 | 
			
		||||
  list(APPEND WARNING_FLAGS_TO_CHECK ${CLANG_ONLY_WARNINGS})
 | 
			
		||||
  list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS_AS_ERRORS})
 | 
			
		||||
  list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${CLANG_WARNINGS_AS_ERRORS})
 | 
			
		||||
  # FIXME: Remove "x.." when CMP0054 is set to NEW
 | 
			
		||||
elseif ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
 | 
			
		||||
  list(APPEND WARNING_FLAGS_TO_CHECK ${MSVC_WARNINGS})
 | 
			
		||||
| 
						 | 
				
			
			@ -31,8 +75,40 @@ foreach (flag ${WARNING_FLAGS_TO_CHECK})
 | 
			
		|||
  z3_add_cxx_flag("${flag}")
 | 
			
		||||
endforeach()
 | 
			
		||||
 | 
			
		||||
option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF)
 | 
			
		||||
if (WARNINGS_AS_ERRORS)
 | 
			
		||||
# TODO: Remove this eventually.
 | 
			
		||||
# Detect legacy `WARNINGS_AS_ERRORS` boolean option and covert to new
 | 
			
		||||
# to new option type.
 | 
			
		||||
get_property(
 | 
			
		||||
  WARNINGS_AS_ERRORS_CACHE_VAR_TYPE
 | 
			
		||||
  CACHE
 | 
			
		||||
  WARNINGS_AS_ERRORS
 | 
			
		||||
  PROPERTY
 | 
			
		||||
  TYPE
 | 
			
		||||
)
 | 
			
		||||
if ("${WARNINGS_AS_ERRORS_CACHE_VAR_TYPE}" STREQUAL "BOOL")
 | 
			
		||||
  message(WARNING "Detected legacy WARNINGS_AS_ERRORS option. Upgrading")
 | 
			
		||||
  set(WARNINGS_AS_ERRORS_DEFAULT "${WARNINGS_AS_ERRORS}")
 | 
			
		||||
  # Delete old entry
 | 
			
		||||
  unset(WARNINGS_AS_ERRORS CACHE)
 | 
			
		||||
else()
 | 
			
		||||
  set(WARNINGS_AS_ERRORS_DEFAULT "SERIOUS_ONLY")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
set(WARNINGS_AS_ERRORS
 | 
			
		||||
  ${WARNINGS_AS_ERRORS_DEFAULT}
 | 
			
		||||
  CACHE STRING
 | 
			
		||||
  "Treat warnings as errors. ON, OFF, or SERIOUS_ONLY"
 | 
			
		||||
)
 | 
			
		||||
 # Set GUI options
 | 
			
		||||
set_property(
 | 
			
		||||
  CACHE
 | 
			
		||||
  WARNINGS_AS_ERRORS
 | 
			
		||||
  PROPERTY STRINGS
 | 
			
		||||
  "ON;OFF;SERIOUS_ONLY"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if ("${WARNINGS_AS_ERRORS}" STREQUAL "ON")
 | 
			
		||||
  message(STATUS "Treating compiler warnings as errors")
 | 
			
		||||
  if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU"))
 | 
			
		||||
    list(APPEND Z3_COMPONENT_CXX_FLAGS "-Werror")
 | 
			
		||||
    # FIXME: Remove "x.." when CMP0054 is set to NEW
 | 
			
		||||
| 
						 | 
				
			
			@ -41,8 +117,14 @@ if (WARNINGS_AS_ERRORS)
 | 
			
		|||
  else()
 | 
			
		||||
    message(AUTHOR_WARNING "Unknown compiler")
 | 
			
		||||
  endif()
 | 
			
		||||
  message(STATUS "Treating compiler warnings as errors")
 | 
			
		||||
else()
 | 
			
		||||
elseif ("${WARNINGS_AS_ERRORS}" STREQUAL "SERIOUS_ONLY")
 | 
			
		||||
  message(STATUS "Treating only serious compiler warnings as errors")
 | 
			
		||||
  # Loop through the flags
 | 
			
		||||
  foreach (flag ${WARNING_AS_ERROR_FLAGS_TO_CHECK})
 | 
			
		||||
    # Add globally because some flags need to be passed at link time.
 | 
			
		||||
    z3_add_cxx_flag("${flag}" GLOBAL)
 | 
			
		||||
  endforeach()
 | 
			
		||||
elseif ("${WARNINGS_AS_ERRORS}" STREQUAL "OFF")
 | 
			
		||||
  message(STATUS "Not treating compiler warnings as errors")
 | 
			
		||||
  # FIXME: Remove "x.." when CMP0054 is set to NEW
 | 
			
		||||
  if ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
 | 
			
		||||
| 
						 | 
				
			
			@ -51,4 +133,8 @@ else()
 | 
			
		|||
    # build system.
 | 
			
		||||
    list(APPEND Z3_COMPONENT_CXX_FLAGS "/WX-")
 | 
			
		||||
  endif()
 | 
			
		||||
else()
 | 
			
		||||
  message(FATAL_ERROR
 | 
			
		||||
    "WARNINGS_AS_ERRORS set to unsupported value \"${WARNINGS_AS_ERRORS}\""
 | 
			
		||||
  )
 | 
			
		||||
endif()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@ include(CheckCXXCompilerFlag)
 | 
			
		|||
include(CMakeParseArguments)
 | 
			
		||||
 | 
			
		||||
function(z3_add_cxx_flag flag)
 | 
			
		||||
  CMAKE_PARSE_ARGUMENTS(z3_add_flag "REQUIRED" "" "" ${ARGN})
 | 
			
		||||
  CMAKE_PARSE_ARGUMENTS(z3_add_flag "REQUIRED;GLOBAL" "" "" ${ARGN})
 | 
			
		||||
  string(REPLACE "-" "_" SANITIZED_FLAG_NAME "${flag}")
 | 
			
		||||
  string(REPLACE "/" "_" SANITIZED_FLAG_NAME "${SANITIZED_FLAG_NAME}")
 | 
			
		||||
  string(REPLACE "=" "_" SANITIZED_FLAG_NAME "${SANITIZED_FLAG_NAME}")
 | 
			
		||||
| 
						 | 
				
			
			@ -16,8 +16,13 @@ function(z3_add_cxx_flag flag)
 | 
			
		|||
  endif()
 | 
			
		||||
  if (HAS_${SANITIZED_FLAG_NAME})
 | 
			
		||||
    message(STATUS "C++ compiler supports ${flag}")
 | 
			
		||||
    list(APPEND Z3_COMPONENT_CXX_FLAGS "${flag}")
 | 
			
		||||
    set(Z3_COMPONENT_CXX_FLAGS "${Z3_COMPONENT_CXX_FLAGS}" PARENT_SCOPE)
 | 
			
		||||
    if (z3_add_flag_GLOBAL)
 | 
			
		||||
      # Set globally
 | 
			
		||||
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag} " PARENT_SCOPE)
 | 
			
		||||
    else()
 | 
			
		||||
      list(APPEND Z3_COMPONENT_CXX_FLAGS "${flag}")
 | 
			
		||||
      set(Z3_COMPONENT_CXX_FLAGS "${Z3_COMPONENT_CXX_FLAGS}" PARENT_SCOPE)
 | 
			
		||||
    endif()
 | 
			
		||||
  else()
 | 
			
		||||
    message(STATUS "C++ compiler does not support ${flag}")
 | 
			
		||||
  endif()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,7 @@ ARG Z3_INSTALL_PREFIX=/usr
 | 
			
		|||
ARG Z3_STATIC_BUILD=0
 | 
			
		||||
# Blank default indicates use latest.
 | 
			
		||||
ARG Z3_SYSTEM_TEST_GIT_REVISION
 | 
			
		||||
ARG Z3_WARNINGS_AS_ERRORS=SERIOUS_ONLY
 | 
			
		||||
ARG Z3_VERBOSE_BUILD_OUTPUT=0
 | 
			
		||||
 | 
			
		||||
ENV \
 | 
			
		||||
| 
						 | 
				
			
			@ -55,6 +56,7 @@ ENV \
 | 
			
		|||
  Z3_STATIC_BUILD=${Z3_STATIC_BUILD} \
 | 
			
		||||
  Z3_SYSTEM_TEST_DIR=/home/user/z3_system_test \
 | 
			
		||||
  Z3_SYSTEM_TEST_GIT_REVISION=${Z3_SYSTEM_TEST_GIT_REVISION} \
 | 
			
		||||
  Z3_WARNINGS_AS_ERRORS=${Z3_WARNINGS_AS_ERRORS} \
 | 
			
		||||
  Z3_INSTALL_PREFIX=${Z3_INSTALL_PREFIX}
 | 
			
		||||
 | 
			
		||||
# We add context across incrementally to maximal cache reuse
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,6 +43,7 @@ the future.
 | 
			
		|||
* `Z3_VERBOSE_BUILD_OUTPUT` - Show compile commands in CMake builds (`0` or `1`)
 | 
			
		||||
* `Z3_STATIC_BUILD` - Build Z3 binaries and libraries statically (`0` or `1`)
 | 
			
		||||
* `Z3_SYSTEM_TEST_GIT_REVISION` - Git revision of [z3test](https://github.com/Z3Prover/z3test). If empty lastest revision will be used.
 | 
			
		||||
* `Z3_WARNINGS_AS_ERRORS` - Set the `WARNINGS_AS_ERRORS` CMake option pased to Z3 (`OFF`, `ON`, or `SERIOUS_ONLY`)
 | 
			
		||||
 | 
			
		||||
### Linux
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,8 @@ set -o pipefail
 | 
			
		|||
: ${DOTNET_BINDINGS?"DOTNET_BINDINGS must be specified"}
 | 
			
		||||
: ${JAVA_BINDINGS?"JAVA_BINDINGS must be specified"}
 | 
			
		||||
: ${USE_LTO?"USE_LTO must be specified"}
 | 
			
		||||
: ${Z3_INSTALL_PREFIX?"Z3_INSTALL_PREFIX"}
 | 
			
		||||
: ${Z3_INSTALL_PREFIX?"Z3_INSTALL_PREFIX must be specified"}
 | 
			
		||||
: ${Z3_WARNINGS_AS_ERRORS?"Z3_WARNINGS_AS_ERRORS must be specified"}
 | 
			
		||||
 | 
			
		||||
ADDITIONAL_Z3_OPTS=()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -120,6 +121,7 @@ cmake \
 | 
			
		|||
  -DCMAKE_BUILD_TYPE=${Z3_BUILD_TYPE} \
 | 
			
		||||
  -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} \
 | 
			
		||||
  -DCMAKE_INSTALL_PREFIX=${Z3_INSTALL_PREFIX} \
 | 
			
		||||
  -DWARNINGS_AS_ERRORS=${Z3_WARNINGS_AS_ERRORS} \
 | 
			
		||||
  "${ADDITIONAL_Z3_OPTS[@]}" \
 | 
			
		||||
  "${Z3_SRC_DIR}"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,6 +120,13 @@ if [ -n "${NO_SUPPRESS_OUTPUT}" ]; then
 | 
			
		|||
  )
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [ -n "${Z3_WARNINGS_AS_ERRORS}" ]; then
 | 
			
		||||
  BUILD_OPTS+=( \
 | 
			
		||||
    "--build-arg" \
 | 
			
		||||
    "Z3_WARNINGS_AS_ERRORS=${Z3_WARNINGS_AS_ERRORS}" \
 | 
			
		||||
  )
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
case ${LINUX_BASE} in
 | 
			
		||||
  ubuntu_14.04)
 | 
			
		||||
    BASE_DOCKER_FILE="${DOCKER_FILE_DIR}/z3_base_ubuntu_14.04.Dockerfile"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6054,6 +6054,24 @@ class Solver(Z3PPObject):
 | 
			
		|||
        """
 | 
			
		||||
        Z3_solver_pop(self.ctx.ref(), self.solver, num)
 | 
			
		||||
 | 
			
		||||
    def num_scopes(self):
 | 
			
		||||
        """Return the current number of backtracking points.
 | 
			
		||||
 | 
			
		||||
        >>> s = Solver()
 | 
			
		||||
        >>> s.num_scopes()
 | 
			
		||||
        0L
 | 
			
		||||
        >>> s.push()
 | 
			
		||||
        >>> s.num_scopes()
 | 
			
		||||
        1L
 | 
			
		||||
        >>> s.push()
 | 
			
		||||
        >>> s.num_scopes()
 | 
			
		||||
        2L
 | 
			
		||||
        >>> s.pop()
 | 
			
		||||
        >>> s.num_scopes()
 | 
			
		||||
        1L
 | 
			
		||||
        """
 | 
			
		||||
        return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
 | 
			
		||||
 | 
			
		||||
    def reset(self):
 | 
			
		||||
        """Remove all asserted constraints and backtracking points created using `push()`.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -421,7 +421,7 @@ typedef enum
 | 
			
		|||
     It has the same semantics as Z3_OP_BUREM, but created in a context where the second operand can be assumed to be non-zero.
 | 
			
		||||
 | 
			
		||||
   - Z3_OP_BSMOD_I: Binary signed modulus.
 | 
			
		||||
     It has the same semantics as Z3_OP_BSMOND, but created in a context where the second operand can be assumed to be non-zero.
 | 
			
		||||
     It has the same semantics as Z3_OP_BSMOD, but created in a context where the second operand can be assumed to be non-zero.
 | 
			
		||||
 | 
			
		||||
   - Z3_OP_PR_UNDEF: Undef/Null proof object.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -732,7 +732,7 @@ void bv_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol const
 | 
			
		|||
        op_names.push_back(builtin_name("bvudiv_i", OP_BUDIV_I));
 | 
			
		||||
        op_names.push_back(builtin_name("bvsrem_i", OP_BSREM_I));
 | 
			
		||||
        op_names.push_back(builtin_name("bvurem_i", OP_BUREM_I));
 | 
			
		||||
        op_names.push_back(builtin_name("bvumod_i", OP_BSMOD_I));
 | 
			
		||||
        op_names.push_back(builtin_name("bvsmod_i", OP_BSMOD_I));
 | 
			
		||||
 | 
			
		||||
        op_names.push_back(builtin_name("ext_rotate_left",OP_EXT_ROTATE_LEFT));
 | 
			
		||||
        op_names.push_back(builtin_name("ext_rotate_right",OP_EXT_ROTATE_RIGHT));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1632,8 +1632,6 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args,
 | 
			
		|||
 | 
			
		||||
    res_exp = e_exp;
 | 
			
		||||
 | 
			
		||||
    // Result could overflow into 4.xxx ...
 | 
			
		||||
 | 
			
		||||
    family_id bvfid = m_bv_util.get_fid();
 | 
			
		||||
    expr_ref res_sgn_c1(m), res_sgn_c2(m), res_sgn_c3(m);
 | 
			
		||||
    expr_ref not_e_sgn(m), not_f_sgn(m), not_sign_bv(m);
 | 
			
		||||
| 
						 | 
				
			
			@ -1646,11 +1644,34 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args,
 | 
			
		|||
    expr * res_sgn_or_args[3] = { res_sgn_c1, res_sgn_c2, res_sgn_c3 };
 | 
			
		||||
    res_sgn = m_bv_util.mk_bv_or(3, res_sgn_or_args);
 | 
			
		||||
 | 
			
		||||
    // Result could have overflown into 4.xxx.
 | 
			
		||||
    SASSERT(m_bv_util.get_bv_size(sig_abs) == 2 * sbits + 2);
 | 
			
		||||
    expr_ref ovfl_into_4(m);
 | 
			
		||||
    ovfl_into_4 = m.mk_eq(m_bv_util.mk_extract(2 * sbits + 1, 2 * sbits, sig_abs),
 | 
			
		||||
                          m_bv_util.mk_numeral(1, 2));
 | 
			
		||||
    dbg_decouple("fpa2bv_fma_ovfl_into_4", ovfl_into_4);
 | 
			
		||||
    if (sbits > 5) {
 | 
			
		||||
        sticky_raw = m_bv_util.mk_extract(sbits - 5, 0, sig_abs);
 | 
			
		||||
        sticky = m_bv_util.mk_zero_extend(sbits + 3, m.mk_app(bvfid, OP_BREDOR, sticky_raw.get()));
 | 
			
		||||
        expr * res_or_args[2] = { m_bv_util.mk_extract(2 * sbits - 1, sbits - 4, sig_abs), sticky };
 | 
			
		||||
        res_sig = m_bv_util.mk_bv_or(2, res_or_args);
 | 
			
		||||
        expr_ref sticky_raw(m), sig_upper(m), sticky_redd(m), res_sig_norm(m);
 | 
			
		||||
        sticky_raw = m_bv_util.mk_extract(sbits - 4, 0, sig_abs);
 | 
			
		||||
        sig_upper = m_bv_util.mk_extract(2 * sbits, sbits - 3, sig_abs);
 | 
			
		||||
        SASSERT(m_bv_util.get_bv_size(sig_upper) == sbits + 4);
 | 
			
		||||
        sticky_redd = m.mk_app(bvfid, OP_BREDOR, sticky_raw.get());
 | 
			
		||||
        sticky = m_bv_util.mk_zero_extend(sbits + 3, sticky_redd);
 | 
			
		||||
        expr * res_or_args[2] = { sig_upper, sticky };
 | 
			
		||||
        res_sig_norm = m_bv_util.mk_bv_or(2, res_or_args);
 | 
			
		||||
 | 
			
		||||
        expr_ref sticky_raw_ovfl(m), sig_upper_ovfl(m), sticky_redd_ovfl(m), sticky_ovfl(m), res_sig_ovfl(m);
 | 
			
		||||
        sticky_raw_ovfl = m_bv_util.mk_extract(sbits - 4, 0, sig_abs);
 | 
			
		||||
        sig_upper_ovfl = m_bv_util.mk_extract(2 * sbits, sbits - 3, sig_abs);
 | 
			
		||||
        SASSERT(m_bv_util.get_bv_size(sig_upper_ovfl) == sbits + 4);
 | 
			
		||||
        sticky_redd_ovfl = m.mk_app(bvfid, OP_BREDOR, sticky_raw_ovfl.get());
 | 
			
		||||
        sticky_ovfl = m_bv_util.mk_zero_extend(sbits + 3, sticky_redd_ovfl);
 | 
			
		||||
        expr * res_or_args_ovfl[2] = { sig_upper_ovfl, sticky_ovfl };
 | 
			
		||||
        res_sig_ovfl = m_bv_util.mk_bv_or(2, res_or_args_ovfl);
 | 
			
		||||
 | 
			
		||||
        res_sig = m.mk_ite(ovfl_into_4, res_sig_ovfl, res_sig_norm);
 | 
			
		||||
        res_exp = m.mk_ite(ovfl_into_4, m_bv_util.mk_bv_add(res_exp, m_bv_util.mk_numeral(1, ebits+2)),
 | 
			
		||||
                                        res_exp);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        unsigned too_short = 6 - sbits;
 | 
			
		||||
| 
						 | 
				
			
			@ -1658,6 +1679,8 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args,
 | 
			
		|||
        res_sig = m_bv_util.mk_extract(sbits + 3, 0, sig_abs);
 | 
			
		||||
    }
 | 
			
		||||
    dbg_decouple("fpa2bv_fma_add_sum_sticky", sticky);
 | 
			
		||||
    dbg_decouple("fpa2bv_fma_sig_abs", sig_abs);
 | 
			
		||||
    dbg_decouple("fpa2bv_fma_res_sig", res_sig);
 | 
			
		||||
    SASSERT(m_bv_util.get_bv_size(res_sig) == sbits + 4);
 | 
			
		||||
 | 
			
		||||
    expr_ref is_zero_sig(m), nil_sbits4(m);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ namespace sat {
 | 
			
		|||
    void model_converter::reset() {
 | 
			
		||||
        m_entries.finalize();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    void model_converter::operator()(model & m) const {
 | 
			
		||||
        vector<entry>::const_iterator begin = m_entries.begin();
 | 
			
		||||
        vector<entry>::const_iterator it    = m_entries.end();
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ namespace sat {
 | 
			
		|||
            literal_vector::const_iterator it2  = it->m_clauses.begin();
 | 
			
		||||
            literal_vector::const_iterator end2 = it->m_clauses.end();
 | 
			
		||||
            for (; it2 != end2; ++it2) {
 | 
			
		||||
                literal l  = *it2;
 | 
			
		||||
                literal l = *it2;
 | 
			
		||||
                if (l == null_literal) {
 | 
			
		||||
                    // end of clause
 | 
			
		||||
                    if (!sat) {
 | 
			
		||||
| 
						 | 
				
			
			@ -56,6 +56,7 @@ namespace sat {
 | 
			
		|||
                    sat = false;
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (sat)
 | 
			
		||||
                    continue;
 | 
			
		||||
                bool sign  = l.sign();
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +126,7 @@ namespace sat {
 | 
			
		|||
        }
 | 
			
		||||
        return ok;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    model_converter::entry & model_converter::mk(kind k, bool_var v) {
 | 
			
		||||
        m_entries.push_back(entry(k, v));
 | 
			
		||||
        entry & e = m_entries.back();
 | 
			
		||||
| 
						 | 
				
			
			@ -218,7 +219,7 @@ namespace sat {
 | 
			
		|||
                out << *it2;
 | 
			
		||||
            }
 | 
			
		||||
            out << ")";
 | 
			
		||||
        }    
 | 
			
		||||
        }
 | 
			
		||||
        out << ")\n";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -237,4 +238,22 @@ namespace sat {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned model_converter::max_var(unsigned min) const {
 | 
			
		||||
        unsigned result = min;
 | 
			
		||||
        vector<entry>::const_iterator it = m_entries.begin();
 | 
			
		||||
        vector<entry>::const_iterator end = m_entries.end();
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            literal_vector::const_iterator lvit = it->m_clauses.begin();
 | 
			
		||||
            literal_vector::const_iterator lvend = it->m_clauses.end();
 | 
			
		||||
            for (; lvit != lvend; ++lvit) {
 | 
			
		||||
                literal l = *lvit;
 | 
			
		||||
                if (l != null_literal) {
 | 
			
		||||
                    if (l.var() > result)
 | 
			
		||||
                        result = l.var();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ namespace sat {
 | 
			
		|||
       \brief Stores eliminated variables and Blocked clauses.
 | 
			
		||||
       It uses these clauses to extend/patch the model produced for the
 | 
			
		||||
       simplified CNF formula.
 | 
			
		||||
       
 | 
			
		||||
 | 
			
		||||
       This information may also be used to support incremental solving.
 | 
			
		||||
       If new clauses are asserted into the SAT engine, then we can
 | 
			
		||||
       restore the state by re-asserting all clauses in the model
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +50,7 @@ namespace sat {
 | 
			
		|||
                m_kind(src.m_kind),
 | 
			
		||||
                m_clauses(src.m_clauses) {
 | 
			
		||||
            }
 | 
			
		||||
            bool_var var() const { return m_var; } 
 | 
			
		||||
            bool_var var() const { return m_var; }
 | 
			
		||||
            kind get_kind() const { return static_cast<kind>(m_kind); }
 | 
			
		||||
        };
 | 
			
		||||
    private:
 | 
			
		||||
| 
						 | 
				
			
			@ -74,8 +74,9 @@ namespace sat {
 | 
			
		|||
 | 
			
		||||
        void copy(model_converter const & src);
 | 
			
		||||
        void collect_vars(bool_var_set & s) const;
 | 
			
		||||
        unsigned max_var(unsigned min) const;
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2628,7 +2628,7 @@ namespace sat {
 | 
			
		|||
        unsigned j = 0;
 | 
			
		||||
        for (unsigned i = 0; i < clauses.size(); ++i) {
 | 
			
		||||
            clause & c = *(clauses[i]);
 | 
			
		||||
            if (c.contains(lit)) {
 | 
			
		||||
            if (c.contains(lit) || c.contains(~lit)) {
 | 
			
		||||
                detach_clause(c);
 | 
			
		||||
                del_clause(c);
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -2684,6 +2684,7 @@ namespace sat {
 | 
			
		|||
            w = max_var(m_clauses, w);
 | 
			
		||||
            w = max_var(true, w);
 | 
			
		||||
            w = max_var(false, w);
 | 
			
		||||
            v = m_mc.max_var(w);
 | 
			
		||||
            for (unsigned i = 0; i < m_trail.size(); ++i) {
 | 
			
		||||
                if (m_trail[i].var() > w) w = m_trail[i].var();
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -3150,9 +3151,9 @@ namespace sat {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    // Algorithm 7: Corebased Algorithm with Chunking
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    static void back_remove(sat::literal_vector& lits, sat::literal l) {
 | 
			
		||||
        for (unsigned i = lits.size(); i > 0; ) {
 | 
			
		||||
            --i;
 | 
			
		||||
| 
						 | 
				
			
			@ -3176,7 +3177,7 @@ namespace sat {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    static lbool core_chunking(sat::solver& s, model const& m, sat::bool_var_vector const& vars, sat::literal_vector const& asms, vector<sat::literal_vector>& conseq, unsigned K) {
 | 
			
		||||
        sat::literal_vector lambda;
 | 
			
		||||
        for (unsigned i = 0; i < vars.size(); i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3375,7 +3376,7 @@ namespace sat {
 | 
			
		|||
        if (check_inconsistent()) return l_false;
 | 
			
		||||
 | 
			
		||||
        unsigned num_iterations = 0;
 | 
			
		||||
        extract_fixed_consequences(unfixed_lits, assumptions, unfixed_vars, conseq); 
 | 
			
		||||
        extract_fixed_consequences(unfixed_lits, assumptions, unfixed_vars, conseq);
 | 
			
		||||
        update_unfixed_literals(unfixed_lits, unfixed_vars);
 | 
			
		||||
        while (!unfixed_lits.empty()) {
 | 
			
		||||
            if (scope_lvl() > 1) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3390,7 +3391,7 @@ namespace sat {
 | 
			
		|||
            unsigned num_assigned = 0;
 | 
			
		||||
            lbool is_sat = l_true;
 | 
			
		||||
            for (; it != end; ++it) {
 | 
			
		||||
                literal lit = *it;                
 | 
			
		||||
                literal lit = *it;
 | 
			
		||||
                if (value(lit) != l_undef) {
 | 
			
		||||
                    ++num_fixed;
 | 
			
		||||
                    if (lvl(lit) <= 1 && value(lit) == l_true) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3445,8 +3446,8 @@ namespace sat {
 | 
			
		|||
                       << " iterations: " << num_iterations
 | 
			
		||||
                       << " variables: " << unfixed_lits.size()
 | 
			
		||||
                       << " fixed: " << conseq.size()
 | 
			
		||||
                       << " status: " << is_sat 
 | 
			
		||||
                       << " pre-assigned: " << num_fixed                        
 | 
			
		||||
                       << " status: " << is_sat
 | 
			
		||||
                       << " pre-assigned: " << num_fixed
 | 
			
		||||
                       << " unfixed: " << lits.size() - conseq.size() - unfixed_lits.size()
 | 
			
		||||
                       << ")\n";);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -131,7 +131,7 @@ public:
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_literal(expr* e) const {
 | 
			
		||||
        return 
 | 
			
		||||
        return
 | 
			
		||||
            is_uninterp_const(e) ||
 | 
			
		||||
            (m.is_not(e, e) && is_uninterp_const(e));
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -153,7 +153,7 @@ public:
 | 
			
		|||
                asm2fml.insert(assumptions[i], assumptions[i]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        TRACE("sat", tout << _assumptions << "\n";);
 | 
			
		||||
        dep2asm_t dep2asm;
 | 
			
		||||
        m_model = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +163,7 @@ public:
 | 
			
		|||
        if (r != l_true) return r;
 | 
			
		||||
 | 
			
		||||
        r = m_solver.check(m_asms.size(), m_asms.c_ptr());
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        switch (r) {
 | 
			
		||||
        case l_true:
 | 
			
		||||
            if (sz > 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -280,14 +280,14 @@ public:
 | 
			
		|||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // build map from bound variables to 
 | 
			
		||||
        // build map from bound variables to
 | 
			
		||||
        // the consequences that cover them.
 | 
			
		||||
        u_map<unsigned> bool_var2conseq;
 | 
			
		||||
        for (unsigned i = 0; i < lconseq.size(); ++i) {
 | 
			
		||||
            TRACE("sat", tout << lconseq[i] << "\n";);
 | 
			
		||||
            bool_var2conseq.insert(lconseq[i][0].var(), i);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        // extract original fixed variables
 | 
			
		||||
        u_map<expr*> asm2dep;
 | 
			
		||||
        extract_asm2dep(dep2asm, asm2dep);
 | 
			
		||||
| 
						 | 
				
			
			@ -441,7 +441,7 @@ private:
 | 
			
		|||
 | 
			
		||||
    lbool internalize_vars(expr_ref_vector const& vars, sat::bool_var_vector& bvars) {
 | 
			
		||||
        for (unsigned i = 0; i < vars.size(); ++i) {
 | 
			
		||||
            internalize_var(vars[i], bvars);            
 | 
			
		||||
            internalize_var(vars[i], bvars);
 | 
			
		||||
        }
 | 
			
		||||
        return l_true;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -453,7 +453,7 @@ private:
 | 
			
		|||
        bool internalized = false;
 | 
			
		||||
        if (is_uninterp_const(v) && m.is_bool(v)) {
 | 
			
		||||
            sat::bool_var b = m_map.to_bool_var(v);
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            if (b != sat::null_bool_var) {
 | 
			
		||||
                bvars.push_back(b);
 | 
			
		||||
                internalized = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -479,7 +479,7 @@ private:
 | 
			
		|||
        else if (is_uninterp_const(v) && bvutil.is_bv(v)) {
 | 
			
		||||
            // variable does not occur in assertions, so is unconstrained.
 | 
			
		||||
        }
 | 
			
		||||
        CTRACE("sat", !internalized, tout << "unhandled variable " << mk_pp(v, m) << "\n";);        
 | 
			
		||||
        CTRACE("sat", !internalized, tout << "unhandled variable " << mk_pp(v, m) << "\n";);
 | 
			
		||||
        return internalized;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -506,7 +506,7 @@ private:
 | 
			
		|||
        }
 | 
			
		||||
        expr_ref val(m);
 | 
			
		||||
        expr_ref_vector conj(m);
 | 
			
		||||
        internalize_value(value, v, val);        
 | 
			
		||||
        internalize_value(value, v, val);
 | 
			
		||||
        while (!premises.empty()) {
 | 
			
		||||
            expr* e = 0;
 | 
			
		||||
            VERIFY(asm2dep.find(premises.pop().index(), e));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,7 @@ bool cached_var_subst::key_eq_proc::operator()(cached_var_subst::key * k1, cache
 | 
			
		|||
        return false;
 | 
			
		||||
    if (k1->m_num_bindings != k2->m_num_bindings)
 | 
			
		||||
        return false;
 | 
			
		||||
    for (unsigned i = 0; i < k1->m_num_bindings; i++) 
 | 
			
		||||
    for (unsigned i = 0; i < k1->m_num_bindings; i++)
 | 
			
		||||
        if (k1->m_bindings[i] != k2->m_bindings[i])
 | 
			
		||||
            return false;
 | 
			
		||||
    return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -49,9 +49,9 @@ void cached_var_subst::operator()(quantifier * qa, unsigned num_bindings, smt::e
 | 
			
		|||
 | 
			
		||||
    new_key->m_qa           = qa;
 | 
			
		||||
    new_key->m_num_bindings = num_bindings;
 | 
			
		||||
    for (unsigned i = 0; i < num_bindings; i++) 
 | 
			
		||||
    for (unsigned i = 0; i < num_bindings; i++)
 | 
			
		||||
        new_key->m_bindings[i] = bindings[i]->get_owner();
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    instances::entry * entry = m_instances.insert_if_not_there2(new_key, 0);
 | 
			
		||||
    if (entry->get_data().m_key != new_key) {
 | 
			
		||||
        SASSERT(entry->get_data().m_value != 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -60,20 +60,27 @@ void cached_var_subst::operator()(quantifier * qa, unsigned num_bindings, smt::e
 | 
			
		|||
        result = entry->get_data().m_value;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    m_proc(qa->get_expr(), new_key->m_num_bindings, new_key->m_bindings, result);
 | 
			
		||||
 | 
			
		||||
    SASSERT(entry->get_data().m_value == 0);
 | 
			
		||||
    try {
 | 
			
		||||
        m_proc(qa->get_expr(), new_key->m_num_bindings, new_key->m_bindings, result);
 | 
			
		||||
    }
 | 
			
		||||
    catch (...) {
 | 
			
		||||
        // CMW: The var_subst reducer was interrupted and m_instances is
 | 
			
		||||
        // in an inconsistent state; we need to remove (new_key, 0).
 | 
			
		||||
        m_instances.remove(new_key);
 | 
			
		||||
        throw; // Throw on to smt::qi_queue/smt::solver.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // cache result
 | 
			
		||||
    entry->get_data().m_value = result;
 | 
			
		||||
 | 
			
		||||
    // remove key from cache
 | 
			
		||||
    m_new_keys[num_bindings] = 0;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    // increment reference counters
 | 
			
		||||
    m_refs.push_back(qa);
 | 
			
		||||
    for (unsigned i = 0; i < new_key->m_num_bindings; i++)
 | 
			
		||||
        m_refs.push_back(new_key->m_bindings[i]);
 | 
			
		||||
    m_refs.push_back(result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ namespace smt {
 | 
			
		|||
        init_parser_vars();
 | 
			
		||||
        m_vals.resize(15, 0.0f);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    qi_queue::~qi_queue() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +50,7 @@ namespace smt {
 | 
			
		|||
        if (!m_parser.parse_string(m_params.m_qi_cost.c_str(), m_cost_function)) {
 | 
			
		||||
            // it is not reasonable to abort here during the creation of smt::context just because an invalid option was provided.
 | 
			
		||||
            // throw default_exception("invalid cost function %s", m_params.m_qi_cost.c_str());
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            // using warning message instead
 | 
			
		||||
            warning_msg("invalid cost function '%s', switching to default one", m_params.m_qi_cost.c_str());
 | 
			
		||||
            // Trying again with default function
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ namespace smt {
 | 
			
		|||
        m_vals[SIZE]               = static_cast<float>(stat->get_size());
 | 
			
		||||
        m_vals[DEPTH]              = static_cast<float>(stat->get_depth());
 | 
			
		||||
        m_vals[GENERATION]         = static_cast<float>(generation);
 | 
			
		||||
        m_vals[QUANT_GENERATION]   = static_cast<float>(stat->get_generation()); 
 | 
			
		||||
        m_vals[QUANT_GENERATION]   = static_cast<float>(stat->get_generation());
 | 
			
		||||
        m_vals[WEIGHT]             = static_cast<float>(q->get_weight());
 | 
			
		||||
        m_vals[VARS]               = static_cast<float>(q->get_num_decls());
 | 
			
		||||
        m_vals[PATTERN_WIDTH]      = pat ? static_cast<float>(pat->get_num_args()) : 1.0f;
 | 
			
		||||
| 
						 | 
				
			
			@ -118,7 +118,7 @@ namespace smt {
 | 
			
		|||
        TRACE("qi_queue_detail", for (unsigned i = 0; i < m_vals.size(); i++) { tout << m_vals[i] << " "; } tout << "\n";);
 | 
			
		||||
        return stat;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    float qi_queue::get_cost(quantifier * q, app * pat, unsigned generation, unsigned min_top_generation, unsigned max_top_generation) {
 | 
			
		||||
        quantifier_stat * stat = set_values(q, pat, generation, min_top_generation, max_top_generation, 0);
 | 
			
		||||
        float r = m_evaluator(m_cost_function, m_vals.size(), m_vals.c_ptr());
 | 
			
		||||
| 
						 | 
				
			
			@ -132,11 +132,11 @@ namespace smt {
 | 
			
		|||
        float r = m_evaluator(m_new_gen_function, m_vals.size(), m_vals.c_ptr());
 | 
			
		||||
        return static_cast<unsigned>(r);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    void qi_queue::insert(fingerprint * f, app * pat, unsigned generation, unsigned min_top_generation, unsigned max_top_generation) {
 | 
			
		||||
        quantifier * q         = static_cast<quantifier*>(f->get_data());
 | 
			
		||||
        float cost             = get_cost(q, pat, generation, min_top_generation, max_top_generation);
 | 
			
		||||
        TRACE("qi_queue_detail", 
 | 
			
		||||
        TRACE("qi_queue_detail",
 | 
			
		||||
              tout << "new instance of " << q->get_qid() << ", weight " << q->get_weight()
 | 
			
		||||
              << ", generation: " << generation << ", scope_level: " << m_context.get_scope_level() << ", cost: " << cost << "\n";
 | 
			
		||||
              for (unsigned i = 0; i < f->get_num_args(); i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -157,7 +157,7 @@ namespace smt {
 | 
			
		|||
            quantifier * qa    = static_cast<quantifier*>(f->get_data());
 | 
			
		||||
 | 
			
		||||
            if (curr.m_cost <= m_eager_cost_threshold) {
 | 
			
		||||
                instantiate(curr);    
 | 
			
		||||
                instantiate(curr);
 | 
			
		||||
            }
 | 
			
		||||
            else if (m_params.m_qi_promote_unsat && m_checker.is_unsat(qa->get_expr(), f->get_num_args(), f->get_args())) {
 | 
			
		||||
                // do not delay instances that produce a conflict.
 | 
			
		||||
| 
						 | 
				
			
			@ -193,7 +193,7 @@ namespace smt {
 | 
			
		|||
                // This nasty side-effect may change the behavior of Z3.
 | 
			
		||||
                m_manager.trace_stream() << " #" << bindings[i]->get_owner_id();
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
            if (m_manager.proofs_enabled())
 | 
			
		||||
                m_manager.trace_stream() << " #" << proof_id;
 | 
			
		||||
| 
						 | 
				
			
			@ -233,7 +233,7 @@ namespace smt {
 | 
			
		|||
        if (m_manager.is_true(s_instance)) {
 | 
			
		||||
            TRACE("checker", tout << "reduced to true, before:\n" << mk_ll_pp(instance, m_manager););
 | 
			
		||||
 | 
			
		||||
            if (m_manager.has_trace_stream()) 
 | 
			
		||||
            if (m_manager.has_trace_stream())
 | 
			
		||||
                m_manager.trace_stream() << "[end-of-instance]\n";
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
| 
						 | 
				
			
			@ -278,7 +278,7 @@ namespace smt {
 | 
			
		|||
                pr1             = m_manager.mk_modus_ponens(qi_pr, rw);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                app * bare_s_lemma  = m_manager.mk_or(m_manager.mk_not(q), s_instance); 
 | 
			
		||||
                app * bare_s_lemma  = m_manager.mk_or(m_manager.mk_not(q), s_instance);
 | 
			
		||||
                proof * prs[1]      = { pr.get() };
 | 
			
		||||
                proof * cg          = m_manager.mk_congruence(bare_lemma, bare_s_lemma, 1, prs);
 | 
			
		||||
                proof * rw          = m_manager.mk_rewrite(bare_s_lemma, lemma);
 | 
			
		||||
| 
						 | 
				
			
			@ -331,13 +331,13 @@ namespace smt {
 | 
			
		|||
        s.m_instances_lim          = m_instances.size();
 | 
			
		||||
        s.m_instantiated_trail_lim = m_instantiated_trail.size();
 | 
			
		||||
    }
 | 
			
		||||
     
 | 
			
		||||
 | 
			
		||||
    void qi_queue::pop_scope(unsigned num_scopes) {
 | 
			
		||||
        unsigned new_lvl    = m_scopes.size() - num_scopes;
 | 
			
		||||
        scope & s           = m_scopes[new_lvl];
 | 
			
		||||
        unsigned old_sz     = s.m_instantiated_trail_lim;
 | 
			
		||||
        unsigned sz         = m_instantiated_trail.size();
 | 
			
		||||
        for (unsigned i = old_sz; i < sz; i++) 
 | 
			
		||||
        for (unsigned i = old_sz; i < sz; i++)
 | 
			
		||||
            m_delayed_entries[m_instantiated_trail[i]].m_instantiated = false;
 | 
			
		||||
        m_instantiated_trail.shrink(old_sz);
 | 
			
		||||
        m_delayed_entries.shrink(s.m_delayed_entries_lim);
 | 
			
		||||
| 
						 | 
				
			
			@ -359,7 +359,7 @@ namespace smt {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    bool qi_queue::final_check_eh() {
 | 
			
		||||
        TRACE("qi_queue", display_delayed_instances_stats(tout); tout << "lazy threshold: " << m_params.m_qi_lazy_threshold 
 | 
			
		||||
        TRACE("qi_queue", display_delayed_instances_stats(tout); tout << "lazy threshold: " << m_params.m_qi_lazy_threshold
 | 
			
		||||
              << ", scope_level: " << m_context.get_scope_level() << "\n";);
 | 
			
		||||
        if (m_params.m_qi_conservative_final_check) {
 | 
			
		||||
            bool  init = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -379,7 +379,7 @@ namespace smt {
 | 
			
		|||
                entry & e       = m_delayed_entries[i];
 | 
			
		||||
                TRACE("qi_queue", tout << e.m_qb << ", cost: " << e.m_cost << ", instantiated: " << e.m_instantiated << "\n";);
 | 
			
		||||
                if (!e.m_instantiated && e.m_cost <= min_cost) {
 | 
			
		||||
                    TRACE("qi_queue", 
 | 
			
		||||
                    TRACE("qi_queue",
 | 
			
		||||
                          tout << "lazy quantifier instantiation...\n" << mk_pp(static_cast<quantifier*>(e.m_qb->get_data()), m_manager) << "\ncost: " << e.m_cost << "\n";);
 | 
			
		||||
                    result             = false;
 | 
			
		||||
                    m_instantiated_trail.push_back(i);
 | 
			
		||||
| 
						 | 
				
			
			@ -389,13 +389,13 @@ namespace smt {
 | 
			
		|||
            }
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
       
 | 
			
		||||
 | 
			
		||||
        bool result = true;
 | 
			
		||||
        for (unsigned i = 0; i < m_delayed_entries.size(); i++) {
 | 
			
		||||
            entry & e       = m_delayed_entries[i];
 | 
			
		||||
            TRACE("qi_queue", tout << e.m_qb << ", cost: " << e.m_cost << ", instantiated: " << e.m_instantiated << "\n";);
 | 
			
		||||
            if (!e.m_instantiated && e.m_cost <= m_params.m_qi_lazy_threshold)  {
 | 
			
		||||
                TRACE("qi_queue", 
 | 
			
		||||
                TRACE("qi_queue",
 | 
			
		||||
                      tout << "lazy quantifier instantiation...\n" << mk_pp(static_cast<quantifier*>(e.m_qb->get_data()), m_manager) << "\ncost: " << e.m_cost << "\n";);
 | 
			
		||||
                result             = false;
 | 
			
		||||
                m_instantiated_trail.push_back(i);
 | 
			
		||||
| 
						 | 
				
			
			@ -443,7 +443,7 @@ namespace smt {
 | 
			
		|||
            quantifier * qa = *it2;
 | 
			
		||||
            delayed_qa_info info;
 | 
			
		||||
            qa2info.find(qa, info);
 | 
			
		||||
            out << qa->get_qid() << ": " << info.m_num << " [" << info.m_min_cost << ", " << info.m_max_cost << "]\n"; 
 | 
			
		||||
            out << qa->get_qid() << ": " << info.m_num << " [" << info.m_min_cost << ", " << info.m_max_cost << "]\n";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -482,6 +482,6 @@ namespace smt {
 | 
			
		|||
        }
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -135,7 +135,7 @@ namespace smt {
 | 
			
		|||
                m_qi_queue.insert(f, pat, max_generation, min_top_generation, max_top_generation); // TODO
 | 
			
		||||
                m_num_instances++;
 | 
			
		||||
            }
 | 
			
		||||
            TRACE("quantifier", 
 | 
			
		||||
            TRACE("quantifier",
 | 
			
		||||
                  tout << mk_pp(q, m()) << " ";
 | 
			
		||||
                  for (unsigned i = 0; i < num_bindings; ++i) {
 | 
			
		||||
                      tout << mk_pp(bindings[i]->get_owner(), m()) << " ";
 | 
			
		||||
| 
						 | 
				
			
			@ -372,7 +372,7 @@ namespace smt {
 | 
			
		|||
        quantifier_manager_plugin * plugin = m_imp->m_plugin->mk_fresh();
 | 
			
		||||
        m_imp->~imp();
 | 
			
		||||
        m_imp = new (m_imp) imp(*this, ctx, p, plugin);
 | 
			
		||||
        plugin->set_manager(*this);        
 | 
			
		||||
        plugin->set_manager(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void quantifier_manager::display(std::ostream & out) const {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ namespace smt {
 | 
			
		|||
        };
 | 
			
		||||
 | 
			
		||||
        bool model_based() const;
 | 
			
		||||
	bool mbqi_enabled(quantifier *q) const; // can mbqi instantiate this quantifier?
 | 
			
		||||
        bool mbqi_enabled(quantifier *q) const; // can mbqi instantiate this quantifier?
 | 
			
		||||
        void adjust_model(proto_model * m);
 | 
			
		||||
        check_model_result check_model(proto_model * m, obj_map<enode, app *> const & root2value);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -167,7 +167,7 @@ namespace smt {
 | 
			
		|||
        virtual void push() = 0;
 | 
			
		||||
        virtual void pop(unsigned num_scopes) = 0;
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,10 +47,10 @@ class collect_statistics_tactic : public tactic {
 | 
			
		|||
 | 
			
		||||
public:
 | 
			
		||||
    collect_statistics_tactic(ast_manager & m, params_ref const & p) :
 | 
			
		||||
        m(m), 
 | 
			
		||||
        m(m),
 | 
			
		||||
        m_params(p) {
 | 
			
		||||
    }    
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~collect_statistics_tactic() {}
 | 
			
		||||
 | 
			
		||||
    virtual tactic * translate(ast_manager & m_) {
 | 
			
		||||
| 
						 | 
				
			
			@ -60,21 +60,21 @@ public:
 | 
			
		|||
    virtual void updt_params(params_ref const & p) {
 | 
			
		||||
        m_params = p;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    virtual void collect_param_descrs(param_descrs & r) {}
 | 
			
		||||
 | 
			
		||||
    virtual void operator()(goal_ref const & g, goal_ref_buffer & result,
 | 
			
		||||
                            model_converter_ref & mc, proof_converter_ref & pc, 
 | 
			
		||||
                            model_converter_ref & mc, proof_converter_ref & pc,
 | 
			
		||||
                            expr_dependency_ref & core) {
 | 
			
		||||
        mc = 0;
 | 
			
		||||
        tactic_report report("collect-statistics", *g);        
 | 
			
		||||
        
 | 
			
		||||
        tactic_report report("collect-statistics", *g);
 | 
			
		||||
 | 
			
		||||
        collect_proc cp(m, m_stats);
 | 
			
		||||
        expr_mark visited;                            
 | 
			
		||||
        expr_mark visited;
 | 
			
		||||
        const unsigned sz = g->size();
 | 
			
		||||
        for (unsigned i = 0; i < sz; i++)
 | 
			
		||||
            for_each_expr(cp, visited, g->form(i));
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        std::cout << "(" << std::endl;
 | 
			
		||||
        stats_type::iterator it = m_stats.begin();
 | 
			
		||||
        stats_type::iterator end = m_stats.end();
 | 
			
		||||
| 
						 | 
				
			
			@ -84,7 +84,7 @@ public:
 | 
			
		|||
 | 
			
		||||
        g->inc_depth();
 | 
			
		||||
        result.push_back(g.get());
 | 
			
		||||
    }    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void cleanup() {}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -98,11 +98,12 @@ protected:
 | 
			
		|||
    class collect_proc {
 | 
			
		||||
    public:
 | 
			
		||||
        ast_manager &            m;
 | 
			
		||||
        stats_type &             m_stats;        
 | 
			
		||||
        stats_type &             m_stats;
 | 
			
		||||
        obj_hashtable<sort>      m_seen_sorts;
 | 
			
		||||
        obj_hashtable<func_decl> m_seen_func_decls;
 | 
			
		||||
        unsigned                 m_qdepth;
 | 
			
		||||
 | 
			
		||||
        collect_proc(ast_manager & m, stats_type & s) : m(m), m_stats(s) {}
 | 
			
		||||
        collect_proc(ast_manager & m, stats_type & s) : m(m), m_stats(s), m_qdepth(0) {}
 | 
			
		||||
 | 
			
		||||
        void operator()(var * v) {
 | 
			
		||||
            m_stats["bound-variables"]++;
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +114,18 @@ protected:
 | 
			
		|||
            m_stats["quantifiers"]++;
 | 
			
		||||
            SASSERT(is_app(q->get_expr()));
 | 
			
		||||
            app * body = to_app(q->get_expr());
 | 
			
		||||
            if (q->is_forall())
 | 
			
		||||
                m_stats["forall-variables"] += q->get_num_decls();
 | 
			
		||||
            else
 | 
			
		||||
                m_stats["exists-variables"] += q->get_num_decls();
 | 
			
		||||
            m_stats["patterns"] += q->get_num_patterns();
 | 
			
		||||
            m_stats["no-patterns"] += q->get_num_no_patterns();
 | 
			
		||||
            m_qdepth++;
 | 
			
		||||
            if (m_stats.find("max-quantification-depth") == m_stats.end() ||
 | 
			
		||||
                m_stats["max-quantification-depth"] < m_qdepth)
 | 
			
		||||
                m_stats["max-quantification-depth"] = m_qdepth;
 | 
			
		||||
            this->operator()(body);
 | 
			
		||||
            m_qdepth--;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void operator()(app * n) {
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +133,7 @@ protected:
 | 
			
		|||
            this->operator()(n->get_decl());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void operator()(sort * s) {            
 | 
			
		||||
        void operator()(sort * s) {
 | 
			
		||||
            if (m.is_uninterp(s)) {
 | 
			
		||||
                if (!m_seen_sorts.contains(s)) {
 | 
			
		||||
                    m_stats["uninterpreted-sorts"]++;
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +147,7 @@ protected:
 | 
			
		|||
                std::stringstream ss;
 | 
			
		||||
                ss << "(declare-sort " << mk_ismt2_pp(s, m, prms) << ")";
 | 
			
		||||
                m_stats[ss.str()]++;
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
                if (s->get_info()->get_num_parameters() > 0) {
 | 
			
		||||
                    std::stringstream ssname;
 | 
			
		||||
                    ssname << "(declare-sort (_ " << s->get_name() << " *))";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue