mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 19:52:29 +00:00 
			
		
		
		
	merge
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
						commit
						dc879dc3fb
					
				
					 74 changed files with 585 additions and 259 deletions
				
			
		|  | @ -1,15 +1,6 @@ | |||
| # Enforce some CMake policies | ||||
| cmake_minimum_required(VERSION 3.4) | ||||
| 
 | ||||
| if (POLICY CMP0054) | ||||
|   cmake_policy(SET CMP0054 NEW) | ||||
| endif() | ||||
| 
 | ||||
| if (POLICY CMP0042) | ||||
|   # Enable `MACOSX_RPATH` by default. | ||||
|   cmake_policy(SET CMP0042 NEW) | ||||
| endif() | ||||
| 
 | ||||
| set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cxx_compiler_flags_overrides.cmake") | ||||
| project(Z3 VERSION 4.8.11.0 LANGUAGES CXX) | ||||
| 
 | ||||
|  | @ -42,7 +33,7 @@ set(z3_polluted_tree_msg | |||
| ################################################################################ | ||||
| # Sanity check - Disallow building in source | ||||
| ################################################################################ | ||||
| if ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}") | ||||
| if (PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) | ||||
|   message(FATAL_ERROR "In source builds are not allowed. You should invoke " | ||||
|           "CMake from a different directory.") | ||||
| endif() | ||||
|  | @ -194,28 +185,28 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) | |||
| ################################################################################ | ||||
| # Platform detection | ||||
| ################################################################################ | ||||
| if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") | ||||
| if (CMAKE_SYSTEM_NAME STREQUAL "Linux") | ||||
|   message(STATUS "Platform: Linux") | ||||
|   list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_LINUX_") | ||||
|   if ("${TARGET_ARCHITECTURE}" STREQUAL "x86_64") | ||||
|   if (TARGET_ARCHITECTURE STREQUAL "x86_64") | ||||
|     list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_USE_THREAD_LOCAL") | ||||
|   endif() | ||||
| elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Android") | ||||
| elseif (CMAKE_SYSTEM_NAME STREQUAL "Android") | ||||
|   message(STATUS "Platform: Android") | ||||
|   list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_ANDROID_") | ||||
| elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "GNU") | ||||
| elseif (CMAKE_SYSTEM_NAME MATCHES "GNU") | ||||
|   message(STATUS "Platform: GNU/Hurd") | ||||
|   list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_HURD_") | ||||
| elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") | ||||
| elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin") | ||||
|   # Does macOS really not need any special flags? | ||||
|   message(STATUS "Platform: Darwin") | ||||
| elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD") | ||||
| elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") | ||||
|   message(STATUS "Platform: FreeBSD") | ||||
|   list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_FREEBSD_") | ||||
| elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "NetBSD") | ||||
| elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD") | ||||
|   message(STATUS "Platform: NetBSD") | ||||
|   list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_NetBSD_") | ||||
| elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD") | ||||
| elseif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") | ||||
|   message(STATUS "Platform: OpenBSD") | ||||
|   list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_OPENBSD_") | ||||
| elseif (CYGWIN) | ||||
|  | @ -251,8 +242,7 @@ if (Z3_USE_LIB_GMP) | |||
|   # can't be found | ||||
|   find_package(GMP REQUIRED) | ||||
|   message(STATUS "Using libgmp") | ||||
|   list(APPEND Z3_DEPENDENT_LIBS ${GMP_C_LIBRARIES}) | ||||
|   list(APPEND Z3_COMPONENT_EXTRA_INCLUDE_DIRS ${GMP_INCLUDE_DIRS}) | ||||
|   list(APPEND Z3_DEPENDENT_LIBS GMP::GMP) | ||||
|   list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_MP_GMP") | ||||
| else() | ||||
|   list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_MP_INTERNAL") | ||||
|  | @ -292,18 +282,18 @@ endif() | |||
| # FP math | ||||
| ################################################################################ | ||||
| # FIXME: Support ARM "-mfpu=vfp -mfloat-abi=hard" | ||||
| if (("${TARGET_ARCHITECTURE}" STREQUAL "x86_64") OR ("${TARGET_ARCHITECTURE}" STREQUAL "i686")) | ||||
|   if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel")) | ||||
|     if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel") | ||||
| if ((TARGET_ARCHITECTURE STREQUAL "x86_64") OR (TARGET_ARCHITECTURE STREQUAL "i686")) | ||||
|   if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Intel")) | ||||
|     if (CMAKE_CXX_COMPILER_ID MATCHES "Intel") | ||||
|       # Intel's compiler requires linking with libiomp5 | ||||
|       list(APPEND Z3_DEPENDENT_LIBS "iomp5") | ||||
|     endif() | ||||
|     set(SSE_FLAGS "-mfpmath=sse" "-msse" "-msse2") | ||||
|   elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel") | ||||
|   elseif (CMAKE_CXX_COMPILER_ID MATCHES "Intel") | ||||
|     set(SSE_FLAGS "-mfpmath=sse" "-msse" "-msse2") | ||||
|     # Intel's compiler requires linking with libiomp5  | ||||
|     list(APPEND Z3_DEPENDENT_LIBS "iomp5")  | ||||
|   elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") | ||||
|   elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | ||||
|     set(SSE_FLAGS "/arch:SSE2") | ||||
|   else() | ||||
|     message(FATAL_ERROR "Unknown compiler ${CMAKE_CXX_COMPILER_ID}") | ||||
|  | @ -320,7 +310,7 @@ endif() | |||
| ################################################################################ | ||||
| set(THREADS_PREFER_PTHREAD_FLAG TRUE) | ||||
| find_package(Threads) | ||||
| list(APPEND Z3_DEPENDENT_LIBS ${CMAKE_THREAD_LIBS_INIT}) | ||||
| list(APPEND Z3_DEPENDENT_LIBS Threads::Threads) | ||||
| 
 | ||||
| ################################################################################ | ||||
| # Compiler warnings | ||||
|  | @ -411,7 +401,7 @@ if (Z3_ENABLE_CFI) | |||
|   if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") | ||||
|     z3_add_cxx_flag("-fsanitize=cfi" REQUIRED) | ||||
|     z3_add_cxx_flag("-fsanitize-cfi-cross-dso" REQUIRED) | ||||
|   elseif ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") | ||||
|   elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | ||||
|     z3_add_cxx_flag("/guard:cf" REQUIRED) | ||||
|     message(STATUS "Enabling CFI for MSVC") | ||||
|     foreach (_build_type ${build_types_with_cfi}) | ||||
|  | @ -428,14 +418,14 @@ endif() | |||
| ################################################################################ | ||||
| # MSVC specific flags inherited from old build system | ||||
| ################################################################################ | ||||
| if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") | ||||
| if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | ||||
|   include(${PROJECT_SOURCE_DIR}/cmake/msvc_legacy_quirks.cmake) | ||||
| endif() | ||||
| 
 | ||||
| ################################################################################ | ||||
| # Pass /RELEASE to the linker so that checksums in PE files are calculated. | ||||
| ################################################################################ | ||||
| if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") | ||||
| if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | ||||
|   string(APPEND CMAKE_EXE_LINKER_FLAGS " /RELEASE") | ||||
|   string(APPEND CMAKE_SHARED_LINKER_FLAGS " /RELEASE") | ||||
| endif() | ||||
|  |  | |||
|  | @ -18,11 +18,11 @@ if (Z3_LINK_TIME_OPTIMIZATION) | |||
| 
 | ||||
|   set(_lto_compiler_flag "") | ||||
|   set(_lto_linker_flag "") | ||||
|   if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR | ||||
|       ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")) | ||||
|   if ((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR | ||||
|       (CMAKE_CXX_COMPILER_ID MATCHES "GNU")) | ||||
|       set(_lto_compiler_flag "-flto") | ||||
|       set(_lto_linker_flag "-flto") | ||||
|   elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") | ||||
|   elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | ||||
|     set(_lto_compiler_flag "/GL") | ||||
|     set(_lto_linker_flag "/LTCG") | ||||
|   else() | ||||
|  |  | |||
|  | @ -46,22 +46,22 @@ set(CLANG_WARNINGS_AS_ERRORS | |||
| ################################################################################ | ||||
| set(WARNING_FLAGS_TO_CHECK "") | ||||
| set(WARNING_AS_ERROR_FLAGS_TO_CHECK "") | ||||
| if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") | ||||
| 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") | ||||
| 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}) | ||||
| elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") | ||||
| elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | ||||
|   list(APPEND WARNING_FLAGS_TO_CHECK ${MSVC_WARNINGS}) | ||||
| 
 | ||||
|   # CMake's default flags include /W3 already so remove them if | ||||
|   # they already exist. | ||||
|   if ("${CMAKE_CXX_FLAGS}" MATCHES "/W3") | ||||
|   if (CMAKE_CXX_FLAGS MATCHES "/W3") | ||||
|     string(REPLACE "/W3" "" _cmake_cxx_flags_remove_w3 "${CMAKE_CXX_FLAGS}") | ||||
|     set(CMAKE_CXX_FLAGS "${_cmake_cxx_flags_remove_w3}" CACHE STRING "" FORCE) | ||||
|   endif() | ||||
|  | @ -84,7 +84,7 @@ get_property( | |||
|   PROPERTY | ||||
|   TYPE | ||||
| ) | ||||
| if ("${WARNINGS_AS_ERRORS_CACHE_VAR_TYPE}" STREQUAL "BOOL") | ||||
| 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 | ||||
|  | @ -106,25 +106,25 @@ set_property( | |||
|   "ON;OFF;SERIOUS_ONLY" | ||||
| ) | ||||
| 
 | ||||
| if ("${WARNINGS_AS_ERRORS}" STREQUAL "ON") | ||||
| 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")) | ||||
|   if ((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "GNU")) | ||||
|     list(APPEND Z3_COMPONENT_CXX_FLAGS "-Werror") | ||||
|   elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") | ||||
|   elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | ||||
|     list(APPEND Z3_COMPONENT_CXX_FLAGS "/WX") | ||||
|   else() | ||||
|     message(AUTHOR_WARNING "Unknown compiler") | ||||
|   endif() | ||||
| elseif ("${WARNINGS_AS_ERRORS}" STREQUAL "SERIOUS_ONLY") | ||||
| 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") | ||||
| elseif (WARNINGS_AS_ERRORS STREQUAL "OFF") | ||||
|   message(STATUS "Not treating compiler warnings as errors") | ||||
|   if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") | ||||
|   if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | ||||
|     # Warnings as errors is off by default for MSVC so setting this | ||||
|     # is not necessary but this duplicates the behaviour of the old | ||||
|     # build system. | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ function(add_git_dir_dependency GIT_DOT_FILE SUCCESS_VAR) | |||
|     # git directory | ||||
|     file(READ "${GIT_DOT_FILE}" GIT_DOT_FILE_DATA LIMIT 512) | ||||
|     string(STRIP "${GIT_DOT_FILE_DATA}" GIT_DOT_FILE_DATA_STRIPPED) | ||||
|     if ("${GIT_DOT_FILE_DATA_STRIPPED}" MATCHES "^gitdir:[ ]*(.+)$") | ||||
|     if (GIT_DOT_FILE_DATA_STRIPPED MATCHES "^gitdir:[ ]*(.+)$") | ||||
|       # Git worktree | ||||
|       message(STATUS "Found git worktree") | ||||
|       set(GIT_WORKTREE_DIR "${CMAKE_MATCH_1}") | ||||
|  | @ -75,7 +75,7 @@ function(add_git_dir_dependency GIT_DOT_FILE SUCCESS_VAR) | |||
|   file(READ "${GIT_HEAD_FILE}" GIT_HEAD_DATA LIMIT 128) | ||||
|   string(STRIP "${GIT_HEAD_DATA}" GIT_HEAD_DATA_STRIPPED) | ||||
| 
 | ||||
|   if ("${GIT_HEAD_DATA_STRIPPED}" MATCHES "^ref:[ ]*(.+)$") | ||||
|   if (GIT_HEAD_DATA_STRIPPED MATCHES "^ref:[ ]*(.+)$") | ||||
|     # HEAD points at a reference. | ||||
|     set(GIT_REF "${CMAKE_MATCH_1}") | ||||
|     if (EXISTS "${GIT_DIR}/${GIT_REF}") | ||||
|  |  | |||
|  | @ -13,52 +13,37 @@ find_library(GMP_C_LIBRARIES | |||
|   NAMES gmp | ||||
|   DOC "GMP C libraries" | ||||
| ) | ||||
| if (GMP_C_LIBRARIES) | ||||
|   message(STATUS "Found GMP C library: \"${GMP_C_LIBRARIES}\"") | ||||
| else() | ||||
|   message(STATUS "Could not find GMP C library") | ||||
| endif() | ||||
| find_library(GMP_CXX_LIBRARIES | ||||
|   NAMES gmpxx | ||||
|   DOC "GMP C++ libraries" | ||||
| ) | ||||
| if (GMP_CXX_LIBRARIES) | ||||
|   message(STATUS "Found GMP C++ library: \"${GMP_CXX_LIBRARIES}\"") | ||||
| else() | ||||
|   message(STATUS "Could not find GMP C++ library") | ||||
| endif() | ||||
| 
 | ||||
| # Try to find headers | ||||
| find_path(GMP_C_INCLUDES | ||||
|   NAMES gmp.h | ||||
|   DOC "GMP C header" | ||||
| ) | ||||
| if (GMP_C_INCLUDES) | ||||
|   message(STATUS "Found GMP C include path: \"${GMP_C_INCLUDES}\"") | ||||
| else() | ||||
|   message(STATUS "Could not find GMP C include path") | ||||
| endif() | ||||
| 
 | ||||
| find_path(GMP_CXX_INCLUDES | ||||
|   NAMES gmpxx.h | ||||
|   DOC "GMP C++ header" | ||||
| ) | ||||
| if (GMP_CXX_INCLUDES) | ||||
|   message(STATUS "Found GMP C++ include path: \"${GMP_CXX_INCLUDES}\"") | ||||
| else() | ||||
|   message(STATUS "Could not find GMP C++ include path") | ||||
| endif() | ||||
| 
 | ||||
| if (GMP_C_LIBRARIES AND GMP_CXX_LIBRARIES AND GMP_C_INCLUDES AND GMP_CXX_INCLUDES) | ||||
|   set(GMP_INCLUDE_DIRS "${GMP_C_INCLUDES}" "${GMP_CXX_INCLUDES}") | ||||
|   list(REMOVE_DUPLICATES GMP_INCLUDE_DIRS) | ||||
|   message(STATUS "Found GMP") | ||||
| else() | ||||
|   message(STATUS "Could not find GMP") | ||||
| endif() | ||||
| 
 | ||||
| # TODO: We should check we can link some simple code against libgmp and libgmpxx | ||||
| 
 | ||||
| # Handle QUIET and REQUIRED and check the necessary variables were set and if so | ||||
| # set ``GMP_FOUND`` | ||||
| find_package_handle_standard_args(GMP DEFAULT_MSG GMP_INCLUDE_DIRS GMP_C_LIBRARIES GMP_CXX_LIBRARIES) | ||||
| find_package_handle_standard_args(GMP | ||||
| 	REQUIRED_VARS GMP_C_LIBRARIES GMP_C_INCLUDES GMP_CXX_LIBRARIES GMP_CXX_INCLUDES) | ||||
| 
 | ||||
| if (GMP_FOUND) | ||||
|   set(GMP_INCLUDE_DIRS "${GMP_C_INCLUDES}" "${GMP_CXX_INCLUDES}") | ||||
|   list(REMOVE_DUPLICATES GMP_INCLUDE_DIRS) | ||||
| 
 | ||||
|   if (NOT TARGET GMP::GMP) | ||||
|     add_library(GMP::GMP UNKNOWN IMPORTED) | ||||
|     set_target_properties(GMP::GMP PROPERTIES | ||||
|       INTERFACE_INCLUDE_DIRECTORIES "${GMP_C_INCLUDES}" | ||||
|       IMPORTED_LOCATION "${GMP_C_LIBRARIES}") | ||||
|   endif() | ||||
| endif() | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ set(Z3_MSVC_LEGACY_DEFINES | |||
|   _UNICODE | ||||
| ) | ||||
| 
 | ||||
| if ("${TARGET_ARCHITECTURE}" STREQUAL "x86_64") | ||||
| if (TARGET_ARCHITECTURE STREQUAL "x86_64") | ||||
|   list(APPEND Z3_MSVC_LEGACY_DEFINES "" | ||||
|     # Don't set `_LIB`. The old build system sets this for x86_64 release | ||||
|     # build. This flag doesn't seem to be documented but a stackoverflow | ||||
|  | @ -57,10 +57,10 @@ endif() | |||
| # Note we don't set WIN32 or _WINDOWS because | ||||
| # CMake provides that for us. As a sanity check make sure the option | ||||
| # is present. | ||||
| if (NOT "${CMAKE_CXX_FLAGS}" MATCHES "[-/]D[ ]*WIN32") | ||||
| if (NOT CMAKE_CXX_FLAGS MATCHES "[-/]D[ ]*WIN32") | ||||
|   message(FATAL_ERROR "\"/D WIN32\" is missing") | ||||
| endif() | ||||
| if (NOT "${CMAKE_CXX_FLAGS}" MATCHES "[-/]D[ ]*_WINDOWS") | ||||
| if (NOT CMAKE_CXX_FLAGS MATCHES "[-/]D[ ]*_WINDOWS") | ||||
|   message(FATAL_ERROR "\"/D _WINDOWS\" is missing") | ||||
| endif() | ||||
| 
 | ||||
|  | @ -82,7 +82,7 @@ endif() | |||
| # build system kept the frame pointer for all configurations | ||||
| # except x86_64 release (I don't know why the frame pointer | ||||
| # is kept for i686 release). | ||||
| if ("${TARGET_ARCHITECTURE}" STREQUAL "x86_64") | ||||
| if (TARGET_ARCHITECTURE STREQUAL "x86_64") | ||||
|   list(APPEND Z3_COMPONENT_CXX_FLAGS | ||||
|     $<$<CONFIG:Debug>:${NO_OMIT_FRAME_POINTER_MSVC_FLAG}> | ||||
|     $<$<CONFIG:MinSizeRel>:${NO_OMIT_FRAME_POINTER_MSVC_FLAG}> | ||||
|  | @ -91,7 +91,7 @@ else() | |||
|   list(APPEND Z3_COMPONENT_CXX_FLAGS ${NO_OMIT_FRAME_POINTER_MSVC_FLAG}) | ||||
| endif() | ||||
| 
 | ||||
| if (("${TARGET_ARCHITECTURE}" STREQUAL "x86_64") OR ("${TARGET_ARCHITECTURE}" STREQUAL "i686")) | ||||
| if ((TARGET_ARCHITECTURE STREQUAL "x86_64") OR (TARGET_ARCHITECTURE STREQUAL "i686")) | ||||
|   # Use __cdecl calling convention. Apparently this is MSVC's default | ||||
|   # but the old build system set it so for completeness set it too. | ||||
|   # See https://msdn.microsoft.com/en-us/library/46t77ak2.aspx | ||||
|  | @ -153,9 +153,9 @@ string(APPEND CMAKE_SHARED_LINKER_FLAGS " /SUBSYSTEM:WINDOWS") | |||
| # in the old build system except release x86_64. We try to emulate this here but | ||||
| # this is likely the wrong thing to do. | ||||
| foreach (_build_type ${_build_types_as_upper}) | ||||
|   if ("${TARGET_ARCHITECTURE}" STREQUAL "x86_64" AND | ||||
|       ("${_build_type}" STREQUAL "RELEASE" OR | ||||
|       "${_build_type}"  STREQUAL "RELWITHDEBINFO") | ||||
|   if (TARGET_ARCHITECTURE STREQUAL "x86_64" AND | ||||
|       (_build_type STREQUAL "RELEASE" OR | ||||
|       _build_type  STREQUAL "RELWITHDEBINFO") | ||||
|       ) | ||||
|     message(AUTHOR_WARNING "Skipping legacy linker MSVC options for x86_64 ${_build_type}") | ||||
|   else() | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ add_executable(cpp_example example.cpp) | |||
| target_include_directories(cpp_example PRIVATE ${Z3_CXX_INCLUDE_DIRS}) | ||||
| target_link_libraries(cpp_example PRIVATE ${Z3_LIBRARIES}) | ||||
| 
 | ||||
| if ("${CMAKE_SYSTEM_NAME}" MATCHES "[Ww]indows") | ||||
| if (CMAKE_SYSTEM_NAME MATCHES "[Ww]indows") | ||||
|   # On Windows we need to copy the Z3 libraries | ||||
|   # into the same directory as the executable | ||||
|   # so that they can be found. | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ endif() | |||
| target_include_directories(c_example PRIVATE ${Z3_C_INCLUDE_DIRS}) | ||||
| target_link_libraries(c_example PRIVATE ${Z3_LIBRARIES}) | ||||
| 
 | ||||
| if ("${CMAKE_SYSTEM_NAME}" MATCHES "[Ww]indows") | ||||
| if (CMAKE_SYSTEM_NAME MATCHES "[Ww]indows") | ||||
|   # On Windows we need to copy the Z3 libraries | ||||
|   # into the same directory as the executable | ||||
|   # so that they can be found. | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| find_package(Dotnet REQUIRED) | ||||
| 
 | ||||
| if("${TARGET_ARCHITECTURE}" STREQUAL "i686") | ||||
| if(TARGET_ARCHITECTURE STREQUAL "i686") | ||||
|     set(Z3_DOTNET_PLATFORM "x86") | ||||
| else() | ||||
|     set(Z3_DOTNET_PLATFORM "AnyCPU") | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ if (FORCE_CXX_LINKER) | |||
|   ) | ||||
| endif() | ||||
| 
 | ||||
| if ("${CMAKE_SYSTEM_NAME}" MATCHES "[Ww]indows") | ||||
| if (CMAKE_SYSTEM_NAME MATCHES "[Ww]indows") | ||||
|   # On Windows we need to copy the Z3 libraries | ||||
|   # into the same directory as the executable | ||||
|   # so that they can be found. | ||||
|  |  | |||
|  | @ -177,6 +177,7 @@ def enumerate_sets(csolver, map): | |||
|            yield ("MSS", csolver.to_c_lits(MSS)) | ||||
|            map.block_down(MSS) | ||||
|         else: | ||||
|            seed = csolver.seed_from_core() | ||||
|            MUS = csolver.shrink(seed) | ||||
|            yield ("MUS", csolver.to_c_lits(MUS)) | ||||
|            map.block_up(MUS) | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| # Jupyter version of the Z3 Python Tutorial. | ||||
| 
 | ||||
| Thanks to Peter Gragert, the Z3 tutorial guide is now available in the Jupyter notebook format. You can try it directly online from: | ||||
| Thanks to Peter Gragert, the Z3 tutorial guide is now available in the Jupyter notebook format.  | ||||
| 
 | ||||
| https://z3examples-nbjorner.notebooks.azure.com/j/notebooks/guide.ipynb | ||||
| An online tutorial is available from https://github.com/philzook58/z3_tutorial | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ add_executable(z3_tptp5 tptp5.cpp tptp5.lex.cpp) | |||
| target_include_directories(z3_tptp5 PRIVATE ${Z3_CXX_INCLUDE_DIRS}) | ||||
| target_link_libraries(z3_tptp5 PRIVATE ${Z3_LIBRARIES}) | ||||
| 
 | ||||
| if ("${CMAKE_SYSTEM_NAME}" MATCHES "[Ww]indows") | ||||
| if (CMAKE_SYSTEM_NAME MATCHES "[Ww]indows") | ||||
|   # On Windows we need to copy the Z3 libraries | ||||
|   # into the same directory as the executable | ||||
|   # so that they can be found. | ||||
|  |  | |||
|  | @ -335,6 +335,7 @@ namespace z3 { | |||
|         expr bool_const(char const * name); | ||||
|         expr int_const(char const * name); | ||||
|         expr real_const(char const * name); | ||||
|         expr string_const(char const * name); | ||||
|         expr bv_const(char const * name, unsigned sz); | ||||
|         expr fpa_const(char const * name, unsigned ebits, unsigned sbits); | ||||
| 
 | ||||
|  | @ -497,6 +498,7 @@ namespace z3 { | |||
|         ast(context & c):object(c), m_ast(0) {} | ||||
|         ast(context & c, Z3_ast n):object(c), m_ast(n) { Z3_inc_ref(ctx(), m_ast); } | ||||
|         ast(ast const & s):object(s), m_ast(s.m_ast) { Z3_inc_ref(ctx(), m_ast); } | ||||
|         ast(ast && s) noexcept : object(std::forward<object>(s)), m_ast(s.m_ast) { s.m_ast = nullptr; } | ||||
|         ~ast() { if (m_ast) Z3_dec_ref(*m_ctx, m_ast); } | ||||
|         operator Z3_ast() const { return m_ast; } | ||||
|         operator bool() const { return m_ast != 0; } | ||||
|  | @ -508,6 +510,12 @@ namespace z3 { | |||
|             m_ast = s.m_ast; | ||||
|             return *this; | ||||
|         } | ||||
|         ast & operator=(ast && s) noexcept { | ||||
|             object::operator=(std::forward<object>(s)); | ||||
|             m_ast = s.m_ast; | ||||
|             s.m_ast = nullptr; | ||||
|             return *this; | ||||
|         } | ||||
|         Z3_ast_kind kind() const { Z3_ast_kind r = Z3_get_ast_kind(ctx(), m_ast); check_error(); return r; } | ||||
|         unsigned hash() const { unsigned r = Z3_get_ast_hash(ctx(), m_ast); check_error(); return r; } | ||||
|         friend std::ostream & operator<<(std::ostream & out, ast const & n); | ||||
|  | @ -568,7 +576,6 @@ namespace z3 { | |||
|             unsigned m_index; | ||||
|         public: | ||||
|             iterator(ast_vector_tpl const* v, unsigned i): m_vector(v), m_index(i) {} | ||||
|             iterator(iterator const& other): m_vector(other.m_vector), m_index(other.m_index) {} | ||||
| 
 | ||||
|             bool operator==(iterator const& other) const noexcept { | ||||
|                 return other.m_index == m_index; | ||||
|  | @ -864,6 +871,36 @@ namespace z3 { | |||
|         */ | ||||
|         bool is_well_sorted() const { bool r = Z3_is_well_sorted(ctx(), m_ast); check_error(); return r; } | ||||
| 
 | ||||
|         /**
 | ||||
|            \brief Return Boolean expression to test whether expression is inf | ||||
|         */ | ||||
|         expr mk_is_inf() const { | ||||
|             assert(is_fpa()); | ||||
|             Z3_ast r = Z3_mk_fpa_is_infinite(ctx(), m_ast); | ||||
|             check_error(); | ||||
|             return expr(ctx(), r); | ||||
|         } | ||||
| 
 | ||||
|         /**
 | ||||
|            \brief Return Boolean expression to test for whether expression is a NaN | ||||
|         */ | ||||
|         expr mk_is_nan() const { | ||||
|             assert(is_fpa()); | ||||
|             Z3_ast r = Z3_mk_fpa_is_nan(ctx(), m_ast); | ||||
|             check_error(); | ||||
|             return expr(ctx(), r); | ||||
|         } | ||||
| 
 | ||||
|         /**
 | ||||
|            \brief Convert this fpa into an IEEE BV | ||||
|         */ | ||||
|         expr mk_to_ieee_bv() const { | ||||
|             assert(is_fpa()); | ||||
|             Z3_ast r = Z3_mk_fpa_to_ieee_bv(ctx(), m_ast); | ||||
|             check_error(); | ||||
|             return expr(ctx(), r); | ||||
|         } | ||||
| 
 | ||||
|         /**
 | ||||
|            \brief Return string representation of numeral or algebraic number | ||||
|            This method assumes the expression is numeral or algebraic | ||||
|  | @ -1271,6 +1308,21 @@ namespace z3 { | |||
|           */ | ||||
|         friend expr fma(expr const& a, expr const& b, expr const& c, expr const& rm); | ||||
| 
 | ||||
|         /**
 | ||||
|            \brief Create an expression of FloatingPoint sort from three bit-vector expressions | ||||
|         */ | ||||
|         friend expr fpa_fp(expr const& sgn, expr const& exp, expr const& sig); | ||||
| 
 | ||||
|         /**
 | ||||
|            \brief Conversion of a floating-point term into a signed bit-vector. | ||||
|         */ | ||||
|         friend expr fpa_to_sbv(expr const& t, unsigned sz); | ||||
| 
 | ||||
|         /**
 | ||||
|            \brief Conversion of a floating-point term into an unsigned bit-vector. | ||||
|         */ | ||||
|         friend expr fpa_to_ubv(expr const& t, unsigned sz); | ||||
| 
 | ||||
|         /**
 | ||||
|            \brief sequence and regular expression operations. | ||||
|            + is overloaded as sequence concatenation and regular expression union. | ||||
|  | @ -1291,7 +1343,7 @@ namespace z3 { | |||
|             check_error(); | ||||
|             return expr(ctx(), r); | ||||
|         } | ||||
|         expr contains(expr const& s) { | ||||
|         expr contains(expr const& s) const { | ||||
|             check_context(*this, s); | ||||
|             Z3_ast r = Z3_mk_seq_contains(ctx(), *this, s); | ||||
|             check_error(); | ||||
|  | @ -1768,6 +1820,27 @@ namespace z3 { | |||
|         return expr(a.ctx(), r); | ||||
|     } | ||||
| 
 | ||||
|     inline expr fpa_fp(expr const& sgn, expr const& exp, expr const& sig) { | ||||
|         check_context(sgn, exp); check_context(exp, sig); | ||||
|         assert(sgn.is_bv() && exp.is_bv() && sig.is_bv()); | ||||
|         Z3_ast r = Z3_mk_fpa_fp(sgn.ctx(), sgn, exp, sig); | ||||
|         sgn.check_error(); | ||||
|         return expr(sgn.ctx(), r); | ||||
|     } | ||||
| 
 | ||||
|     inline expr fpa_to_sbv(expr const& t, unsigned sz) { | ||||
|         assert(t.is_fpa()); | ||||
|         Z3_ast r = Z3_mk_fpa_to_sbv(t.ctx(), t.ctx().fpa_rounding_mode(), t, sz); | ||||
|         t.check_error(); | ||||
|         return expr(t.ctx(), r); | ||||
|     } | ||||
| 
 | ||||
|     inline expr fpa_to_ubv(expr const& t, unsigned sz) { | ||||
|         assert(t.is_fpa()); | ||||
|         Z3_ast r = Z3_mk_fpa_to_ubv(t.ctx(), t.ctx().fpa_rounding_mode(), t, sz); | ||||
|         t.check_error(); | ||||
|         return expr(t.ctx(), r); | ||||
|     } | ||||
| 
 | ||||
|     /**
 | ||||
|        \brief Create the if-then-else expression <tt>ite(c, t, e)</tt> | ||||
|  | @ -1818,6 +1891,18 @@ namespace z3 { | |||
|     inline expr slt(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvslt(a.ctx(), a, b)); } | ||||
|     inline expr slt(expr const & a, int b) { return slt(a, a.ctx().num_val(b, a.get_sort())); } | ||||
|     inline expr slt(int a, expr const & b) { return slt(b.ctx().num_val(a, b.get_sort()), b); } | ||||
|     /**
 | ||||
|        \brief signed greater than or equal to operator for bitvectors. | ||||
|     */ | ||||
|     inline expr sge(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvsge(a.ctx(), a, b)); } | ||||
|     inline expr sge(expr const & a, int b) { return sge(a, a.ctx().num_val(b, a.get_sort())); } | ||||
|     inline expr sge(int a, expr const & b) { return sge(b.ctx().num_val(a, b.get_sort()), b); } | ||||
|     /**
 | ||||
|        \brief signed greater than operator for bitvectors. | ||||
|     */ | ||||
|     inline expr sgt(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvsgt(a.ctx(), a, b)); } | ||||
|     inline expr sgt(expr const & a, int b) { return sgt(a, a.ctx().num_val(b, a.get_sort())); } | ||||
|     inline expr sgt(int a, expr const & b) { return sgt(b.ctx().num_val(a, b.get_sort()), b); } | ||||
| 
 | ||||
| 
 | ||||
|     /**
 | ||||
|  | @ -1985,8 +2070,7 @@ namespace z3 { | |||
| 
 | ||||
|     template<typename T> | ||||
|     template<typename T2> | ||||
|     array<T>::array(ast_vector_tpl<T2> const & v):m_array(new T[v.size()]) { | ||||
|         m_size  = v.size(); | ||||
|     array<T>::array(ast_vector_tpl<T2> const & v):m_array(new T[v.size()]), m_size(v.size()) { | ||||
|         for (unsigned i = 0; i < m_size; i++) { | ||||
|             m_array[i] = v[i]; | ||||
|         } | ||||
|  | @ -2937,8 +3021,16 @@ namespace z3 { | |||
|             return *this; | ||||
|         } | ||||
|         operator Z3_fixedpoint() const { return m_fp; } | ||||
|         void from_string(char const* s) { Z3_fixedpoint_from_string(ctx(), m_fp, s); check_error(); } | ||||
|         void from_file(char const* s) { Z3_fixedpoint_from_file(ctx(), m_fp, s); check_error(); } | ||||
|         expr_vector from_string(char const* s) {  | ||||
|             Z3_ast_vector r = Z3_fixedpoint_from_string(ctx(), m_fp, s);  | ||||
|             check_error();  | ||||
|             return expr_vector(ctx(), r); | ||||
|         } | ||||
|         expr_vector from_file(char const* s) {  | ||||
|             Z3_ast_vector r = Z3_fixedpoint_from_file(ctx(), m_fp, s);  | ||||
|             check_error();  | ||||
|             return expr_vector(ctx(), r); | ||||
|         } | ||||
|         void add_rule(expr& rule, symbol const& name) { Z3_fixedpoint_add_rule(ctx(), m_fp, rule, name); check_error(); } | ||||
|         void add_fact(func_decl& f, unsigned * args) { Z3_fixedpoint_add_fact(ctx(), m_fp, f, f.arity(), args); check_error(); } | ||||
|         check_result query(expr& q) { Z3_lbool r = Z3_fixedpoint_query(ctx(), m_fp, q); check_error(); return to_check_result(r); } | ||||
|  | @ -3176,6 +3268,7 @@ namespace z3 { | |||
|     inline expr context::bool_const(char const * name) { return constant(name, bool_sort()); } | ||||
|     inline expr context::int_const(char const * name) { return constant(name, int_sort()); } | ||||
|     inline expr context::real_const(char const * name) { return constant(name, real_sort()); } | ||||
|     inline expr context::string_const(char const * name) { return constant(name, string_sort()); } | ||||
|     inline expr context::bv_const(char const * name, unsigned sz) { return constant(name, bv_sort(sz)); } | ||||
|     inline expr context::fpa_const(char const * name, unsigned ebits, unsigned sbits) { return constant(name, fpa_sort(ebits, sbits)); } | ||||
| 
 | ||||
|  |  | |||
|  | @ -140,7 +140,7 @@ endforeach() | |||
| # Note, nuget package file names do not have the ${VER_REV} part. | ||||
| 
 | ||||
| set(Z3_DOTNET_NUPKG_VERSION "${VER_MAJOR}.${VER_MINOR}.${VER_BUILD}") | ||||
| if("${TARGET_ARCHITECTURE}" STREQUAL "i686") | ||||
| if(TARGET_ARCHITECTURE STREQUAL "i686") | ||||
|     set(Z3_DOTNET_PLATFORM "x86") | ||||
| else() | ||||
|     set(Z3_DOTNET_PLATFORM "AnyCPU") | ||||
|  |  | |||
|  | @ -83,6 +83,9 @@ ${Z3_DOTNET_COMPILE_ITEMS} | |||
|     <Content Include="${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libz3.so" Condition="Exists('${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libz3.so')"> | ||||
|       <PackagePath>runtimes\linux-x64\native</PackagePath> | ||||
|     </Content> | ||||
|     <Content Include="${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libz3.dylib" Condition="Exists('${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libz3.dylib')"> | ||||
|       <PackagePath>runtimes\macos\native</PackagePath> | ||||
|     </Content> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|   <!-- Native binaries for x86; currently only Windows is supported. --> | ||||
|  |  | |||
|  | @ -898,7 +898,8 @@ bool arith_util::is_extended_numeral(expr* term, rational& r) const { | |||
|             continue; | ||||
|         } | ||||
|         if (is_mul(term)) { | ||||
|             rational r(mul), n(0); | ||||
|             r = mul; | ||||
|             rational n(0); | ||||
|             for (expr* arg : *to_app(term)) { | ||||
|                 if (!is_extended_numeral(arg, n)) | ||||
|                     return false; | ||||
|  | @ -907,7 +908,8 @@ bool arith_util::is_extended_numeral(expr* term, rational& r) const { | |||
|             return true; | ||||
|         } | ||||
|         if (is_add(term)) { | ||||
|             rational r(0), n(0); | ||||
|             rational n(0); | ||||
|             r = 0; | ||||
|             for (expr* arg : *to_app(term)) { | ||||
|                 if (!is_extended_numeral(arg, n)) | ||||
|                     return false; | ||||
|  | @ -921,8 +923,7 @@ bool arith_util::is_extended_numeral(expr* term, rational& r) const { | |||
|         if (is_sub(term, t1, t2) &&  | ||||
|             is_extended_numeral(t1, k1) && | ||||
|             is_extended_numeral(t2, k2)) { | ||||
|             r = k1 - k2; | ||||
|             r *= mul; | ||||
|             r = (k1 - k2) * mul; | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
|  |  | |||
|  | @ -718,7 +718,7 @@ void bv_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol const | |||
|     op_names.push_back(builtin_name("rotate_right",OP_ROTATE_RIGHT)); | ||||
|     op_names.push_back(builtin_name("bit2bool", OP_BIT2BOOL)); | ||||
| 
 | ||||
|     if (logic == symbol::null || logic == symbol("ALL") || logic == "QF_FD") { | ||||
|     if (logic == symbol::null || logic == symbol("ALL") || logic == "QF_FD" || logic == "HORN") { | ||||
|         op_names.push_back(builtin_name("bvumul_noovfl",OP_BUMUL_NO_OVFL)); | ||||
|         op_names.push_back(builtin_name("bvsmul_noovfl",OP_BSMUL_NO_OVFL)); | ||||
|         op_names.push_back(builtin_name("bvsmul_noudfl",OP_BSMUL_NO_UDFL)); | ||||
|  | @ -827,6 +827,15 @@ bool bv_recognizers::is_extract(expr const* e, unsigned& low, unsigned& high, ex | |||
|     return true; | ||||
| } | ||||
| 
 | ||||
| bool bv_recognizers::is_repeat(expr const * e, expr*& arg, unsigned& n) const { | ||||
|     if (!is_app_of(e, get_fid(), OP_REPEAT)) | ||||
|         return false; | ||||
|     arg = to_app(e)->get_arg(0); | ||||
|     n = to_app(e)->get_parameter(0).get_int(); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| bool bv_recognizers::is_bv2int(expr const* e, expr*& r) const { | ||||
|     if (!is_bv2int(e)) return false; | ||||
|     r = to_app(e)->get_arg(0); | ||||
|  |  | |||
|  | @ -310,6 +310,7 @@ public: | |||
|     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); } | ||||
|  |  | |||
|  | @ -281,21 +281,36 @@ namespace euf { | |||
|        VERIFY(n->num_args() == 0 || !n->merge_enabled() || m_table.contains(n)); | ||||
|     } | ||||
| 
 | ||||
|     void egraph::set_value(enode* n, lbool value) {         | ||||
|         force_push(); | ||||
|         TRACE("euf", tout << bpp(n) << "\n";); | ||||
|         SASSERT(n->value() == l_undef); | ||||
|         n->set_value(value); | ||||
|         m_updates.push_back(update_record(n, update_record::value_assignment())); | ||||
|     void egraph::set_value(enode* n, lbool value) {   | ||||
|         if (n->value() == l_undef) { | ||||
|             force_push(); | ||||
|             TRACE("euf", tout << bpp(n) << " := " << value << "\n";); | ||||
|             n->set_value(value); | ||||
|             m_updates.push_back(update_record(n, update_record::value_assignment())); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void egraph::set_lbl_hash(enode* n) { | ||||
|         NOT_IMPLEMENTED_YET(); | ||||
|         SASSERT(n->m_lbl_hash == -1); | ||||
|         // m_lbl_hash should be different from -1, if and only if,
 | ||||
|         // there is a pattern that contains the enode. So,
 | ||||
|         // I use a trail to restore the value of m_lbl_hash to -1.
 | ||||
|         m_updates.push_back(update_record(n, update_record::lbl_hash())); | ||||
|         unsigned h = hash_u(n->get_expr_id()); | ||||
|         n->m_lbl_hash = h & (APPROX_SET_CAPACITY - 1); | ||||
|         // propagate modification to the root m_lbls set.
 | ||||
|         enode* r = n->get_root(); | ||||
|         approx_set & r_lbls = r->m_lbls; | ||||
|         if (!r_lbls.may_contain(n->m_lbl_hash)) { | ||||
|             m_updates.push_back(update_record(r, update_record::lbl_set())); | ||||
|             r_lbls.insert(n->m_lbl_hash); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void egraph::pop(unsigned num_scopes) { | ||||
|         if (num_scopes <= m_num_scopes) { | ||||
|             m_num_scopes -= num_scopes; | ||||
|             m_to_merge.reset(); | ||||
|             return; | ||||
|         } | ||||
|         num_scopes -= m_num_scopes; | ||||
|  | @ -355,6 +370,12 @@ namespace euf { | |||
|                 VERIFY(p.r1->value() != l_undef); | ||||
|                 p.r1->set_value(l_undef); | ||||
|                 break; | ||||
|             case update_record::tag_t::is_lbl_hash: | ||||
|                 p.r1->m_lbl_hash = p.m_lbl_hash; | ||||
|                 break; | ||||
|             case update_record::tag_t::is_lbl_set: | ||||
|                 p.r1->m_lbls.set(p.m_lbls); | ||||
|                 break; | ||||
|             default: | ||||
|                 UNREACHABLE(); | ||||
|                 break; | ||||
|  | @ -439,8 +460,8 @@ namespace euf { | |||
|                 auto rc = insert_table(p); | ||||
|                 enode* p_other = rc.first; | ||||
|                 SASSERT(m_table.contains_ptr(p) == (p_other == p)); | ||||
|                 if (p_other != p) | ||||
|                     m_to_merge.push_back(to_merge(p_other, p, rc.second)); | ||||
|                 if (p_other != p)  | ||||
|                     m_to_merge.push_back(to_merge(p_other, p, rc.second));                 | ||||
|                 else | ||||
|                     r2->m_parents.push_back(p); | ||||
|                 if (p->is_equality()) | ||||
|  | @ -704,8 +725,6 @@ namespace euf { | |||
|                 TRACE("euf", display(tout << bpp(n) << " is not closed under congruence\n");); | ||||
|                 UNREACHABLE(); | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     std::ostream& egraph::display(std::ostream& out, unsigned max_args, enode* n) const { | ||||
|  | @ -765,7 +784,6 @@ namespace euf { | |||
| 
 | ||||
|     void egraph::copy_from(egraph const& src, std::function<void*(void*)>& copy_justification) { | ||||
|         SASSERT(m_scopes.empty()); | ||||
|         SASSERT(src.m_scopes.empty()); | ||||
|         SASSERT(m_nodes.empty()); | ||||
|         ptr_vector<enode> old_expr2new_enode, args; | ||||
|         ast_translation tr(src.m, m); | ||||
|  | @ -793,6 +811,9 @@ namespace euf { | |||
|                 merge(n2, n2t, n1->m_justification.copy(copy_justification)); | ||||
|         } | ||||
|         propagate(); | ||||
|         for (unsigned i = 0; i < src.m_scopes.size(); ++i) | ||||
|             push(); | ||||
|         force_push(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -102,9 +102,12 @@ namespace euf { | |||
|             struct new_lits_qhead {}; | ||||
|             struct inconsistent {}; | ||||
|             struct value_assignment {}; | ||||
|             struct lbl_hash {}; | ||||
|             struct lbl_set {}; | ||||
|             enum class tag_t { is_set_parent, is_add_node, is_toggle_merge,  | ||||
|                          is_add_th_var, is_replace_th_var, is_new_lit, is_new_th_eq, | ||||
|                          is_new_th_eq_qhead, is_new_lits_qhead, is_inconsistent, is_value_assignment }; | ||||
|                     is_add_th_var, is_replace_th_var, is_new_lit, is_new_th_eq, | ||||
|                     is_lbl_hash, is_new_th_eq_qhead, is_new_lits_qhead,  | ||||
|                     is_inconsistent, is_value_assignment, is_lbl_set }; | ||||
|             tag_t  tag; | ||||
|             enode* r1; | ||||
|             enode* n1; | ||||
|  | @ -116,6 +119,8 @@ namespace euf { | |||
|                 }; | ||||
|                 unsigned qhead; | ||||
|                 bool     m_inconsistent; | ||||
|                 signed char m_lbl_hash; | ||||
|                 unsigned long long m_lbls; | ||||
|             }; | ||||
|             update_record(enode* r1, enode* n1, unsigned r2_num_parents) : | ||||
|                 tag(tag_t::is_set_parent), r1(r1), n1(n1), r2_num_parents(r2_num_parents) {} | ||||
|  | @ -139,6 +144,10 @@ namespace euf { | |||
|                 tag(tag_t::is_inconsistent), r1(nullptr), n1(nullptr), m_inconsistent(inc) {} | ||||
|             update_record(enode* n, value_assignment) : | ||||
|                 tag(tag_t::is_value_assignment), r1(n), n1(nullptr), qhead(0) {} | ||||
|             update_record(enode* n, lbl_hash): | ||||
|                 tag(tag_t::is_lbl_hash), r1(n), n1(nullptr), m_lbl_hash(n->m_lbl_hash) {} | ||||
|             update_record(enode* n, lbl_set): | ||||
|                 tag(tag_t::is_lbl_set), r1(n), n1(nullptr), m_lbls(n->m_lbls.get()) {}     | ||||
|         }; | ||||
|         ast_manager&           m; | ||||
|         svector<to_merge>      m_to_merge; | ||||
|  |  | |||
|  | @ -72,7 +72,7 @@ namespace euf { | |||
|     void * etable::mk_table_for(unsigned arity, func_decl * d) { | ||||
|         void * r; | ||||
|         SASSERT(d->get_arity() >= 1); | ||||
|         SASSERT(arity >= d->get_arity()); | ||||
|         SASSERT(arity >= d->get_arity() || d->is_associative()); | ||||
|         switch (arity) { | ||||
|         case 1: | ||||
|             r = TAG(void*, alloc(unary_table), UNARY); | ||||
|  |  | |||
|  | @ -336,8 +336,13 @@ br_status array_rewriter::mk_map_core(func_decl * f, unsigned num_args, expr * c | |||
|     //
 | ||||
|     quantifier* lam = nullptr; | ||||
|     for (unsigned i = 0; i < num_args; ++i) { | ||||
|         if (is_lambda(args[i])) { | ||||
|         if (is_lambda(args[i])) | ||||
|             lam = to_quantifier(args[i]); | ||||
|         else if (m_util.is_const(args[i])) | ||||
|             continue; | ||||
|         else { | ||||
|             lam = nullptr; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     if (lam) { | ||||
|  | @ -351,15 +356,6 @@ br_status array_rewriter::mk_map_core(func_decl * f, unsigned num_args, expr * c | |||
|                 lam = to_quantifier(a); | ||||
|                 args1.push_back(lam->get_expr()); | ||||
|             } | ||||
|             else { | ||||
|                 expr_ref_vector sel(m()); | ||||
|                 sel.push_back(a); | ||||
|                 unsigned n = lam->get_num_decls(); | ||||
|                 for (unsigned i = 0; i < n; ++i) { | ||||
|                     sel.push_back(m().mk_var(n - i - 1, lam->get_decl_sort(i))); | ||||
|                 } | ||||
|                 args1.push_back(m_util.mk_select(sel.size(), sel.data())); | ||||
|             } | ||||
|         } | ||||
|         result = m().mk_app(f, args1.size(), args1.data()); | ||||
|         result = m().update_quantifier(lam, result); | ||||
|  |  | |||
|  | @ -437,7 +437,7 @@ namespace seq { | |||
|         expr_ref t_eq_empty = mk_eq_empty(t); | ||||
| 
 | ||||
|         // |t| = 0 => |s| = 0 or indexof(t,s,offset) = -1
 | ||||
|         // ~contains(t,s) <=> indexof(t,s,offset) = -1
 | ||||
|         // ~contains(t,s) => indexof(t,s,offset) = -1
 | ||||
| 
 | ||||
|         add_clause(cnt,  i_eq_m1); | ||||
|         add_clause(~t_eq_empty, s_eq_empty, i_eq_m1); | ||||
|  | @ -489,7 +489,7 @@ namespace seq { | |||
|             // 0 <= offset & offset < len(t) => len(x) = offset
 | ||||
|             // 0 <= offset & offset < len(t) & indexof(y,s,0) = -1 => -1 = i
 | ||||
|             // 0 <= offset & offset < len(t) & indexof(y,s,0) >= 0 =>
 | ||||
|             //                  -1 = indexof(y,s,0) + offset = indexof(t, s, offset)
 | ||||
|             //                  indexof(y,s,0) + offset = indexof(t, s, offset)
 | ||||
| 
 | ||||
|             add_clause(~offset_ge_0, offset_ge_len, mk_seq_eq(t, mk_concat(x, y))); | ||||
|             add_clause(~offset_ge_0, offset_ge_len, mk_eq(mk_len(x), offset)); | ||||
|  |  | |||
|  | @ -1492,6 +1492,7 @@ seq_util::rex::info seq_util::rex::info::orelse(seq_util::rex::info const& i) co | |||
| seq_util::rex::info seq_util::rex::info::loop(unsigned lower, unsigned upper) const { | ||||
|     if (is_known()) { | ||||
|         unsigned m = min_length * lower; | ||||
|         // Code review: this is not a complete overflow check. 
 | ||||
|         if (m > 0 && (m < min_length || m < lower)) | ||||
|             m = UINT_MAX; | ||||
|         lbool loop_nullable = (nullable == l_true || lower == 0 ? l_true : nullable); | ||||
|  |  | |||
|  | @ -104,7 +104,7 @@ void static_features::reset() { | |||
|     m_num_aliens_per_family                .reset(); | ||||
|     m_num_theories                         = 0; | ||||
|     m_theories                             .reset(); | ||||
|     m_max_stack_depth                      = 500; | ||||
|     m_max_stack_depth                      = 100; | ||||
|     flush_cache(); | ||||
| } | ||||
| 
 | ||||
|  | @ -404,10 +404,11 @@ void static_features::process(expr * e, bool form_ctx, bool or_and_ctx, bool ite | |||
|         m_num_sharing++; | ||||
|         return; | ||||
|     }     | ||||
| 
 | ||||
|     if (stack_depth > m_max_stack_depth) { | ||||
|         for (expr* arg : subterms(expr_ref(e, m))) | ||||
|             if (get_depth(arg) <= 3 || is_quantifier(arg))  | ||||
|                 process(arg, form_ctx, or_and_ctx, ite_ctx, stack_depth-10); | ||||
|                 process(arg, form_ctx, or_and_ctx, ite_ctx, stack_depth - 10); | ||||
|         return; | ||||
|     } | ||||
|     mark(e); | ||||
|  |  | |||
|  | @ -877,10 +877,11 @@ void cmd_context::insert(symbol const & s, func_decl * f) { | |||
| } | ||||
| 
 | ||||
| void cmd_context::insert(symbol const & s, psort_decl * p) { | ||||
|     pm().inc_ref(p); | ||||
|     if (m_psort_decls.contains(s)) { | ||||
|         pm().dec_ref(p); | ||||
|         throw cmd_exception("sort already defined ", s); | ||||
|     } | ||||
|     pm().inc_ref(p); | ||||
|     m_psort_decls.insert(s, p); | ||||
|     if (!m_global_decls) { | ||||
|         m_psort_decls_stack.push_back(s); | ||||
|  | @ -1122,7 +1123,7 @@ bool cmd_context::try_mk_builtin_app(symbol const & s, unsigned num_args, expr * | |||
|         result = m().mk_app(fid, k, num_indices, indices, num_args, args, range); | ||||
|     } | ||||
|     CHECK_SORT(result.get()); | ||||
|     return true; | ||||
|     return nullptr != result.get(); | ||||
| } | ||||
| 
 | ||||
| bool cmd_context::try_mk_declared_app(symbol const & s, unsigned num_args, expr * const * args,  | ||||
|  |  | |||
|  | @ -1246,8 +1246,8 @@ namespace dd { | |||
|             } | ||||
|             else { | ||||
|                 set_mark(r); | ||||
|                 m_todo.pop_back(); | ||||
|                 m_todo.push_back(lo(r)).push_back(hi(r)); | ||||
|                 m_todo.push_back(lo(r)); | ||||
|                 m_todo.push_back(hi(r)); | ||||
|             } | ||||
|         } | ||||
|         return max_d; | ||||
|  |  | |||
|  | @ -89,7 +89,7 @@ class hilbert_basis { | |||
|     reslimit&          m_limit; | ||||
|     vector<num_vector> m_ineqs;      // set of asserted inequalities
 | ||||
|     bool_vector      m_iseq;       // inequalities that are equalities
 | ||||
|     num_vector         m_store;      // store of vectors
 | ||||
|     mutable num_vector         m_store;      // store of vectors
 | ||||
|     svector<offset_t>  m_basis;      // vector of current basis
 | ||||
|     svector<offset_t>  m_free_list;  // free list of unused storage
 | ||||
|     svector<offset_t>  m_active;     // active set
 | ||||
|  |  | |||
|  | @ -23,21 +23,30 @@ bool const_iterator_mon::get_factors(factor& k, factor& j, rational& sign) const | |||
|     std::sort(k_vars.begin(), k_vars.end()); | ||||
|     std::sort(j_vars.begin(), j_vars.end()); | ||||
| 
 | ||||
|     if (false && m_num_failures > 10) { | ||||
|         for (bool& m : m_mask) m = true; | ||||
|         m_mask[0] = false; | ||||
|         m_full_factorization_returned = true; | ||||
|         return false; | ||||
|     } | ||||
|     if (k_vars.size() == 1) { | ||||
|         k.set(k_vars[0], factor_type::VAR); | ||||
|     } else { | ||||
|         unsigned i; | ||||
|         if (!m_ff->find_canonical_monic_of_vars(k_vars, i)) { | ||||
|             ++m_num_failures; | ||||
|             return false; | ||||
|         } | ||||
|         k.set(i, factor_type::MON); | ||||
|     } | ||||
|     m_num_failures = 0; | ||||
| 
 | ||||
|     if (j_vars.size() == 1) { | ||||
|         j.set(j_vars[0], factor_type::VAR); | ||||
|     } else { | ||||
|         unsigned i; | ||||
|         if (!m_ff->find_canonical_monic_of_vars(j_vars, i)) { | ||||
|             ++m_num_failures; | ||||
|             return false; | ||||
|         } | ||||
|         j.set(i, factor_type::MON); | ||||
|  | @ -46,7 +55,7 @@ bool const_iterator_mon::get_factors(factor& k, factor& j, rational& sign) const | |||
| } | ||||
| 
 | ||||
| factorization const_iterator_mon::operator*() const { | ||||
|     if (m_full_factorization_returned == false)  { | ||||
|     if (!m_full_factorization_returned)  { | ||||
|         return create_full_factorization(m_ff->m_monic); | ||||
|     } | ||||
|     factor j, k; rational sign; | ||||
|  |  | |||
|  | @ -30,12 +30,12 @@ struct factorization_factory; | |||
| enum class factor_type { VAR, MON }; | ||||
| 
 | ||||
| class factor { | ||||
|     lpvar        m_var; | ||||
|     factor_type  m_type; | ||||
|     bool        m_sign; | ||||
|     lpvar        m_var{ UINT_MAX }; | ||||
|     factor_type  m_type{ factor_type::VAR }; | ||||
|     bool         m_sign{ false }; | ||||
| public: | ||||
|     factor(): factor(false) {} | ||||
|     factor(bool sign): m_var(UINT_MAX), m_type(factor_type::VAR), m_sign(sign) {} | ||||
|     factor(bool sign): m_sign(sign) {} | ||||
|     explicit factor(lpvar v, factor_type t) : m_var(v), m_type(t), m_sign(false) {} | ||||
|     unsigned var() const { return m_var; } | ||||
|     factor_type type() const { return m_type; } | ||||
|  | @ -77,9 +77,10 @@ public: | |||
| 
 | ||||
| struct const_iterator_mon { | ||||
|     // fields
 | ||||
|     bool_vector                  m_mask; | ||||
|     mutable bool_vector                    m_mask; | ||||
|     const factorization_factory *  m_ff; | ||||
|     bool                           m_full_factorization_returned; | ||||
|     mutable bool                           m_full_factorization_returned; | ||||
|     mutable unsigned               m_num_failures{ 0 }; | ||||
| 
 | ||||
|     // typedefs
 | ||||
|     typedef const_iterator_mon self_type; | ||||
|  |  | |||
|  | @ -61,7 +61,7 @@ namespace lp { | |||
|             return true; | ||||
|         const lar_term* t = lra.terms()[i]; | ||||
|         impq delta = get_cube_delta_for_term(*t); | ||||
|         TRACE("cube", lra.print_term_as_indices(*t, tout); tout << ", delta = " << delta;); | ||||
|         TRACE("cube", lra.print_term_as_indices(*t, tout); tout << ", delta = " << delta << "\n";); | ||||
|         if (is_zero(delta)) | ||||
|             return true; | ||||
|         return lra.tighten_term_bounds_by_delta(tv::term(i), delta); | ||||
|  |  | |||
|  | @ -2331,15 +2331,16 @@ namespace lp { | |||
|                 v = flv; | ||||
|             } | ||||
|             m_incorrect_columns.insert(j); | ||||
|             TRACE("cube", tout << "new val = " << v << "\n";); | ||||
|             TRACE("cube", tout << "new val = " << v << " column: " << j << "\n";); | ||||
|         } | ||||
|         if (m_incorrect_columns.size()) { | ||||
|         if (!m_incorrect_columns.empty()) { | ||||
|             fix_terms_with_rounded_columns(); | ||||
|             m_incorrect_columns.clear(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void lar_solver::fix_terms_with_rounded_columns() { | ||||
| 
 | ||||
|         for (unsigned i = 0; i < m_terms.size(); i++) { | ||||
|             if (!term_is_used_as_row(i)) | ||||
|                 continue; | ||||
|  | @ -2357,8 +2358,10 @@ namespace lp { | |||
|                 m_mpq_lar_core_solver.m_r_solver.update_x(j, v); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         SASSERT(ax_is_correct()); | ||||
|     } | ||||
| 
 | ||||
|     // return true if all y coords are zeroes
 | ||||
|     bool lar_solver::sum_first_coords(const lar_term& t, mpq& val) const { | ||||
|         val = zero_of_type<mpq>(); | ||||
|  |  | |||
|  | @ -66,7 +66,7 @@ namespace lp_api { | |||
|         lp::constraint_index get_constraint(bool b) const { return m_constraints[b]; } | ||||
| 
 | ||||
|         inf_rational get_value(bool is_true) const { | ||||
|             if (is_true)  | ||||
|             if (is_true != get_lit().sign())  | ||||
|                 return inf_rational(m_value);                         // v >= value or v <= value
 | ||||
|             if (m_is_int) { | ||||
|                 SASSERT(m_value.is_int()); | ||||
|  |  | |||
|  | @ -34,7 +34,7 @@ public: | |||
|      | ||||
|     void flush() { | ||||
|         SASSERT(b.size() == A.size()); | ||||
|         unsigned sz = A.size(); | ||||
|         auto sz = A.size(); | ||||
|         for (unsigned i = 0; i < sz; i++) { | ||||
|             svector<numeral> & as = A[i]; | ||||
|             m.del(b[i]); | ||||
|  |  | |||
|  | @ -4096,7 +4096,7 @@ namespace polynomial { | |||
|         // select a new random value in GF(p) that is not in vals, and store it in r
 | ||||
|         void peek_fresh(scoped_numeral_vector const & vals, unsigned p, scoped_numeral & r) { | ||||
|             SASSERT(vals.size() < p); // otherwise we can't keep the fresh value
 | ||||
|             unsigned sz = vals.size(); | ||||
|             auto sz = vals.size(); | ||||
|             while (true) { | ||||
|                 m().set(r, rand() % p); | ||||
|                 // check if fresh value...
 | ||||
|  | @ -6240,7 +6240,7 @@ namespace polynomial { | |||
|             } | ||||
| 
 | ||||
|             void reset() { | ||||
|                 unsigned sz = m_xs.size(); | ||||
|                 auto sz = m_xs.size(); | ||||
|                 for (unsigned i = 0; i < sz; i++) { | ||||
|                     m_max_degree[m_xs[i]] = 0; | ||||
|                 } | ||||
|  |  | |||
|  | @ -2126,7 +2126,7 @@ namespace upolynomial { | |||
|         } | ||||
|         frame_stack.push_back(drs_frame(parent_idx, sz, true)); | ||||
|         // right child
 | ||||
|         translate(sz, p_stack.end() - sz, p_aux); | ||||
|         translate(sz, p_stack.data() + p_stack.size() - sz, p_aux); | ||||
|         normalize(p_aux); | ||||
|         for (unsigned i = 0; i < sz; i++) { | ||||
|             p_stack.push_back(numeral()); | ||||
|  | @ -2226,7 +2226,7 @@ namespace upolynomial { | |||
|             drs_frame & fr    = frame_stack.back(); | ||||
|             unsigned sz       = fr.m_size; | ||||
|             SASSERT(sz <= p_stack.size()); | ||||
|             numeral const * p = p_stack.end() - sz; | ||||
|             numeral const * p = p_stack.data() + p_stack.size() - sz; | ||||
|             TRACE("upolynomial", tout << "processing frame #" << frame_stack.size() - 1 << "\n" | ||||
|                   << "first: " << fr.m_first << ", left: " << fr.m_left << ", sz: " << fr.m_size << ", parent_idx: "; | ||||
|                   if (fr.m_parent_idx == UINT_MAX) tout << "<null>"; else tout << fr.m_parent_idx; | ||||
|  |  | |||
|  | @ -39,8 +39,9 @@ namespace opt { | |||
|     class model_based_opt { | ||||
|     public: | ||||
|         struct var { | ||||
|             unsigned m_id; | ||||
|             unsigned m_id { 0 }; | ||||
|             rational m_coeff; | ||||
|             var() {} | ||||
|             var(unsigned id, rational const& c): m_id(id), m_coeff(c) {} | ||||
|             struct compare { | ||||
|                 bool operator()(var x, var y) { | ||||
|  |  | |||
|  | @ -616,7 +616,6 @@ struct model_evaluator::imp : public rewriter_tpl<mev::evaluator_cfg> { | |||
|                                     false, // no proofs for evaluator
 | ||||
|                                     m_cfg), | ||||
|         m_cfg(md.get_manager(), md, p) { | ||||
|         set_cancel_check(false); | ||||
|     } | ||||
|     void expand_stores(expr_ref &val) {m_cfg.expand_stores(val);} | ||||
|     void reset() { | ||||
|  |  | |||
|  | @ -202,12 +202,14 @@ namespace opt { | |||
|         return r; | ||||
|     } | ||||
| 
 | ||||
|     void opt_solver::maximize_objectives(expr_ref_vector& blockers) { | ||||
|     bool opt_solver::maximize_objectives1(expr_ref_vector& blockers) { | ||||
|         expr_ref blocker(m); | ||||
|         for (unsigned i = 0; i < m_objective_vars.size(); ++i) { | ||||
|             maximize_objective(i, blocker); | ||||
|             if (!maximize_objective(i, blocker)) | ||||
|                 return false; | ||||
|             blockers.push_back(blocker); | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     lbool opt_solver::find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes) { | ||||
|  | @ -238,7 +240,7 @@ namespace opt { | |||
|        Precondition: the state of the solver is satisfiable and such that a current model can be extracted. | ||||
|         | ||||
|     */ | ||||
|     void opt_solver::maximize_objective(unsigned i, expr_ref& blocker) { | ||||
|     bool opt_solver::maximize_objective(unsigned i, expr_ref& blocker) { | ||||
|         smt::theory_var v = m_objective_vars[i]; | ||||
|         bool has_shared = false; | ||||
|         m_last_model = nullptr; | ||||
|  | @ -256,8 +258,9 @@ namespace opt { | |||
|             SASSERT(has_shared); | ||||
|             decrement_value(i, val); | ||||
|             if (l_true != m_context.check(0, nullptr))   | ||||
|                 throw default_exception("maximization suspended"); | ||||
|             m_context.get_model(m_last_model);             | ||||
|                 return false; | ||||
|             m_context.get_model(m_last_model);       | ||||
|             return true; | ||||
|         }; | ||||
| 
 | ||||
|         if (!val.is_finite()) { | ||||
|  | @ -268,15 +271,15 @@ namespace opt { | |||
|             m_last_model = nullptr; | ||||
|             m_context.get_model(m_last_model); | ||||
|             if (has_shared && val != current_objective_value(i)) { | ||||
|                 decrement(); | ||||
|                 if (!decrement()) | ||||
|                     return false; | ||||
|             } | ||||
|             else { | ||||
|                 m_models.set(i, m_last_model.get()); | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             decrement(); | ||||
|         } | ||||
|         else if (!decrement()) | ||||
|             return false; | ||||
|         m_objective_values[i] = val; | ||||
|         TRACE("opt", {  | ||||
|                 tout << "objective:     " << mk_pp(m_objective_terms[i].get(), m) << "\n"; | ||||
|  | @ -285,6 +288,7 @@ namespace opt { | |||
|                 if (m_models[i]) model_smt2_pp(tout << "update model:\n", m, *m_models[i], 0);  | ||||
|                 if (m_last_model) model_smt2_pp(tout << "last model:\n", m, *m_last_model, 0); | ||||
|             }); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     lbool opt_solver::decrement_value(unsigned i, inf_eps& val) { | ||||
|  |  | |||
|  | @ -119,8 +119,8 @@ namespace opt { | |||
| 
 | ||||
|         smt::theory_var add_objective(app* term); | ||||
|         void reset_objectives(); | ||||
|         void maximize_objective(unsigned i, expr_ref& blocker); | ||||
|         void maximize_objectives(expr_ref_vector& blockers); | ||||
|         bool maximize_objective(unsigned i, expr_ref& blocker); | ||||
|         bool maximize_objectives1(expr_ref_vector& blockers); | ||||
|         inf_eps const & saved_objective_value(unsigned obj_index); | ||||
|         inf_eps current_objective_value(unsigned obj_index); | ||||
|         model* get_model_idx(unsigned obj_index) { return m_models[obj_index]; } | ||||
|  |  | |||
|  | @ -321,7 +321,8 @@ namespace opt { | |||
|                 is_sat = m_s->check_sat(1,vars); | ||||
|                 if (is_sat == l_true) { | ||||
|                     disj.reset(); | ||||
|                     m_s->maximize_objectives(disj); | ||||
|                     if (!m_s->maximize_objectives1(disj))  | ||||
|                         return l_undef; | ||||
|                     m_s->get_model(m_model);        | ||||
|                     m_s->get_labels(m_labels);             | ||||
|                     for (unsigned i = 0; i < ors.size(); ++i) { | ||||
|  | @ -395,7 +396,8 @@ namespace opt { | |||
|         expr_ref_vector disj(m); | ||||
|         m_s->get_model(m_model); | ||||
|         m_s->get_labels(m_labels); | ||||
|         m_s->maximize_objectives(disj); | ||||
|         if (!m_s->maximize_objectives1(disj)) | ||||
|             return expr_ref(m.mk_true(), m); | ||||
|         set_max(m_lower, m_s->get_objective_values(), disj); | ||||
|         TRACE("opt", model_pp(tout << m_lower << "\n", *m_model);); | ||||
|         IF_VERBOSE(2, verbose_stream() << "(optsmt.lower " << m_lower << ")\n";); | ||||
|  |  | |||
|  | @ -1944,6 +1944,8 @@ namespace smt2 { | |||
|                 expr ** expr_it   = expr_stack().data() + fr->m_expr_spos; | ||||
|                 expr ** expr_end  = expr_it + num_decls; | ||||
|                 for (; expr_it != expr_end; ++expr_it, ++sym_it) { | ||||
|                     if (!(*expr_it)) | ||||
|                         throw parser_exception("invalid let expression"); | ||||
|                     TRACE("let_frame", tout << "declaring: " << *sym_it << " " << mk_pp(*expr_it, m()) << "\n";); | ||||
|                     m_env.insert(*sym_it, local(*expr_it, m_num_bindings)); | ||||
|                 } | ||||
|  | @ -2569,7 +2571,7 @@ namespace smt2 { | |||
|                 throw cmd_exception("invalid assert command, expression required as argument"); | ||||
|             } | ||||
|             expr * f = expr_stack().back(); | ||||
|             if (!m().is_bool(f)) { | ||||
|             if (!f || !m().is_bool(f)) { | ||||
|                 TRACE("smt2parser", tout << expr_ref(f, m()) << "\n";); | ||||
|                 throw cmd_exception("invalid assert command, term is not Boolean"); | ||||
|             } | ||||
|  |  | |||
|  | @ -68,7 +68,7 @@ namespace sat { | |||
|         symbol m_name; | ||||
|         solver* m_solver { nullptr }; | ||||
|     public:         | ||||
|         extension(symbol const& name, int id): m_id(id), m_name(name) {} | ||||
|         extension(symbol const& name, int id): m_id(id), m_name(name) { } | ||||
|         virtual ~extension() {} | ||||
|         int get_id() const { return m_id; } | ||||
|         void set_solver(solver* s) { m_solver = s; }         | ||||
|  |  | |||
|  | @ -1296,7 +1296,7 @@ namespace sat { | |||
|             return do_local_search(num_lits, lits); | ||||
|         } | ||||
|         if ((m_config.m_num_threads > 1 || m_config.m_local_search_threads > 0 ||  | ||||
|              m_config.m_ddfw_threads > 0) && !m_par) { | ||||
|              m_config.m_ddfw_threads > 0) && !m_par && !m_ext) { | ||||
|             SASSERT(scope_lvl() == 0); | ||||
|             return check_par(num_lits, lits); | ||||
|         } | ||||
|  | @ -1440,6 +1440,9 @@ namespace sat { | |||
|         if (!rlimit().inc()) { | ||||
|             return l_undef; | ||||
|         } | ||||
|         if (m_ext) | ||||
|             return l_undef; | ||||
| 
 | ||||
|         scoped_ptr_vector<i_local_search> ls; | ||||
|         scoped_ptr_vector<solver> uw; | ||||
|         int num_extra_solvers = m_config.m_num_threads - 1; | ||||
|  |  | |||
|  | @ -164,7 +164,7 @@ namespace arith { | |||
|         unsigned index = 0; | ||||
|         while (index < terms.size()) { | ||||
|             SASSERT(index >= vars.size()); | ||||
|             expr* n = terms[index].get(); | ||||
|             expr* n = terms.get(index); | ||||
|             st.to_ensure_enode().push_back(n); | ||||
|             if (a.is_add(n)) { | ||||
|                 for (expr* arg : *to_app(n)) { | ||||
|  | @ -382,7 +382,7 @@ namespace arith { | |||
|         updt_unassigned_bounds(v, +1); | ||||
|         m_bounds_trail.push_back(v); | ||||
|         m_bool_var2bound.insert(bv, b); | ||||
|         TRACE("arith_verbose", tout << "Internalized " << bv << ": " << mk_pp(atom, m) << "\n";); | ||||
|         TRACE("arith_verbose", tout << "Internalized " << lit << ": " << mk_pp(atom, m) << " " << *b << "\n";); | ||||
|         m_new_bounds.push_back(b); | ||||
|         //add_use_lists(b);
 | ||||
|         return true; | ||||
|  | @ -391,7 +391,7 @@ namespace arith { | |||
| 
 | ||||
|     bool solver::internalize_term(expr* term) { | ||||
|         if (!has_var(term)) | ||||
|             internalize_def(term); | ||||
|             register_theory_var_in_lar_solver(internalize_def(term)); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|  | @ -583,11 +583,10 @@ namespace arith { | |||
|         if (e->is_attached_to(get_id())) | ||||
|             return e->get_th_var(get_id()); | ||||
|         theory_var v = mk_var(e); | ||||
|         TRACE("arith", tout << "fresh var: v" << v << " " << mk_pp(n, m) << "\n";); | ||||
|         TRACE("arith_verbose", tout << "v" << v << " " << mk_pp(n, m) << "\n";); | ||||
|         SASSERT(m_bounds.size() <= static_cast<unsigned>(v) || m_bounds[v].empty()); | ||||
|         reserve_bounds(v); | ||||
|         ctx.attach_th_var(e, this, v); | ||||
|         TRACE("arith", tout << mk_pp(n, m) << " " << v << "\n";); | ||||
|         SASSERT(euf::null_theory_var != v); | ||||
|         return v; | ||||
|     } | ||||
|  |  | |||
|  | @ -145,7 +145,7 @@ namespace arith { | |||
|         bool v_is_int = b.is_int(); | ||||
|         literal lit2 = sat::null_literal; | ||||
|         bool find_glb = (is_true == (k == lp_api::lower_t)); | ||||
|         TRACE("arith", tout << "v" << v << " find_glb: " << find_glb << " is_true: " << is_true << " k: " << k << " is_lower: " << (k == lp_api::lower_t) << "\n";); | ||||
|         TRACE("arith", tout << lit1 << " v" << v << " val " << val << " find_glb: " << find_glb << " is_true: " << is_true << " k: " << k << " is_lower: " << (k == lp_api::lower_t) << "\n";); | ||||
|         if (find_glb) { | ||||
|             rational glb; | ||||
|             api_bound* lb = nullptr; | ||||
|  | @ -187,6 +187,7 @@ namespace arith { | |||
|         m_params.push_back(parameter(m_farkas)); | ||||
|         m_params.push_back(parameter(rational(1))); | ||||
|         m_params.push_back(parameter(rational(1))); | ||||
|         TRACE("arith", tout << lit2 << " <- " << m_core << "\n";); | ||||
|         assign(lit2, m_core, m_eqs, m_params); | ||||
|         ++m_stats.m_bounds_propagations; | ||||
|     } | ||||
|  | @ -1001,6 +1002,8 @@ namespace arith { | |||
|             ++m_stats.m_assume_eqs; | ||||
|             return sat::check_result::CR_CONTINUE; | ||||
|         } | ||||
|         if (!check_delayed_eqs())  | ||||
|             return sat::check_result::CR_CONTINUE; | ||||
|         if (m_not_handled != nullptr) { | ||||
|             TRACE("arith", tout << "unhandled operator " << mk_pp(m_not_handled, m) << "\n";); | ||||
|             return sat::check_result::CR_GIVEUP; | ||||
|  |  | |||
|  | @ -39,8 +39,10 @@ namespace array { | |||
|                 dep.add(n, p->get_arg(i)); | ||||
|         } | ||||
|         for (euf::enode* k : euf::enode_class(n))  | ||||
|             if (a.is_const(k->get_expr())) | ||||
|                 dep.add(n, k->get_arg(0));     | ||||
|             if (a.is_const(k->get_expr()))  | ||||
|                 dep.add(n, k->get_arg(0));  | ||||
|         if (!dep.deps().contains(n)) | ||||
|             dep.insert(n, nullptr); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -31,6 +31,8 @@ namespace bv { | |||
|     } | ||||
| 
 | ||||
|     void ackerman::reset() { | ||||
|         while (m_queue) | ||||
|             remove(m_queue->prev());      | ||||
|         m_table.reset(); | ||||
|         m_queue = nullptr;         | ||||
|     } | ||||
|  |  | |||
|  | @ -90,7 +90,7 @@ namespace bv { | |||
|         m_wpos.push_back(0); | ||||
|         m_zero_one_bits.push_back(zero_one_bits());        | ||||
|         ctx.attach_th_var(n, this, r);         | ||||
|         TRACE("bv", tout << "mk-var: " << r << " " << n->get_expr_id() << " " << mk_bounded_pp(n->get_expr(), m) << "\n";); | ||||
|         TRACE("bv", tout << "mk-var: v" << r << " " << n->get_expr_id() << " " << mk_bounded_pp(n->get_expr(), m) << "\n";); | ||||
|         return r; | ||||
|     } | ||||
| 
 | ||||
|  | @ -157,11 +157,15 @@ namespace bv { | |||
|         std::function<void(unsigned sz, expr* const* xs, expr* const* ys, expr_ref& bit)> ebin; | ||||
|         std::function<void(unsigned sz, expr* const* xs, expr_ref_vector& bits)> un; | ||||
|         std::function<void(unsigned sz, expr* const* xs, unsigned p, expr_ref_vector& bits)> pun; | ||||
|         std::function<expr*(expr* x, expr* y)> ibin; | ||||
|         std::function<expr*(expr* x)> iun; | ||||
| 
 | ||||
| #define internalize_bin(F) bin = [&](unsigned sz, expr* const* xs, expr* const* ys, expr_ref_vector& bits) { m_bb.F(sz, xs, ys, bits); }; internalize_binary(a, bin); | ||||
| #define internalize_un(F) un = [&](unsigned sz, expr* const* xs, expr_ref_vector& bits) { m_bb.F(sz, xs, bits);}; internalize_unary(a, un); | ||||
| #define internalize_ac(F) bin = [&](unsigned sz, expr* const* xs, expr* const* ys, expr_ref_vector& bits) { m_bb.F(sz, xs, ys, bits); }; internalize_ac_binary(a, bin); | ||||
| #define internalize_pun(F) pun = [&](unsigned sz, expr* const* xs, unsigned p, expr_ref_vector& bits) { m_bb.F(sz, xs, p, bits);}; internalize_par_unary(a, pun); | ||||
| #define internalize_nfl(F) ebin = [&](unsigned sz, expr* const* xs, expr* const* ys, expr_ref& out) { m_bb.F(sz, xs, ys, out);}; internalize_novfl(a, ebin); | ||||
| #define internalize_int(B, U) ibin = [&](expr* x, expr* y) { return B(x, y); }; iun = [&](expr* x) { return U(x); }; internalize_interp(a, ibin, iun); | ||||
| 
 | ||||
|         switch (a->get_decl_kind()) { | ||||
|         case OP_BV_NUM:           internalize_num(a); break; | ||||
|  | @ -209,10 +213,15 @@ namespace bv { | |||
|         case OP_BSUB:             internalize_sub(a); break; | ||||
|         case OP_CONCAT:           internalize_concat(a); break; | ||||
|         case OP_EXTRACT:          internalize_extract(a); break; | ||||
|         case OP_REPEAT:           internalize_repeat(a); break; | ||||
|         case OP_MKBV:             internalize_mkbv(a); break; | ||||
|         case OP_INT2BV:           internalize_int2bv(a); break; | ||||
|         case OP_BV2INT:           internalize_bv2int(a); break; | ||||
|         case OP_BUDIV:            internalize_udiv(a); break; | ||||
|         case OP_BUDIV:            internalize_int(bv.mk_bv_udiv_i, bv.mk_bv_udiv0); break; | ||||
|         case OP_BSDIV:            internalize_int(bv.mk_bv_sdiv_i, bv.mk_bv_sdiv0); break; | ||||
|         case OP_BSREM:            internalize_int(bv.mk_bv_srem_i, bv.mk_bv_srem0); break; | ||||
|         case OP_BUREM:            internalize_int(bv.mk_bv_urem_i, bv.mk_bv_urem0); break; | ||||
|         case OP_BSMOD:            internalize_int(bv.mk_bv_smod_i, bv.mk_bv_smod0); break; | ||||
|         case OP_BSDIV0:           break; | ||||
|         case OP_BUDIV0:           break; | ||||
|         case OP_BSREM0:           break; | ||||
|  | @ -280,6 +289,7 @@ namespace bv { | |||
|         SASSERT(l == mk_true() || ~l == mk_true()); | ||||
|         bool is_true = l == mk_true(); | ||||
|         zero_one_bits& bits = m_zero_one_bits[v]; | ||||
|         TRACE("bv", tout << "register v" << v << " " << l << " " << mk_true() << "\n";); | ||||
|         bits.push_back(zero_one_bit(v, idx, is_true)); | ||||
|     } | ||||
| 
 | ||||
|  | @ -516,19 +526,20 @@ namespace bv { | |||
|         internalize_binary(a, bin); | ||||
|     } | ||||
| 
 | ||||
|     void solver::internalize_udiv(app* n) { | ||||
|     void solver::internalize_interp(app* n, std::function<expr*(expr*, expr*)>& ibin, std::function<expr*(expr*)>& iun) { | ||||
|         bv_rewriter_params p(s().params()); | ||||
|         expr* arg1 = n->get_arg(0); | ||||
|         expr* arg2 = n->get_arg(1); | ||||
|         mk_bits(get_th_var(n)); | ||||
|         if (p.hi_div0()) { | ||||
|             add_unit(eq_internalize(n, bv.mk_bv_udiv_i(arg1, arg2))); | ||||
|             add_unit(eq_internalize(n, ibin(arg1, arg2))); | ||||
|             return; | ||||
|         } | ||||
|         unsigned sz = bv.get_bv_size(n); | ||||
|         expr_ref zero(bv.mk_numeral(0, sz), m); | ||||
|         expr_ref eq(m.mk_eq(arg2, zero), m); | ||||
|         expr_ref udiv(m.mk_ite(eq, bv.mk_bv_udiv0(arg1), bv.mk_bv_udiv_i(arg1, arg2)), m); | ||||
|         add_unit(eq_internalize(n, udiv)); | ||||
|         expr_ref ite(m.mk_ite(eq, iun(arg1), ibin(arg1, arg2)), m); | ||||
|         add_unit(eq_internalize(n, ite)); | ||||
|     } | ||||
| 
 | ||||
|     void solver::internalize_unary(app* n, std::function<void(unsigned, expr* const*, expr_ref_vector&)>& fn) { | ||||
|  | @ -559,7 +570,7 @@ namespace bv { | |||
|     } | ||||
| 
 | ||||
|     void solver::internalize_ac_binary(app* e, std::function<void(unsigned, expr* const*, expr* const*, expr_ref_vector&)>& fn) { | ||||
|         SASSERT(e->get_num_args() >= 2); | ||||
|         SASSERT(e->get_num_args() >= 1); | ||||
|         expr_ref_vector bits(m), new_bits(m), arg_bits(m); | ||||
|         unsigned i = e->get_num_args() - 1; | ||||
|         get_arg_bits(e, i, bits); | ||||
|  | @ -632,6 +643,18 @@ namespace bv { | |||
|         find_wpos(v); | ||||
|     } | ||||
| 
 | ||||
|     void solver::internalize_repeat(app* e) { | ||||
|         unsigned n = 0; | ||||
|         expr* arg = nullptr; | ||||
|         VERIFY(bv.is_repeat(e, arg, n)); | ||||
|         expr_ref_vector conc(m); | ||||
|         for (unsigned i = 0; i < n; ++i) | ||||
|             conc.push_back(arg); | ||||
|         expr_ref r(bv.mk_concat(conc), m); | ||||
|         mk_bits(get_th_var(e)); | ||||
|         add_unit(eq_internalize(e, r)); | ||||
|     } | ||||
| 
 | ||||
|     void solver::internalize_bit2bool(app* n) { | ||||
|         unsigned idx = 0; | ||||
|         expr* arg = nullptr; | ||||
|  |  | |||
|  | @ -93,8 +93,16 @@ namespace bv { | |||
|         } while (curr != v); | ||||
| 
 | ||||
|         zero_one_bits const& _bits = m_zero_one_bits[v]; | ||||
|         if (_bits.size() != num_bits) | ||||
|             std::cout << v << " " << _bits.size() << " " << num_bits << "\n"; | ||||
|         if (_bits.size() != num_bits) { | ||||
|             std::cout << "v" << v << " " << _bits.size() << " " << num_bits << "\n"; | ||||
|             std::cout << "true: " << mk_true() << "\n"; | ||||
|             do { | ||||
|                 std::cout << "v" << curr << ": " << m_bits[curr] << "\n"; | ||||
|                 curr = m_find.next(curr); | ||||
|             } | ||||
|             while (curr != v); | ||||
|         } | ||||
|         SASSERT(_bits.size() == num_bits); | ||||
|         VERIFY(_bits.size() == num_bits); | ||||
|         bool_vector already_found; | ||||
|         already_found.resize(bv_sz, false); | ||||
|  |  | |||
|  | @ -661,9 +661,10 @@ namespace bv { | |||
|             result->m_bits[i].append(m_bits[i]); | ||||
|             result->m_zero_one_bits[i].append(m_zero_one_bits[i]); | ||||
|         } | ||||
|         result->set_solver(&ctx.s()); | ||||
|         for (theory_var i = 0; i < static_cast<theory_var>(get_num_vars()); ++i) | ||||
|             if (find(i) != i) | ||||
|                 result->m_find.merge(i, find(i)); | ||||
|                 result->m_find.set_root(i, find(i)); | ||||
|         result->m_prop_queue.append(m_prop_queue); | ||||
|         for (unsigned i = 0; i < m_bool_var2atom.size(); ++i) { | ||||
|             atom* a = m_bool_var2atom[i]; | ||||
|  |  | |||
|  | @ -102,6 +102,9 @@ namespace bv { | |||
|             unsigned   m_is_true:1; | ||||
|             zero_one_bit(theory_var v = euf::null_theory_var, unsigned idx = UINT_MAX, bool is_true = false): | ||||
|                 m_owner(v), m_idx(idx), m_is_true(is_true) {} | ||||
|             std::ostream& display(std::ostream& out) const { | ||||
|                 return out << "v" << m_owner << " @ " << m_idx << " " << (m_is_true?"T":"F"); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         typedef svector<zero_one_bit> zero_one_bits; | ||||
|  | @ -239,6 +242,7 @@ namespace bv { | |||
|         void internalize_ac_binary(app* n, std::function<void(unsigned, expr* const*, expr* const*, expr_ref_vector&)>& fn); | ||||
|         void internalize_par_unary(app* n, std::function<void(unsigned, expr* const*, unsigned p, expr_ref_vector&)>& fn); | ||||
|         void internalize_novfl(app* n, std::function<void(unsigned, expr* const*, expr* const*, expr_ref&)>& fn); | ||||
|         void internalize_interp(app* n, std::function<expr*(expr*, expr*)>& ibin, std::function<expr*(expr*)>& un); | ||||
|         void internalize_num(app * n);        | ||||
|         void internalize_concat(app * n);         | ||||
|         void internalize_bv2int(app* n); | ||||
|  | @ -248,8 +252,8 @@ namespace bv { | |||
|         void internalize_carry(app* n); | ||||
|         void internalize_sub(app* n); | ||||
|         void internalize_extract(app* n); | ||||
|         void internalize_repeat(app* n); | ||||
|         void internalize_bit2bool(app* n); | ||||
|         void internalize_udiv(app* n); | ||||
|         void internalize_udiv_i(app* n); | ||||
|         template<bool Signed, bool Reverse, bool Negated> | ||||
|         void internalize_le(app* n); | ||||
|  | @ -366,9 +370,12 @@ namespace bv { | |||
|         typedef std::pair<solver const*, theory_var> pp_var; | ||||
|         pp_var pp(theory_var v) const { return pp_var(this, v); } | ||||
| 
 | ||||
|         friend std::ostream& operator<<(std::ostream& out, solver::zero_one_bit const& zo) { return zo.display(out); } | ||||
| 
 | ||||
|     }; | ||||
| 
 | ||||
|     inline std::ostream& operator<<(std::ostream& out, solver::pp_var const& p) { return p.first->display(out, p.second); } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -63,6 +63,7 @@ namespace dt { | |||
|         SASSERT(s.m_to_unmark2.empty()); | ||||
|         s.m_used_eqs.reset(); | ||||
|         s.m_dfs.reset(); | ||||
|         s.m_parent.reset(); | ||||
|     } | ||||
| 
 | ||||
|     solver::final_check_st::~final_check_st() { | ||||
|  | @ -692,6 +693,10 @@ namespace dt { | |||
| 
 | ||||
|     void solver::add_value(euf::enode* n, model& mdl, expr_ref_vector& values) { | ||||
|         theory_var v = n->get_th_var(get_id()); | ||||
|         if (v == euf::null_theory_var) { | ||||
|             values.set(n->get_root_id(), mdl.get_fresh_value(n->get_sort())); | ||||
|             return; | ||||
|         } | ||||
|         v = m_find.find(v); | ||||
|         SASSERT(v != euf::null_theory_var); | ||||
|         enode* con = m_var_data[v]->m_constructor; | ||||
|  | @ -703,9 +708,11 @@ namespace dt { | |||
|     } | ||||
| 
 | ||||
|     bool solver::add_dep(euf::enode* n, top_sort<euf::enode>& dep) { | ||||
|         theory_var v = n->get_th_var(get_id()); | ||||
|         if (!is_datatype(n->get_expr())) | ||||
|             return true; | ||||
|             return false; | ||||
|         theory_var v = n->get_th_var(get_id()); | ||||
|         if (v == euf::null_theory_var)  | ||||
|             return false; | ||||
|         euf::enode* con = m_var_data[m_find.find(v)]->m_constructor; | ||||
|         if (con->num_args() == 0) | ||||
|             dep.insert(n, nullptr); | ||||
|  | @ -715,10 +722,8 @@ namespace dt { | |||
|     } | ||||
| 
 | ||||
|     sat::literal solver::internalize(expr* e, bool sign, bool root, bool redundant) { | ||||
|         if (!visit_rec(m, e, sign, root, redundant)) { | ||||
|             TRACE("dt", tout << mk_pp(e, m) << "\n";); | ||||
|             return sat::null_literal; | ||||
|         } | ||||
|         if (!visit_rec(m, e, sign, root, redundant))  | ||||
|             return sat::null_literal;         | ||||
|         auto lit = ctx.expr2literal(e); | ||||
|         if (sign) | ||||
|             lit.neg(); | ||||
|  |  | |||
|  | @ -141,8 +141,7 @@ namespace euf { | |||
|         } | ||||
| 
 | ||||
|         m_bool_var2expr.reserve(v + 1, nullptr); | ||||
|         if (m_bool_var2expr[v]) { | ||||
|             SASSERT(m_egraph.find(e)); | ||||
|         if (m_bool_var2expr[v] && m_egraph.find(e)) { | ||||
|             SASSERT(m_egraph.find(e)->bool_var() == v); | ||||
|             return lit; | ||||
|         } | ||||
|  | @ -158,6 +157,8 @@ namespace euf { | |||
|             m_egraph.set_merge_enabled(n, false); | ||||
|         if (!si.is_bool_op(e)) | ||||
|             track_relevancy(lit.var()); | ||||
|         if (s().value(lit) != l_undef)  | ||||
|             m_egraph.set_value(n, s().value(lit)); | ||||
|         return lit; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -48,8 +48,10 @@ namespace euf { | |||
|         if (s().inconsistent()) | ||||
|             return; | ||||
|         for (enode* n : m_egraph.nodes()) | ||||
|             if (m.is_false(n->get_root()->get_expr()) && m.is_eq(n->get_expr()) && | ||||
|                 n->get_arg(0)->get_root() == n->get_arg(1)->get_root()) { | ||||
|             if (m.is_false(n->get_root()->get_expr()) &&  | ||||
|                 m.is_eq(n->get_expr()) && | ||||
|                 !m.is_bool(n->get_app()->get_arg(0)) &&  | ||||
|                 (n->get_arg(0)->get_root() == n->get_arg(1)->get_root())) { | ||||
|                 enable_trace("euf"); | ||||
|                 TRACE("euf", display(tout << n->get_expr_id() << ": " << mk_pp(n->get_expr(), m) << "\n"  | ||||
|                                      << "#" << n->get_arg(0)->get_expr_id() << " == #" << n->get_arg(1)->get_expr_id() << " r: " << n->get_arg(0)->get_root_id() << "\n"); | ||||
|  |  | |||
|  | @ -144,6 +144,16 @@ namespace euf { | |||
|                     m_values.set(id, m.mk_false()); | ||||
|                     continue; | ||||
|                 } | ||||
|                 switch (n->value()) { | ||||
|                 case l_true: | ||||
|                     m_values.set(id, m.mk_true()); | ||||
|                     continue; | ||||
|                 case l_false: | ||||
|                     m_values.set(id, m.mk_false()); | ||||
|                     continue; | ||||
|                 default: | ||||
|                     break; | ||||
|                 } | ||||
|                 if (is_app(e) && to_app(e)->get_family_id() == m.get_basic_family_id()) | ||||
|                     continue; | ||||
|                 sat::bool_var v = get_enode(e)->bool_var(); | ||||
|  | @ -198,6 +208,7 @@ namespace euf { | |||
|                     fi = alloc(func_interp, m, arity); | ||||
|                     mdl->register_decl(f, fi); | ||||
|                 } | ||||
|                 TRACE("euf", tout << f->get_name() << "\n";); | ||||
|                 args.reset();                 | ||||
|                 for (enode* arg : enode_args(n))  | ||||
|                     args.push_back(m_values.get(arg->get_root_id()));                 | ||||
|  |  | |||
|  | @ -410,10 +410,8 @@ namespace q { | |||
|         mam::ground_subterms(pat, m_ground); | ||||
|         for (expr* g : m_ground) {  | ||||
|             euf::enode* n = ctx.get_egraph().find(g); | ||||
|             if (!n->is_attached_to(m_qs.get_id())) { | ||||
|                 euf::theory_var v = m_qs.mk_var(n); | ||||
|                 ctx.get_egraph().add_th_var(n, v, m_qs.get_id()); | ||||
|             } | ||||
|             if (!n->is_attached_to(m_qs.get_id()))  | ||||
|                 m_qs.mk_var(n);             | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -96,7 +96,6 @@ namespace q { | |||
|     } | ||||
| 
 | ||||
|     euf::theory_var solver::mk_var(euf::enode* n) { | ||||
|         SASSERT(is_forall(n->get_expr()) || is_exists(n->get_expr())); | ||||
|         auto v = euf::th_euf_solver::mk_var(n); | ||||
|         ctx.attach_th_var(n, this, v);         | ||||
|         return v; | ||||
|  |  | |||
|  | @ -162,13 +162,13 @@ namespace smt { | |||
|        The variables are replaced by skolem constants. These constants are stored in sks. | ||||
|     */ | ||||
| 
 | ||||
|     void model_checker::assert_neg_q_m(quantifier * q, expr_ref_vector & sks) { | ||||
|     bool model_checker::assert_neg_q_m(quantifier * q, expr_ref_vector & sks) { | ||||
|         expr_ref tmp(m); | ||||
|          | ||||
|         TRACE("model_checker", tout << "curr_model:\n"; model_pp(tout, *m_curr_model);); | ||||
| 
 | ||||
|         if (!m_curr_model->eval(q->get_expr(), tmp, true)) { | ||||
|             return; | ||||
|             return false; | ||||
|         } | ||||
|         TRACE("model_checker", tout << "q after applying interpretation:\n" << mk_ismt2_pp(tmp, m) << "\n";); | ||||
|         ptr_buffer<expr> subst_args; | ||||
|  | @ -191,6 +191,7 @@ namespace smt { | |||
|         r = m.mk_not(sk_body); | ||||
|         TRACE("model_checker", tout << "mk_neg_q_m:\n" << mk_ismt2_pp(r, m) << "\n";); | ||||
|         m_aux_context->assert_expr(r); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     bool model_checker::add_instance(quantifier * q, model * cex, expr_ref_vector & sks, bool use_inv) { | ||||
|  | @ -333,7 +334,8 @@ namespace smt { | |||
|         TRACE("model_checker", tout << "model checking:\n" << expr_ref(flat_q->get_expr(), m) << "\n";); | ||||
|         expr_ref_vector sks(m); | ||||
| 
 | ||||
|         assert_neg_q_m(flat_q, sks); | ||||
|         if (!assert_neg_q_m(flat_q, sks)) | ||||
|             return false; | ||||
|         TRACE("model_checker", tout << "skolems:\n" << sks << "\n";); | ||||
| 
 | ||||
|         flet<bool> l(m_aux_context->get_fparams().m_array_fake_support, true); | ||||
|  |  | |||
|  | @ -62,7 +62,7 @@ namespace smt { | |||
|         expr * get_type_compatible_term(expr * val); | ||||
|         expr_ref replace_value_from_ctx(expr * e); | ||||
|         void restrict_to_universe(expr * sk, obj_hashtable<expr> const & universe); | ||||
|         void assert_neg_q_m(quantifier * q, expr_ref_vector & sks); | ||||
|         bool assert_neg_q_m(quantifier * q, expr_ref_vector & sks); | ||||
|         bool add_blocking_clause(model * cex, expr_ref_vector & sks); | ||||
|         bool check(quantifier * q); | ||||
|         void check_quantifiers(bool& found_relevant, unsigned& num_failures); | ||||
|  |  | |||
|  | @ -74,7 +74,6 @@ namespace smt { | |||
|                 for (auto const& kv : m_elems) { | ||||
|                     m.dec_ref(kv.m_key); | ||||
|                 } | ||||
|                 m_elems.reset(); | ||||
|             } | ||||
| 
 | ||||
|             obj_map<expr, unsigned> const& get_elems() const { return m_elems; } | ||||
|  |  | |||
|  | @ -1872,11 +1872,14 @@ public: | |||
| 
 | ||||
| app* theory_seq::get_ite_value(expr* e) { | ||||
|     expr* e1, *e2, *e3; | ||||
|     while (m.is_ite(e, e1, e2, e3)) { | ||||
|         if (get_root(e2) == get_root(e)) { | ||||
|     while (m.is_ite(e, e1, e2, e3)) {         | ||||
|         if (!ctx.e_internalized(e)) | ||||
|             break; | ||||
|         enode* r = ctx.get_enode(e)->get_root(); | ||||
|         if (ctx.get_enode(e2)->get_root() == r) { | ||||
|             e = e2; | ||||
|         } | ||||
|         else if (get_root(e3) == get_root(e)) { | ||||
|         else if (ctx.get_enode(e3)->get_root() == r) { | ||||
|             e = e3; | ||||
|         } | ||||
|         else { | ||||
|  |  | |||
|  | @ -70,6 +70,10 @@ public: | |||
|         m_set(s.m_set) { | ||||
|     } | ||||
| 
 | ||||
|     void set(R s) { m_set = s; } | ||||
| 
 | ||||
|     R get() const { return m_set; } | ||||
| 
 | ||||
|     void insert(T const & e) { | ||||
|         m_set |= e2s(e); | ||||
|     } | ||||
|  | @ -162,7 +166,7 @@ class approx_set : public u_approx_set { | |||
| public: | ||||
|     approx_set():u_approx_set() {} | ||||
|     approx_set(unsigned e):u_approx_set(e) {} | ||||
| 
 | ||||
|      | ||||
|     class iterator { | ||||
|         unsigned long long m_set; | ||||
|         unsigned           m_val; | ||||
|  |  | |||
|  | @ -139,7 +139,7 @@ public: | |||
|         if (empty()) { | ||||
|             return; | ||||
|         } | ||||
|         memset(m_value2indices.begin(), 0, sizeof(int) * m_value2indices.size()); | ||||
|         memset(m_value2indices.data(), 0, sizeof(int) * m_value2indices.size()); | ||||
|         m_values.reset(); | ||||
|         m_values.push_back(-1); | ||||
|         CASSERT("heap", check_invariant()); | ||||
|  | @ -244,11 +244,11 @@ public: | |||
|     } | ||||
| 
 | ||||
|     iterator begin() {  | ||||
|         return m_values.begin() + 1;  | ||||
|         return m_values.data() + 1;  | ||||
|     } | ||||
| 
 | ||||
|     iterator end() {  | ||||
|         return m_values.end();  | ||||
|         return m_values.data() + m_values.size();  | ||||
|     } | ||||
| 
 | ||||
|     const_iterator begin() const {  | ||||
|  |  | |||
|  | @ -112,7 +112,7 @@ class mpff_manager { | |||
|      | ||||
|     unsigned          m_precision;      //!< Number of words in the significand. Must be an even number.
 | ||||
|     unsigned          m_precision_bits; //!< Number of bits in the significand.  Must be 32*m_precision.
 | ||||
|     unsigned_vector   m_significands;   //!< Array containing all significands.
 | ||||
|     mutable unsigned_vector   m_significands;   //!< Array containing all significands.
 | ||||
|     unsigned          m_capacity;       //!< Number of significands that can be stored in m_significands.
 | ||||
|     bool              m_to_plus_inf;    //!< If True, then round to plus infinity, otherwise to minus infinity
 | ||||
|     id_gen            m_id_gen; | ||||
|  |  | |||
|  | @ -258,7 +258,7 @@ void mpfx_manager::set_core(mpfx & n, mpz_manager<SYNCH> & m, mpz const & v) { | |||
|         m_tmp_digits.reset(); | ||||
|         allocate_if_needed(n); | ||||
|         n.m_sign = m.decompose(v, m_tmp_digits); | ||||
|         unsigned sz = m_tmp_digits.size(); | ||||
|         auto sz = m_tmp_digits.size(); | ||||
|         if (sz > m_int_part_sz) | ||||
|             throw overflow_exception(); | ||||
|         unsigned * w = words(n); | ||||
|  | @ -299,7 +299,7 @@ void mpfx_manager::set_core(mpfx & n, mpq_manager<SYNCH> & m, mpq const & v) { | |||
|         } | ||||
|         m_tmp_digits.reset(); | ||||
|         m.decompose(tmp, m_tmp_digits); | ||||
|         unsigned sz = m_tmp_digits.size(); | ||||
|         auto sz = m_tmp_digits.size(); | ||||
|         if (sz > m_total_sz) | ||||
|             throw overflow_exception(); | ||||
|         unsigned * w = words(n); | ||||
|  |  | |||
|  | @ -81,11 +81,11 @@ class mpfx_manager { | |||
|     unsigned          m_int_part_sz; | ||||
|     unsigned          m_frac_part_sz; | ||||
|     unsigned          m_total_sz;       //!< == m_int_part_sz + m_frac_part_sz
 | ||||
|     unsigned_vector   m_words;          //!< Array containing all words
 | ||||
|     mutable unsigned_vector   m_words;          //!< Array containing all words
 | ||||
|     unsigned          m_capacity;       //!< Number of mpfx numerals that can be stored in m_words.
 | ||||
|     bool              m_to_plus_inf;    //!< If True, then round to plus infinity, otherwise to minus infinity
 | ||||
|     id_gen            m_id_gen; | ||||
|     unsigned_vector   m_buffer0, m_buffer1, m_buffer2; | ||||
|     mutable unsigned_vector   m_buffer0, m_buffer1, m_buffer2; | ||||
|     unsigned_vector   m_tmp_digits; | ||||
|     mpfx              m_one; | ||||
|     mpn_manager       m_mpn_manager; | ||||
|  |  | |||
|  | @ -52,10 +52,14 @@ Revision History: | |||
| // This is needed for _tzcnt_u32 and friends.
 | ||||
| #include <immintrin.h> | ||||
| #define _trailing_zeros32(X) _tzcnt_u32(X) | ||||
| #endif | ||||
| 
 | ||||
| #if defined(__GNUC__) | ||||
| #elif defined(__GNUC__) | ||||
| #define _trailing_zeros32(X) __builtin_ctz(X) | ||||
| #else | ||||
| static uint32_t _trailing_zeros32(uint32_t x) { | ||||
|     uint32_t r = 0; | ||||
|     for (; 0 == (x & 1) && r < 32; ++r, x >>= 1); | ||||
|     return r; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #if (defined(__LP64__) || defined(_WIN64)) && !defined(_M_ARM) && !defined(_M_ARM64) | ||||
|  | @ -65,23 +69,11 @@ Revision History: | |||
|  #define _trailing_zeros64(X) _tzcnt_u64(X) | ||||
|  #endif | ||||
| #else | ||||
| inline uint64_t _trailing_zeros64(uint64_t x) { | ||||
| static uint64_t _trailing_zeros64(uint64_t x) { | ||||
|     uint64_t r = 0; | ||||
|     for (; 0 == (x & 1) && r < 64; ++r, x >>= 1); | ||||
|     return r; | ||||
| } | ||||
| 
 | ||||
| #if defined(_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) | ||||
| // _trailing_zeros32 already defined using intrinsics
 | ||||
| #elif defined(__GNUC__) | ||||
| // _trailing_zeros32 already defined using intrinsics
 | ||||
| #else | ||||
| inline uint32_t _trailing_zeros32(uint32_t x) { | ||||
|     uint32_t r = 0; | ||||
|     for (; 0 == (x & 1) && r < 32; ++r, x >>= 1); | ||||
|     return r; | ||||
| } | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| unsigned trailing_zeros(uint32_t x) { | ||||
|  | @ -1723,8 +1715,8 @@ void mpz_manager<SYNCH>::display(std::ostream & out, mpz const & a) const { | |||
|         // GMP version
 | ||||
|         size_t sz = mpz_sizeinbase(*a.m_ptr, 10) + 2; | ||||
|         sbuffer<char, 1024> buffer(sz, 0); | ||||
|         mpz_get_str(buffer.c_ptr(), 10, *a.m_ptr); | ||||
|         out << buffer.c_ptr(); | ||||
|         mpz_get_str(buffer.data(), 10, *a.m_ptr); | ||||
|         out << buffer.data(); | ||||
| #endif | ||||
|     }  | ||||
| } | ||||
|  | @ -1783,11 +1775,11 @@ void mpz_manager<SYNCH>::display_hex(std::ostream & out, mpz const & a, unsigned | |||
|         unsigned requiredLength = num_bits / 4; | ||||
|         unsigned padding = requiredLength > sz ? requiredLength - sz : 0; | ||||
|         sbuffer<char, 1024> buffer(sz, 0); | ||||
|         mpz_get_str(buffer.c_ptr(), 16, *(a.m_ptr)); | ||||
|         mpz_get_str(buffer.data(), 16, *(a.m_ptr)); | ||||
|         for (unsigned i = 0; i < padding; ++i) { | ||||
|             out << "0"; | ||||
|         } | ||||
|         out << buffer.c_ptr() + (sz > requiredLength ? sz - requiredLength : 0); | ||||
|         out << buffer.data() + (sz > requiredLength ? sz - requiredLength : 0); | ||||
| #endif | ||||
|     } | ||||
|     out.copyfmt(fmt); | ||||
|  | @ -1837,11 +1829,11 @@ void mpz_manager<SYNCH>::display_bin(std::ostream & out, mpz const & a, unsigned | |||
|         size_t sz = mpz_sizeinbase(*(a.m_ptr), 2); | ||||
|         unsigned padding = num_bits > sz ? num_bits - sz : 0; | ||||
|         sbuffer<char, 1024> buffer(sz, 0); | ||||
|         mpz_get_str(buffer.c_ptr(), 2, *(a.m_ptr)); | ||||
|         mpz_get_str(buffer.data(), 2, *(a.m_ptr)); | ||||
|         for (unsigned i = 0; i < padding; ++i) { | ||||
|             out << "0"; | ||||
|         } | ||||
|         out << buffer.c_ptr() + (sz > num_bits ? sz - num_bits : 0); | ||||
|         out << buffer.data() + (sz > num_bits ? sz - num_bits : 0); | ||||
| #endif | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -58,28 +58,28 @@ public: | |||
|     ref_vector_core(ref_vector_core &&) noexcept = default; | ||||
|      | ||||
|     ~ref_vector_core() { | ||||
|         dec_range_ref(m_nodes.begin(), m_nodes.end()); | ||||
|         dec_range_ref(m_nodes.data(), m_nodes.data() + m_nodes.size()); | ||||
|     } | ||||
|      | ||||
|     void reset() { | ||||
|         dec_range_ref(m_nodes.begin(), m_nodes.end()); | ||||
|         dec_range_ref(m_nodes.data(), m_nodes.data() + m_nodes.size()); | ||||
|         m_nodes.reset(); | ||||
|     } | ||||
| 
 | ||||
|     void finalize() { | ||||
|         dec_range_ref(m_nodes.begin(), m_nodes.end()); | ||||
|         dec_range_ref(m_nodes.data(), m_nodes.data() + m_nodes.size()); | ||||
|         m_nodes.finalize(); | ||||
|     } | ||||
| 
 | ||||
|     void resize(unsigned sz) { | ||||
|         if (sz < m_nodes.size()) | ||||
|             dec_range_ref(m_nodes.begin() + sz, m_nodes.end()); | ||||
|             dec_range_ref(m_nodes.data() + sz, m_nodes.data() + m_nodes.size()); | ||||
|         m_nodes.resize(sz); | ||||
|     } | ||||
| 
 | ||||
|     void resize(unsigned sz, T * d) { | ||||
|         if (sz < m_nodes.size()) { | ||||
|             dec_range_ref(m_nodes.begin() + sz, m_nodes.end()); | ||||
|             dec_range_ref(m_nodes.data() + sz, m_nodes.data() + m_nodes.size()); | ||||
|             m_nodes.shrink(sz);  | ||||
|         } | ||||
|         else { | ||||
|  | @ -130,11 +130,11 @@ public: | |||
| 
 | ||||
|     T * get(unsigned idx, T * d) const { return m_nodes.get(idx, d); } | ||||
| 
 | ||||
|     T * const * data() const { return m_nodes.begin(); } | ||||
|     T * const * data() const { return m_nodes.data(); } | ||||
| 
 | ||||
|     typedef T* const* iterator; | ||||
| 
 | ||||
|     T ** data() { return m_nodes.begin(); } | ||||
|     T ** data() { return m_nodes.data(); } | ||||
| 
 | ||||
|     unsigned hash() const { | ||||
|         unsigned sz = size(); | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ public: | |||
|     } | ||||
| 
 | ||||
|     void reset() { | ||||
|         unsigned sz = this->size(); | ||||
|         auto sz = this->size(); | ||||
|         for (unsigned i = 0; i < sz; i++) { | ||||
|             m().del(this->operator[](i)); | ||||
|         } | ||||
|  |  | |||
|  | @ -80,7 +80,7 @@ public: | |||
| 
 | ||||
|     // Insert in the this object the elements in the set source.
 | ||||
|     uint_set & operator |=(const uint_set & source) { | ||||
|         unsigned source_size = source.size(); | ||||
|         auto source_size = source.size(); | ||||
|         if (source_size > size()) { | ||||
|             resize(source_size + 1); | ||||
|         } | ||||
|  | @ -91,7 +91,7 @@ public: | |||
|     } | ||||
| 
 | ||||
|     uint_set& operator &=(const uint_set& source) { | ||||
|         unsigned source_size = source.size(); | ||||
|         auto source_size = source.size(); | ||||
|         if (source_size < size()) { | ||||
|             resize(source_size); | ||||
|         } | ||||
|  | @ -102,7 +102,7 @@ public: | |||
|     } | ||||
| 
 | ||||
|     bool operator==(const uint_set & source) const { | ||||
|         unsigned min_size = size(); | ||||
|         auto min_size = size(); | ||||
|         if (source.size() < min_size) { | ||||
|             min_size = source.size(); | ||||
|         } | ||||
|  | @ -111,12 +111,12 @@ public: | |||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         for (unsigned i = min_size; i < size(); ++i) { | ||||
|         for (auto i = min_size; i < size(); ++i) { | ||||
|             if ((*this)[i]) { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         for (unsigned i = min_size; i < source.size(); ++i) { | ||||
|         for (auto i = min_size; i < source.size(); ++i) { | ||||
|             if (source[i]) { | ||||
|                 return false; | ||||
|             } | ||||
|  | @ -131,7 +131,7 @@ public: | |||
| 
 | ||||
|     // Return true if the this set is a subset of source.
 | ||||
|     bool subset_of(const uint_set & source) const { | ||||
|         unsigned min_size = size(); | ||||
|         auto min_size = size(); | ||||
|         if (source.size() < min_size) { | ||||
|             min_size = source.size(); | ||||
|         } | ||||
|  | @ -140,7 +140,7 @@ public: | |||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         for (unsigned i = min_size; i < size(); ++i) { | ||||
|         for (auto i = min_size; i < size(); ++i) { | ||||
|             if ((*this)[i]) { | ||||
|                 return false; | ||||
|             } | ||||
|  | @ -252,7 +252,7 @@ public: | |||
|     void remove(unsigned v) { | ||||
|         if (contains(v)) { | ||||
|             m_in_set[v] = false; | ||||
|             unsigned i = m_set.size(); | ||||
|             auto i = m_set.size(); | ||||
|             for (; i > 0 && m_set[--i] != v; )  | ||||
|                 ; | ||||
|             SASSERT(m_set[i] == v); | ||||
|  | @ -282,7 +282,7 @@ public: | |||
|     iterator end() const { return m_set.end(); } | ||||
|     // void reset() { m_set.reset(); m_in_set.reset(); }
 | ||||
|     void reset() {  | ||||
|         unsigned sz = m_set.size(); | ||||
|         auto sz = m_set.size(); | ||||
|         for (unsigned i = 0; i < sz; ++i) m_in_set[m_set[i]] = false; | ||||
|         m_set.reset();  | ||||
|     } | ||||
|  |  | |||
|  | @ -134,6 +134,14 @@ public: | |||
|         CASSERT("union_find", check_invariant()); | ||||
|     } | ||||
| 
 | ||||
|     void set_root(unsigned v, unsigned root) { | ||||
|         TRACE("union_find", tout << "merging " << v << " " << root << "\n";); | ||||
|         SASSERT(v != root); | ||||
|         m_find[v] = root; | ||||
|         m_size[root] += m_size[v]; | ||||
|         std::swap(m_next[root], m_next[v]); | ||||
|     } | ||||
| 
 | ||||
|     // dissolve equivalence class of v
 | ||||
|     // this method cannot be used with backtracking.
 | ||||
|     void dissolve(unsigned v) { | ||||
|  |  | |||
|  | @ -40,6 +40,125 @@ Revision History: | |||
| #pragma warning(disable:4127) | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #if 0 | ||||
| 
 | ||||
| // portability guide to std::vector.
 | ||||
| // memory allocator should be based on memory_allocator<T>
 | ||||
| // 
 | ||||
| // template<typename T>
 | ||||
| // struct memory_allocator {
 | ||||
| //     typedef  T value_type;
 | ||||
| //     etc (interface seems to change between C++17, 20 versions)
 | ||||
| // };
 | ||||
| //
 | ||||
| 
 | ||||
| // Note:
 | ||||
| // polynomial.h contains declaration
 | ||||
| // typedef svector<numeral>                        numeral_vector;
 | ||||
| // it is crucial that it uses svector and not vector. The destructors on elements of the numeral vector are handled outside.
 | ||||
| // Numeral gets instantiated by mpz and mpz does not support copy constructors.
 | ||||
| // porting svector to vector is therefore blocked on the semantics of svector being 
 | ||||
| // copy-constructor free.
 | ||||
| // 
 | ||||
| 
 | ||||
| #include <vector> | ||||
| 
 | ||||
| template<typename T, bool CallDestructors=true, typename SZ = unsigned> | ||||
| class vector : public std::vector<T> { | ||||
| public: | ||||
|     typedef T data_t; | ||||
|     typedef typename std::vector<T>::iterator iterator; | ||||
| 
 | ||||
|     vector() {} | ||||
|     vector(SZ s) { | ||||
|         // TODO resize(s, T());
 | ||||
|     } | ||||
|     vector(SZ s, T const& e) { | ||||
|         // TODO resize(s, e);
 | ||||
|     } | ||||
| 
 | ||||
|     vector(SZ s, T const* e) { | ||||
|         // TODO
 | ||||
|     } | ||||
| 
 | ||||
|     void reset() { clear(); } | ||||
|     void finalize() { clear(); } | ||||
|     void reserve(SZ s, T const & d) { | ||||
|         if (s > size()) | ||||
|             resize(s, d); | ||||
|     } | ||||
|     void reserve(SZ s) { | ||||
|          | ||||
|     } | ||||
| 
 | ||||
|     void setx(SZ idx, T const & elem, T const & d) { | ||||
|         if (idx >= size())  | ||||
|             resize(idx+1, d); | ||||
|         (*this)[idx] = elem; | ||||
|     } | ||||
| 
 | ||||
|     T const & get(SZ idx, T const & d) const { | ||||
|         if (idx >= size()) { | ||||
|             return d; | ||||
|         } | ||||
|         return (*this)[idx]; | ||||
|     } | ||||
| 
 | ||||
|     void insert(T const & elem) { | ||||
|         push_back(elem); | ||||
|     } | ||||
|      | ||||
|     void erase(iterator pos) { | ||||
|         // TODO
 | ||||
|     } | ||||
| 
 | ||||
|     void erase(T const& e) { | ||||
|         // TODO
 | ||||
|     } | ||||
|     void fill(T const & elem) { | ||||
|         for (auto& e : *this) | ||||
|             e = elem; | ||||
|     } | ||||
| 
 | ||||
|     void fill(unsigned sz, T const & elem) { | ||||
|         resize(sz); | ||||
|         fill(elem); | ||||
|     } | ||||
| 
 | ||||
|     void shrink(SZ s) { | ||||
|         resize(s); | ||||
|     } | ||||
|     void reverse() { | ||||
|         SZ sz = size(); | ||||
|         for (SZ i = 0; i < sz/2; ++i) { | ||||
|             std::swap((*this)[i], (*this)[sz-i-1]); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void append(vector<T, CallDestructors> const & other) { | ||||
|         for(SZ i = 0; i < other.size(); ++i) { | ||||
|             push_back(other[i]); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void append(unsigned n,  T const* elems) { | ||||
|         // TODO
 | ||||
|     } | ||||
| 
 | ||||
|     bool contains(T const & elem) const { | ||||
|         for (auto const& e : *this) | ||||
|             if (e == elem) | ||||
|                 return true; | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|      | ||||
| };  | ||||
| 
 | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| template<typename T, bool CallDestructors=true, typename SZ = unsigned> | ||||
| class vector { | ||||
| #define SIZE_IDX     -1 | ||||
|  | @ -602,6 +721,8 @@ public: | |||
| 
 | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| template<typename T> | ||||
| class ptr_vector : public vector<T *, false> { | ||||
| public: | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue