diff --git a/.clang-format b/.clang-format index 7014a740..75b0046f 100644 --- a/.clang-format +++ b/.clang-format @@ -1,44 +1,28 @@ ---- -IndentWidth: 4 ---- -# Specify Language -Language: Cpp +BasedOnStyle: Google -# ___ Short statement ___ -# "if (a) return"; can be put on a single line. -AllowShortIfStatementsOnASingleLine: AllIfsAndElse +IndentWidth: 4 +# no column limit +ColumnLimit: 0 -# If "true", "while (true) continue"; can be put on a single line. -AllowShortLoopsOnASingleLine: true +AlignTrailingComments: true +AlignAfterOpenBracket: true +IndentRequires: false -# int f() { return 0; } can be put on a single line. -AllowShortFunctionsOnASingleLine: Inline +# puts public, private, on the same column with class definition +AccessModifierOffset: -4 -# ___ Align ___ -# Horizontally aligns arguments after an open bracket. -AlignAfterOpenBracket: Align +PackConstructorInitializers: BinPack -# Align consecutive declarations -AlignConsecutiveDeclarations: - Enabled: true - AcrossComments: true - Consecutive: true +# "if (a) return"; can be put on a single line. +AllowShortIfStatementsOnASingleLine: AllIfsAndElse # Align consecutive assignments. AlignConsecutiveAssignments: Consecutive -# The return type of the function on its own line. -AlwaysBreakAfterDefinitionReturnType: TopLevel - -# The column limit. -ColumnLimit: 80 +# Enum Style +AllowShortEnumsOnASingleLine: true -# Extern and Class indent setting -BreakBeforeBraces: Custom -BraceWrapping: - AfterExternBlock: true - AfterClass: true - AfterEnum: true +# Indent extern "C" block +IndentExternBlock: Indent -IndentAccessModifiers: true -PointerAlignment: Left +AlignArrayOfStructures: Left diff --git a/.cmake-format.yaml b/.cmake-format.yaml new file mode 100644 index 00000000..9e09140f --- /dev/null +++ b/.cmake-format.yaml @@ -0,0 +1,8 @@ +# Specify line width for formatting +line_width: 100 + +# Indentation settings +indent_width: 8 +continuation_indent_width: 8 +tab_size: 4 +use_tab: false diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index f08378c4..a293b103 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -1,32 +1,50 @@ name: Build(Linux) on: - push: - branches: [ "main","develop"] - pull_request: - branches: [ "main","develop"] + push: + branches: ["main", "develop"] + pull_request: + branches: ["main", "develop"] jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 - - name: Modify INSTALL.sh - run: | - sed -i "s/.\/gv;//g" ./INSTALL.sh - - - name: Install Dependencies - shell: bash - run: | - sudo apt-get update - sudo apt-get install gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev + - name: Cache CMake dependency source code + uses: actions/cache@v3 + env: + cache-name: cache-cmake-engine-sources + with: + # CMake cache is at ${{github.workspace}}/build/_deps but we only will cache folders ending in '-src' to cache source code + path: ${{github.workspace}}/build/engines/src/engine-* + # Cache hash is dependent on CMakeLists files anywhere as these can change what's in the cache, as well as cmake modules files + # key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('./CMakeLists.txt') }} + key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('./CMakeLists.txt') }} + # it's acceptable to reuse caches for different CMakeLists content if exact match is not available and unlike build caches, we + # don't need to restrict these by OS or compiler as it's only source code that's being cached + restore-keys: | + ${{ runner.os }}-${{ env.cache-name }}- + - name: Install Dependencies + shell: bash + run: | + ls + sudo apt-get update + sudo apt-get -y install gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev git cmake parallel + sudo apt-get -y install graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev - - name: Install GV - run: sudo ./INSTALL.sh + - name: Install GV + run: | + echo "Start to build the GV " + make build + - name: Install Yosys + working-directory: ${{github.workspace}}/build/engines/src/engine-yosys + run: | + echo "Start to install the Yosys" + sudo make install - - name: Check GV library - run: ldd ./gv - - name: Run tests - run: ./gv -f tests/test.dofile + - name: Run tests + shell: bash + run: make test diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index 49215914..b060e844 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -1,26 +1,50 @@ name: Build(MacOS) on: - push: - branches: [ "main","develop"] - pull_request: - branches: [ "main","develop"] + push: + branches: ["main", "develop"] + pull_request: + branches: ["main", "develop"] jobs: - build: - runs-on: macos-12 - steps: - - uses: actions/checkout@v3 + build: + runs-on: macos-latest + env: + ACTIONS_CACHE_DEBUG: true # Enable cache debug mode + steps: + - uses: actions/checkout@v3 - - name: Modify INSTALL.sh - run: | - sed -i -e "s/.\/gv;//g" ./INSTALL.sh - - - name: Install Dependencies - shell: bash - run: | - brew install bison flex gawk libffi pkg-config bash + - name: Cache CMake dependency source code + uses: actions/cache@v3 + env: + cache-name: cache-cmake-engine-sources + with: + # CMake cache is at ${{github.workspace}}/build/_deps but we only will cache folders ending in '-src' to cache source code + path: ${{github.workspace}}/build/engines/src/engine-* + # Cache hash is dependent on CMakeLists files anywhere as these can change what's in the cache, as well as cmake modules files + # key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('./CMakeLists.txt') }} + key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('./CMakeLists.txt') }} + # it's acceptable to reuse caches for different CMakeLists content if exact match is not available and unlike build caches, we + # don't need to restrict these by OS or compiler as it's only source code that's being cached + restore-keys: | + ${{ runner.os }}-${{ env.cache-name }}- - - name: Install GV - run: sudo ./INSTALL.sh + - name: Install Dependencies + shell: bash + run: brew tap Homebrew/bundle && brew bundle + + - name: Export the brew path + shell: bash + run: | + brew install bison + echo 'export PATH="$(brew --prefix bison)/bin:$PATH"' >> $GITHUB_ENV + # export PATH="$(brew --prefix bison)/bin:$(brew --prefix)/bin:$PATH" + + - name: Verify the brew path + shell: bash + run: bison --version + + # - name: Install GV + # run: make + # + # - name: Run tests + # run: make test - - name: Run tests - run: ./gv -f tests/test.dofile diff --git a/.gitignore b/.gitignore index 6d3150bc..d774817a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,46 @@ -/src/lib/*.a -/src/lib/*.so -/src/lib/lib.d - -/engine -/include -*.o -*.d -*.a -/gv -/lib -btorinfo.log -test.btor -*.dofile -*.v -*.btor +# engine files and folders +engine/ +# static library files +lib/ +# headers files +include/ + + +# makefile files +src/*/*.mak +# cmake files +build/ +# object files +src/*/*.o +# yosys extension files +src/ext/*.so +src/ext/*.d + +# yosys execution files +yosys-abc +yosys-config + +# vscode configuration files and folders +.vscode/ + +# vim configuration files and folders +.cache/ +compile_commands.json + +# simulation files +.sim_main.cpp +.sim.cpp +.tb + +# design and log files *.aig -.vscode +*.v +*.txt +*.json +*.history + +# gv +gv +# debugging files +debug.dofile \ No newline at end of file diff --git a/Brewfile b/Brewfile new file mode 100644 index 00000000..f03f16fc --- /dev/null +++ b/Brewfile @@ -0,0 +1,15 @@ +brew "bison" +brew "flex" +brew "gawk" +brew "libffi" +brew "git" +brew "graphviz" +brew "pkg-config" +brew "python3" +brew "tcl-tk" +brew "xdot" +brew "bash" +brew "boost-python3" +brew "llvm" +brew "gmp" +brew "parallel" diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..d0905a69 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,242 @@ +cmake_minimum_required(VERSION 3.19) + +# * Macro to exclude the directory from source +function(EXCLUDE_FROM_LIST REMOVE_LIST TARGET_LIST) + message(STATUS "Exclude the directory - ${${REMOVE_LIST}}") + foreach(REMOVE_DIR ${${REMOVE_LIST}}) + foreach(TMP_PATH ${${TARGET_LIST}}) + string(FIND ${TMP_PATH} ${REMOVE_DIR} EXCLUDE_DIR_FOUND) + if(NOT ${EXCLUDE_DIR_FOUND} EQUAL -1) + message("Removing ${TMP_PATH}") + # list(REMOVE_ITEM TARGET_LIST ${TMP_PATH}) + list(REMOVE_ITEM ${TARGET_LIST} ${TMP_PATH}) + endif() + endforeach(TMP_PATH) + endforeach(REMOVE_DIR) + # message(STATUS ${${TARGET_LIST}}) + set(${TARGET_LIST} + ${${TARGET_LIST}} + PARENT_SCOPE) +endfunction() + +# * Debug config +# * set(CMAKE_VERBOSE_MAKEFILE on) +# * set_property(GLOBAL PROPERTY GLOBAL_DEPENDS_DEBUG_MODE 1) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +set(CMAKE_CXX_FLAGS "") +set(CMAKE_CXX_FLAGS_DEBUG "-g") +set(CMAKE_CXX_FLAGS_RELEASE "-O3") + +include(ExternalProject) +include(FetchContent) + +project( + gv + LANGUAGES CXX + VERSION 0.3.0) + +# * Git clokne the ABC repo at build time +# * Run the BUILD_COMMAND "make libabc.a" for creating the ABC static library +set(LIBABC_NAME libabc.a) +ExternalProject_Add( + engine-abc + GIT_REPOSITORY https://github.com/berkeley-abc/abc.git + GIT_TAG 6ca7eab + GIT_PROGRESS TRUE + PREFIX engines + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + INSTALL_COMMAND "" + UPDATE_COMMAND "" + UPDATE_DISCONNECTED TRUE + BUILD_COMMAND $(MAKE) ${LIBABC_NAME} + LOG_CONFIGURE ON + LOG_INSTALL ON + # LOG_BUILD ON +) +ExternalProject_Get_Property(engine-abc SOURCE_DIR) +set(ABC_DIR ${SOURCE_DIR}) +set(LIBABC_PATH ${ABC_DIR}/libabc.a) +add_library(libabc STATIC IMPORTED) +set_target_properties(libabc PROPERTIES IMPORTED_LOCATION ${LIBABC_PATH}) + +# * Git clone the Yosys repo at build time +# * Run the PATCH_COMMAND for applying the modification for yosys (patches/yosys.patch) +# * Run the BUILD_COMMAND "make libyosys.so" for creating the Yosys shared lib +set(PATCH_DIR ${CMAKE_SOURCE_DIR}/patches) +set(YOSYS_PATCH_CMAKE yosys_patch.cmake) +set(LIBYOSYS_NAME libyosys.so) +ExternalProject_Add( + engine-yosys + GIT_REPOSITORY https://github.com/YosysHQ/yosys.git + GIT_TAG yosys-0.35 + GIT_PROGRESS TRUE + PREFIX engines + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + INSTALL_COMMAND "" + UPDATE_COMMAND "" + UPDATE_DISCONNECTED TRUE + PATCH_COMMAND ${CMAKE_COMMAND} -P ${PATCH_DIR}/${YOSYS_PATCH_CMAKE} + BUILD_COMMAND $(MAKE) ${LIBYOSYS_NAME} + LOG_CONFIGURE ON + LOG_INSTALL ON + # LOG_BUILD ON +) +ExternalProject_Get_Property(engine-yosys SOURCE_DIR) +set(YOSYS_DIR ${SOURCE_DIR}) +set(LIBYOSYS_PATH ${YOSYS_DIR}/libyosys.so) +add_library(libyosys SHARED IMPORTED) +set_target_properties(libyosys PROPERTIES IMPORTED_LOCATION ${LIBYOSYS_PATH}) + +# * Git clone the Verilog-VCD-Parser repo at build time +set(LIB_VCD_PARSER_NAME libverilog-vcd-parser.a) +set(VCD_PARSER_PATCH_CMAKE vcd_parser_patch.cmake) +ExternalProject_Add( + vcd-parser + GIT_REPOSITORY https://github.com/ben-marshall/verilog-vcd-parser.git + # GIT_TAG yosys-0.35 + GIT_PROGRESS TRUE + PREFIX engines + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + INSTALL_COMMAND "" + UPDATE_COMMAND "" + UPDATE_DISCONNECTED TRUE + PATCH_COMMAND ${CMAKE_COMMAND} -P ${PATCH_DIR}/${VCD_PARSER_PATCH_CMAKE} + BUILD_COMMAND $(MAKE) all + LOG_CONFIGURE ON + LOG_INSTALL ON + # LOG_BUILD ON +) +ExternalProject_Get_Property(vcd-parser SOURCE_DIR) +set(VCD_PARSER_DIR ${SOURCE_DIR}) +set(LIB_VCD_PARSER_PATH ${VCD_PARSER_DIR}/build/libverilog-vcd-parser.a) +add_library(libvcd-parser STATIC IMPORTED) +set_target_properties(libvcd-parser PROPERTIES IMPORTED_LOCATION ${LIB_VCD_PARSER_PATH}) + +# * FMT Library +FetchContent_Declare( + fmt + GIT_REPOSITORY https://github.com/fmtlib/fmt.git + GIT_TAG 10.2.1) +FetchContent_MakeAvailable(fmt) + +# * Glucose +FetchContent_Declare( + glucose + GIT_REPOSITORY https://github.com/audemard/glucose.git + GIT_TAG 4.2.1) +FetchContent_MakeAvailable(glucose) + +# Link the library installed by brew +if(APPLE) + link_directories(/opt/homebrew/lib) + link_directories(/usr/local/opt/gmp/lib) +endif() +# Link the Yosys shared libray path +link_directories(${YOSYS_DIR}) + +# Set the install rpath to the YOSYS_DIR +set(CMAKE_MACOSX_RPATH TRUE) +set(CMAKE_INSTALL_RPATH "${YOSYS_DIR}") + +# Collect all the cpp and header files under src/ +file( + GLOB_RECURSE SOURCES + RELATIVE ${CMAKE_SOURCE_DIR} + "src/*/*.cpp" "src/*/*.h" "${CMAKE_SOURCE_DIR}/satsolvers/minisat/*") +# * Exlcude the src/verilator/** from SOURCES +# * list(APPEND EXCLUDE_DIR "verilator") +# * exclude_from_list(EXCLUDE_DIR SOURCES) +add_executable(${CMAKE_PROJECT_NAME} ${SOURCES}) + +# Add the definitions for ABC +add_compile_definitions(ABC_USE_STDINT_H) +# Add the definitions for Yosys +add_compile_definitions(_YOSYS_) +# Add the definitions for Yosys Extension add_compile_definitions(GV_SIMSO_PATH="src/ext/") +add_compile_definitions(GV_PATH="${CMAKE_SOURCE_DIR}/") +add_compile_definitions(GV_SIMSO_PATH="${CMAKE_SOURCE_DIR}/build/src/ext/") +add_compile_definitions(GV_TEMPLATE_PATH="${CMAKE_SOURCE_DIR}/simulators/verilator/template/") +add_compile_definitions(GV_VERILATOR_PATH="${CMAKE_SOURCE_DIR}/simulators/verilator/") +add_compile_definitions(GV_VERILATOR_BUILD_PATH="${CMAKE_SOURCE_DIR}/simulators/verilator/build/") +add_compile_definitions(GV_CXXRTL_PATH="${CMAKE_SOURCE_DIR}/simulators/cxxrtl/") +# target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE) +# target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE -Wall -Wextra) +target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE -w) + +# g++ is being too paranoid about missing field initializers +if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") + target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE -Wno-missing-field-initializers) +endif() + +file( + GLOB SRC_DIR + RELATIVE ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/* ${CMAKE_SOURCE_DIR}/src/*/*) + +# Include all header files under the src/*/ and src/*/*/ +foreach(DIR ${SRC_DIR}) + if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/${DIR}) + target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/${DIR}) + endif() +endforeach() +# Include all the header files under the engine Yosys +target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${YOSYS_DIR}) +target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${YOSYS_DIR}) +# Include all the header files under the engine ABC +target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${ABC_DIR}/src) +# Include the readline header files +target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE /usr/include/readline) +# Include the gmp header files +target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE /usr/local/include) +# Include the VCD parser header files +target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${VCD_PARSER_DIR}/build) +# Include the Glucose header files +# message(FATAL_ERROR ${glucose_SOURCE_DIR}/core) +target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${glucose_SOURCE_DIR}) +# Include the satsolver directory +target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/satsolvers) + +# target_link_libraries(${CMAKE_PROJECT_NAME} libabc libyosys readline gmp) +target_link_libraries(${CMAKE_PROJECT_NAME} libabc readline gmp) +target_link_libraries(${CMAKE_PROJECT_NAME} ${LIBYOSYS_PATH}) +# * Link the filesystem library +# target_link_libraries(${CMAKE_PROJECT_NAME} stdc++fs) +# * Link the verilog-vcd-parser library +target_link_libraries(${CMAKE_PROJECT_NAME} libvcd-parser) +# * Link the fmt library +target_link_libraries(${CMAKE_PROJECT_NAME} fmt::fmt) +# * Link the glucose library +target_link_libraries(${CMAKE_PROJECT_NAME} glucose) + +# Add the Yosys extension CMake file +set(YOSYS_PLUGIN_PATH src/ext/) +add_subdirectory(${YOSYS_PLUGIN_PATH}) + +# Allow GV to be built only after all steps in the External project are completed +add_dependencies(${CMAKE_PROJECT_NAME} engine-yosys) +add_dependencies(${CMAKE_PROJECT_NAME} engine-abc) +add_dependencies(${CMAKE_PROJECT_NAME} vcd-parser) + +install(TARGETS ${CMAKE_PROJECT_NAME} DESTINATION) + +# default to ON +option(SYMBLINK_EXECUTABLE " Symbolic link executable to project root" ON) +if(SYMBLINK_EXECUTABLE) + add_custom_command( + TARGET ${CMAKE_PROJECT_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E create_symlink $ + ${CMAKE_SOURCE_DIR}/${CMAKE_PROJECT_NAME} + COMMENT " Symbolic link executable to ${CMAKE_SOURCE_DIR}/${CMAKE_PROJECT_NAME}") +endif() diff --git a/INSTALL.sh b/INSTALL.sh deleted file mode 100755 index 2b6077da..00000000 --- a/INSTALL.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# go to engine/ -cd engine/ - -# install "abc" -./abc.script -# install "yosys" -./yosys.script -# install "boolector" -./boolector.script - -# back to gv0/ -cd ../ - -# make GV -make diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 index e3d0cb59..0990f7e0 --- a/Makefile +++ b/Makefile @@ -1,96 +1,37 @@ -SRCPKGS = util cmd mod abc bdd itp ntk cir sim vrf ext prove -LIBPKGS = util cmd mod abc bdd itp ntk cir sim vrf prove +all: build -MAIN = main +build: + cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=1 + $(MAKE) -C build -j 8 --no-print-directory -EXTLIBS = -lm -lz -lreadline -ltermcap -ldl -lstdc++ -ltcl -lffi -lgmp -SRCLIBS = $(addprefix -l, $(LIBPKGS)) $(addprefix -l, $(ENGPKGS)) +release: + cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_BUILD_TYPE=Release + $(MAKE) -C build -j 8 --no-print-directory +# force macos to use the clang++ installed by brew instead of the default one +# which is outdated +# build-clang++: +# cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=1 $(shell which clang++) +# $(MAKE) -C build -#ENGPKGS += quteRTL -ENGPKGS += boolector -ENGPKGS += lgl -ENGPKGS += btor2parser -#ENGPKGS += minisat -ENGPKGS += abcc -ENGPKGS += yosys +# run all tests with current gv binary at the root of the project +# use ./scripts/RUN_TESTS to run tests with specific dofiles +test: + ./scripts/RUN_TEST -v -ENGSSRC = eng +test-full: + ./scripts/RUN_TEST -v -f -EXEC = gv -.PHONY : all debug +test-update: + ./scripts/RUN_TEST -u -all : EXEC = gv -debug : EXEC = gv.debug +debug: + cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_BUILD_TYPE=Debug + $(MAKE) -C build -j 8 -all: DEBUG_FLAG = -debug:DEBUG_FLAG = -DGV_DEBUG +clean: + cmake --build build --target clean + rm -rf bin +# rm -rf build -LIB = libgv.a - - -all debug: srcLib - @echo "Checking $(MAIN)..." - @cd src/$(MAIN); make --no-print-directory EXTLIB="$(SRCLIBS) $(EXTLIBS)" EXEC=$(EXEC); cd ../.. ; - -srcLib: engLib - @cd include; ln -fs ../src/*/*.h ./; - @for pkg in $(SRCPKGS); \ - do \ - echo "Checking $$pkg..."; \ - cd src/$$pkg; make --no-print-directory DEBUG_FLAG=$(DEBUG_FLAG) PKGNAME=$$pkg || exit; \ - cd ../.. ; \ - done - -engLib: - @for pkg in $(ENGPKGS); \ - do \ - cd include ; ln -fs ../src/$(ENGSSRC)/$$pkg/* .; cd .. ; \ - cd lib ; ln -fs ../src/$(ENGSSRC)/$$pkg/*.a .; ln -fs ../src/$(ENGSSRC)/$$pkg/*.so .; cd .. ; \ - done - @rm -f include/*.a - -main: - @echo "Checking $(MAIN)..." - @cd src/$(MAIN); \ - make --no-print-directory EXTLIB="$(SRCLIBS) $(EXTLIBS)" EXEC=$(EXEC); - @ln -fs bin/$(EXEC) . -# @strip bin/$(EXEC) - -clean: - @for pkg in $(SRCPKGS); \ - do \ - echo "Cleaning $$pkg..."; \ - cd src/$$pkg; make --no-print-directory PKGNAME=$$pkg clean; \ - cd ../.. ; \ - done - @echo "Cleaning $(MAIN)..." - @cd src/$(MAIN); make --no-print-directory clean - @echo "Removing $(EXEC)..." - @rm -f $(EXEC) - -ctags: - @rm -f src/tags - @for pkg in $(SRCPKGS); \ - do \ - echo "Tagging $$pkg..."; \ - cd src; ctags -a $$pkg/*.cpp $$pkg/*.h; cd ..; \ - done - @echo "Tagging $(MAIN)..." - cd src; ctags -a $(MAIN)/*.cpp - @echo "Tagging $(GUI)..." - cd src; ctags -a $(GUI)/*.cpp - -rmdep: - @for pkg in $(SRCPKGS); \ - do \ - rm src/$$pkg/.*.mak; \ - done - @rm src/main/.*.mak; - -linux18 linux16 mac: - @for pkg in $(REFPKGS); \ - do \ - cd lib; ln -sf lib$$pkg-$@.a lib$$pkg.a; cd ../..; \ - done - @cd ref; ln -sf $(EXEC)-$@ $(EXEC); +.PHONY: all build build-clang++ test lint clean diff --git a/README.md b/README.md index 21e8471b..8a9373c0 100755 --- a/README.md +++ b/README.md @@ -1,43 +1,33 @@ # GV -- **GV** is a general-purposed verification framework (take version 0.0) - **GV** serves as the bridge between multiple engines, meaning that developers who require several engines can implement their algorithms using only **"GV"** # GV Installation -```json= -git clone git@github.com:ric2k1/gv0.git -cd gv0/ -./SETUP.sh -./INSTALL.sh +```bash= +git clone https://github.com/DVLab-NTU/gv.git +cd ./gv ``` -- **For using GV tool interface, type after installation:** -```json= -cd GV/ -./gv +## Install the dependencies +- for MacOS : +```bash= +brew tap Homebrew/bundle && brew bundle + +export PATH="$(brew --prefix)/bin:$PATH" ``` +- for linux : +```bash= +sudo apt-get -y install gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev git cmake parallel -# GV's Third-Party Tools -- **word-level** -> [yosys](https://github.com/YosysHQ/yosys) / [boolector](https://github.com/Boolector/boolector) -- **gate-level** -> [berkeley-abc](https://github.com/berkeley-abc/abc) -- **file format converter** -> yosys -- **formal verification engine** -> berkeley-abc -- **simulator** -> yosys +sudo apt-get -y install graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev +``` -# GV's Architecture -- **Parser** - - Read in DUV - - e.g. berkeley-abc (GIA, which is the improved data structure of AIG) -> convert into GV's AIG data structure - - e.g. yosys (RTL data structure) -> convert into GV's word-level data structure (TBD) -- **Engine** - - Wrap API from off-the-shelf engine - - e.g. [miniSAT](https://github.com/niklasso/minisat) -> SAT solver - - e.g. [RicBDD](https://github.com/ric2k1/RicBDD) -> BDD -- **Application** - - e.g. Engineering Change Order, Model Checking, Equivalence Checking -Screen Shot 2023-09-19 at 3 19 13 PM +## Compile +```bash= +make +``` -# GV's API & Tutorial -- For GV usage, please check the document in [gv0/doc/GV_tutorial.pdf](https://github.com/ric2k1/gv0/tree/main/doc) +- **For using GV tool interface, type after installation:** +```bash= +./gv +``` -# Develop on GV -- If one would like to develop features on GV, please check the document in [gv0/doc/README.md](https://github.com/ric2k1/gv0/tree/main/doc) diff --git a/SETUP.sh b/SETUP.sh deleted file mode 100755 index 0b7505c4..00000000 --- a/SETUP.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -# Install prerequisites for building yosys -sudo apt-get install gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev - -# Make install yosys -if [ -f "/usr/local/lib/yosys/libyosys.so" ]; then - echo "File /usr/local/lib/yosys/libyosys.so exists." -else - echo "File /usr/local/lib/yosys/libyosys.so does not exists." - cd engine/yosys; - sudo make install; -fi - -# Install GTKWave package -sudo apt-get install gtkwave; diff --git a/designs/Simulation/adder.v b/designs/Simulation/adder.v new file mode 100644 index 00000000..d1bc614e --- /dev/null +++ b/designs/Simulation/adder.v @@ -0,0 +1,18 @@ +module adder ( + input wire clk, + input wire rst, + input wire [3:0] a, + input wire [3:0] b, + output reg [4:0] sum +); + +always @(posedge clk) begin + if (!rst) begin + sum <= 5'b00000; // Reset state + end + else begin + sum <= a + b; // Add a and b when not in reset + end +end + +endmodule diff --git a/designs/Simulation/adder_input.pattern b/designs/Simulation/adder_input.pattern new file mode 100644 index 00000000..63153946 --- /dev/null +++ b/designs/Simulation/adder_input.pattern @@ -0,0 +1,6 @@ +00001111 +01010101 +01110111 +11011011 +10110111 +01010001 diff --git a/designs/Simulation/alu.v b/designs/Simulation/alu.v new file mode 100644 index 00000000..a58ae59f --- /dev/null +++ b/designs/Simulation/alu.v @@ -0,0 +1,133 @@ +module alu #( + parameter INT_W = 3, + parameter FRAC_W = 5, + parameter INST_W = 3, + parameter DATA_W = INT_W + FRAC_W +)( + input i_clk, + input i_rst_n, + input i_valid, + input signed [DATA_W-1:0] i_data_a, + input signed [DATA_W-1:0] i_data_b, + input [INST_W-1:0] i_inst, + output o_valid, + output [DATA_W-1:0] o_data +); + +// ref: Tony Tony (score 100) +// FIXME: I only put my bug code at "i_inst = 110" + +// --------------------------------------------------------------------------- +// Wires and Registers +// --------------------------------------------------------------------------- +reg [DATA_W:0] o_data_w, o_data_r; +reg o_valid_w, o_valid_r; +reg signed [(DATA_W + DATA_W):0] temp_multiply; +reg [DATA_W-1:0] mod_reg; +// ---- Add your own wires and registers here if needed ---- // + + +// --------------------------------------------------------------------------- +// Continuous Assignment +// --------------------------------------------------------------------------- +assign o_valid = o_valid_r; +assign o_data = o_data_r; +// ---- Add your own wire data assignments here if needed ---- // + + +// --------------------------------------------------------------------------- +// Combinational Blocks +// --------------------------------------------------------------------------- +// ---- Write your combinational block design here ---- // +always@(*) begin + o_valid_w = 1'b0; + if(i_valid) begin + case(i_inst) + 3'b000: begin// signed addition + o_data_w = i_data_a + i_data_b; + if(i_data_a[DATA_W-1] == 1'b0 && i_data_b[DATA_W-1] == 1'b0 && o_data_w[DATA_W-1] == 1'b1) begin + o_data_w = 9'b001111111; + end + else if(i_data_a[DATA_W-1] == 1'b1 && i_data_b[DATA_W-1] == 1'b1 && o_data_w[DATA_W-1] == 1'b0) begin + o_data_w = 9'b010000000; + end + end + 3'b001: begin// signed subtraction + o_data_w = i_data_a - i_data_b; + if(i_data_a[DATA_W-1] == 1'b0 && i_data_b[DATA_W-1] == 1'b1 && o_data_w[DATA_W-1] == 1'b1) begin + o_data_w = 9'b001111111; + end + else if(i_data_a[DATA_W-1] == 1'b1 && i_data_b[DATA_W-1] == 1'b0 && o_data_w[DATA_W-1] == 1'b0) begin + o_data_w = 9'b010000000; + end + end + 3'b010: begin// signed multiplication + temp_multiply = $signed(i_data_a) * $signed(i_data_b); + if(temp_multiply[FRAC_W-1] == 1'd1) begin + if ((temp_multiply[(DATA_W + DATA_W)] == 1'd0) || ((temp_multiply[(DATA_W + DATA_W)] == 1'd1) && (temp_multiply[FRAC_W-2:0] != 0))) begin + temp_multiply = temp_multiply +5'b10000; + end + end + if($signed(temp_multiply[(DATA_W + DATA_W):FRAC_W]) > $signed(8'b01111111)) begin + o_data_w = 9'b001111111; + end + else if($signed(temp_multiply[(DATA_W + DATA_W):FRAC_W]) < $signed(8'b10000000)) begin + o_data_w = 9'b010000000; + end + else begin + o_data_w = temp_multiply[(DATA_W + DATA_W):FRAC_W]; + end + end + 3'b011: begin// NAND + o_data_w = ~(i_data_a & i_data_b); + end + 3'b100: begin// XNOR + o_data_w = ~(i_data_a ^ i_data_b); + end + 3'b101: begin// Sigmoid + if(i_data_a >= $signed(8'b01000000))begin + o_data_w = 9'b000100000; + end + else if(i_data_a <= $signed(8'b11000000)) begin + o_data_w = 9'b000000000; + end + else begin// 1/4x+1/2 + // o_data_w = {1'b0, (i_data_a >>> 2) + $signed(8'b00010000)}; // FIXME: golden -> arithmetic right shift (pad with sign bit) + o_data_w = {1'b0, (i_data_a >> 2) + $signed(8'b00010000)}; // FIXME: bug -> logical right shift (pad with 0s) + end + end + 3'b110: begin// Right Circular Shift + mod_reg = $unsigned(i_data_b) % (DATA_W); + if (mod_reg == 0) begin + o_data_w = i_data_a; + end + else begin + o_data_w = ({8'b0, i_data_a} >> mod_reg) | ({8'b0, i_data_a} << (DATA_W-mod_reg)); + end + o_valid_w = 1; + end + 3'b111: begin// Min + o_data_w = {1'b0, ((i_data_a < i_data_b) ? i_data_a : i_data_b)}; + end + default: begin + o_data_w = o_data_r; + end + endcase + o_valid_w = 1'b1; + end +end + +// --------------------------------------------------------------------------- +// Sequential Block +// --------------------------------------------------------------------------- +// ---- Write your sequential block design here ---- // +always@(posedge i_clk or negedge i_rst_n) begin + if(!i_rst_n) begin + o_data_r <= 0; + o_valid_r <= 0; + end else begin + o_data_r <= o_data_w; + o_valid_r <= o_valid_w; + end +end +endmodule diff --git a/designs/Simulation/alu_input.pattern b/designs/Simulation/alu_input.pattern new file mode 100644 index 00000000..a27834db --- /dev/null +++ b/designs/Simulation/alu_input.pattern @@ -0,0 +1,10 @@ +00011001000000111101 +00001100110101110111 +00000011110100100111 +00001011000000001011 +00011101011001111011 +00011001111111011111 +00000011001111101111 +00000010000011111111 +00001010000011100001 +00010111111101001011 diff --git a/designs/Simulation/and.v b/designs/Simulation/and.v new file mode 100644 index 00000000..6e776cbb --- /dev/null +++ b/designs/Simulation/and.v @@ -0,0 +1,9 @@ +module and_gate (a, b, o); + +input a; +input b; +output o; + +assign o = a & b; + +endmodule \ No newline at end of file diff --git a/designs/Simulation/arbiter2.v b/designs/Simulation/arbiter2.v new file mode 100644 index 00000000..6936fe4a --- /dev/null +++ b/designs/Simulation/arbiter2.v @@ -0,0 +1,22 @@ +module arbiter2(clk, rst, req1, req2, gnt1, gnt2); + input clk, rst; + input req1, req2; + output gnt1, gnt2; + reg state; + reg gnt1, gnt2; + always @(posedge clk or posedge rst) begin + if (rst) state <= 0; + else state <= gnt1; + end + always @(*) begin + if (state) begin + gnt1 = req1; // bug + // gnt1 = req1 & ~req2; // golden + gnt2 = req2; + end + else begin + gnt1 = req1; + gnt2 = req2 & ~req1; + end + end +endmodule \ No newline at end of file diff --git a/design/SoCV/vending/vending-origin.v b/designs/Simulation/vending-origin.v similarity index 100% rename from design/SoCV/vending/vending-origin.v rename to designs/Simulation/vending-origin.v diff --git a/design/SoCV/vending/vending-simple.v b/designs/Simulation/vending-simple.v similarity index 100% rename from design/SoCV/vending/vending-simple.v rename to designs/Simulation/vending-simple.v diff --git a/designs/Simulation/vending_input.pattern b/designs/Simulation/vending_input.pattern new file mode 100644 index 00000000..ab78d581 --- /dev/null +++ b/designs/Simulation/vending_input.pattern @@ -0,0 +1,33 @@ +XXXXXXXXXX +0100000100 +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +1000000001 +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +1110110100 +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX +00XXXXXXXX diff --git a/design/SoCV/basic/a.v b/designs/SoCV/basic/a.v similarity index 100% rename from design/SoCV/basic/a.v rename to designs/SoCV/basic/a.v diff --git a/design/SoCV/basic/b.v b/designs/SoCV/basic/b.v similarity index 100% rename from design/SoCV/basic/b.v rename to designs/SoCV/basic/b.v diff --git a/design/SoCV/basic/c.v b/designs/SoCV/basic/c.v similarity index 100% rename from design/SoCV/basic/c.v rename to designs/SoCV/basic/c.v diff --git a/design/SoCV/hwmcc/6s136.aig b/designs/SoCV/hwmcc/6s136.aig similarity index 100% rename from design/SoCV/hwmcc/6s136.aig rename to designs/SoCV/hwmcc/6s136.aig diff --git a/design/SoCV/hwmcc/6s206rb025.aig b/designs/SoCV/hwmcc/6s206rb025.aig similarity index 100% rename from design/SoCV/hwmcc/6s206rb025.aig rename to designs/SoCV/hwmcc/6s206rb025.aig diff --git a/design/SoCV/hwmcc/6s221rb18.aig b/designs/SoCV/hwmcc/6s221rb18.aig similarity index 100% rename from design/SoCV/hwmcc/6s221rb18.aig rename to designs/SoCV/hwmcc/6s221rb18.aig diff --git a/design/SoCV/hwmcc/6s307rb06.aig b/designs/SoCV/hwmcc/6s307rb06.aig similarity index 100% rename from design/SoCV/hwmcc/6s307rb06.aig rename to designs/SoCV/hwmcc/6s307rb06.aig diff --git a/design/SoCV/hwmcc/6s326rb02.aig b/designs/SoCV/hwmcc/6s326rb02.aig similarity index 100% rename from design/SoCV/hwmcc/6s326rb02.aig rename to designs/SoCV/hwmcc/6s326rb02.aig diff --git a/design/SoCV/hwmcc/6s327rb10.aig b/designs/SoCV/hwmcc/6s327rb10.aig similarity index 100% rename from design/SoCV/hwmcc/6s327rb10.aig rename to designs/SoCV/hwmcc/6s327rb10.aig diff --git a/design/SoCV/hwmcc/6s374b029.aig b/designs/SoCV/hwmcc/6s374b029.aig similarity index 100% rename from design/SoCV/hwmcc/6s374b029.aig rename to designs/SoCV/hwmcc/6s374b029.aig diff --git a/design/SoCV/hwmcc/6s380b129.aig b/designs/SoCV/hwmcc/6s380b129.aig similarity index 100% rename from design/SoCV/hwmcc/6s380b129.aig rename to designs/SoCV/hwmcc/6s380b129.aig diff --git a/design/SoCV/hwmcc/6s388b07.aig b/designs/SoCV/hwmcc/6s388b07.aig similarity index 100% rename from design/SoCV/hwmcc/6s388b07.aig rename to designs/SoCV/hwmcc/6s388b07.aig diff --git a/design/SoCV/hwmcc/6s6.aig b/designs/SoCV/hwmcc/6s6.aig similarity index 100% rename from design/SoCV/hwmcc/6s6.aig rename to designs/SoCV/hwmcc/6s6.aig diff --git a/design/SoCV/hwmcc/abp4pold.aig b/designs/SoCV/hwmcc/abp4pold.aig similarity index 100% rename from design/SoCV/hwmcc/abp4pold.aig rename to designs/SoCV/hwmcc/abp4pold.aig diff --git a/design/SoCV/hwmcc/bob9234spec7neg.aig b/designs/SoCV/hwmcc/bob9234spec7neg.aig similarity index 100% rename from design/SoCV/hwmcc/bob9234spec7neg.aig rename to designs/SoCV/hwmcc/bob9234spec7neg.aig diff --git a/design/SoCV/hwmcc/bobpci215.aig b/designs/SoCV/hwmcc/bobpci215.aig similarity index 100% rename from design/SoCV/hwmcc/bobpci215.aig rename to designs/SoCV/hwmcc/bobpci215.aig diff --git a/design/SoCV/hwmcc/pdtpmsfpmult.aig b/designs/SoCV/hwmcc/pdtpmsfpmult.aig similarity index 100% rename from design/SoCV/hwmcc/pdtpmsfpmult.aig rename to designs/SoCV/hwmcc/pdtpmsfpmult.aig diff --git a/design/SoCV/hwmcc/pj2018.aig b/designs/SoCV/hwmcc/pj2018.aig similarity index 100% rename from design/SoCV/hwmcc/pj2018.aig rename to designs/SoCV/hwmcc/pj2018.aig diff --git a/designs/SoCV/vending/input-Cex.pattern b/designs/SoCV/vending/input-Cex.pattern new file mode 100644 index 00000000..8f52e164 --- /dev/null +++ b/designs/SoCV/vending/input-Cex.pattern @@ -0,0 +1,40 @@ +1 0 0 0 0 +1 0 0 1 0 +1 1 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 +1 0 0 1 0 \ No newline at end of file diff --git a/design/V3/vending/vending.v b/designs/SoCV/vending/vending-origin.v similarity index 100% rename from design/V3/vending/vending.v rename to designs/SoCV/vending/vending-origin.v diff --git a/designs/SoCV/vending/vending-simple.v b/designs/SoCV/vending/vending-simple.v new file mode 100644 index 00000000..29822021 --- /dev/null +++ b/designs/SoCV/vending/vending-simple.v @@ -0,0 +1,289 @@ +/* + Source : vending/vending.v + Synopsis : Written by Cheng-Yin Wu for SoCV Assignments + Date : 2013/02/20 + Version : 1.0 + revised : Simplified by Chu Chen-Kai @ 2013/02/26 +*/ + +// Service Types +`define SERVICE_OFF 2'b00 +`define SERVICE_ON 2'b01 +`define SERVICE_BUSY 2'b10 +// Coin Types +`define NTD_50 2'b00 +`define NTD_10 2'b01 +`define NTD_5 2'b10 +`define NTD_1 2'b11 +// Coin Values +`define VALUE_NTD_50 8'd50 +`define VALUE_NTD_10 8'd10 +`define VALUE_NTD_5 8'd5 +`define VALUE_NTD_1 8'd1 +// Item Types +`define ITEM_NONE 2'b00 +`define ITEM_A 2'b01 +`define ITEM_B 2'b10 +`define ITEM_C 2'b11 +// Item Costs +`define COST_A 8'd8 +`define COST_B 8'd15 +`define COST_C 8'd22 + +module vendingMachine( + // Property Output Ports + p, + // General I/O Ports + clk, + reset, + // Input Ports + coinInNTD_50, + coinInNTD_10, + coinInNTD_5, + coinInNTD_1, + itemTypeIn, + // Output Ports + coinOutNTD_50, + coinOutNTD_10, + coinOutNTD_5, + coinOutNTD_1, + itemTypeOut, + serviceTypeOut +); + +// Property Output Ports +output p; +// General I/O Ports +input clk; +input reset; +// Input Ports +input [1:0] coinInNTD_50; // input number of NTD_50 +input [1:0] coinInNTD_10; // input number of NTD_10 +input [1:0] coinInNTD_5; // input number of NTD_5 +input [1:0] coinInNTD_1; // input number of NTD_1 +input [1:0] itemTypeIn; // type of an item +// Output Ports +output [2:0] coinOutNTD_50; // output number of NTD_50 +output [2:0] coinOutNTD_10; // output number of NTD_10 +output [2:0] coinOutNTD_5; // output number of NTD_5 +output [2:0] coinOutNTD_1; // output number of NTD_1 +output [1:0] itemTypeOut; // type of an item +output [1:0] serviceTypeOut; // type of the service + +reg [2:0] coinOutNTD_50; // output number of NTD_50 +reg [2:0] coinOutNTD_10; // output number of NTD_10 +reg [2:0] coinOutNTD_5; // output number of NTD_5 +reg [2:0] coinOutNTD_1; // output number of NTD_1 +reg [1:0] itemTypeOut; // type of an item +reg [1:0] serviceTypeOut; // type of the service + +reg [2:0] countNTD_50; // number of NTD_50 +reg [2:0] countNTD_10; // number of NTD_10 +reg [2:0] countNTD_5; // number of NTD_5 +reg [2:0] countNTD_1; // number of NTD_1 + +reg [7:0] inputValue; // total amount of input money +reg [7:0] serviceValue; // total amount of service money +reg [1:0] serviceCoinType; // type of the coin for the service +reg exchangeReady; // ready for exchange in BUSY +reg initialized; // initialized or not (i.e. reset) + +reg [2:0] coinOutNTD_50_w; // output number of NTD_50 +reg [2:0] coinOutNTD_10_w; // output number of NTD_10 +reg [2:0] coinOutNTD_5_w; // output number of NTD_5 +reg [2:0] coinOutNTD_1_w; // output number of NTD_1 +reg [1:0] itemTypeOut_w; // type of an item +reg [1:0] serviceTypeOut_w; // type of the service + +reg [2:0] countNTD_50_w; // number of NTD_50 +reg [2:0] countNTD_10_w; // number of NTD_10 +reg [2:0] countNTD_5_w; // number of NTD_5 +reg [2:0] countNTD_1_w; // number of NTD_1 + +reg [7:0] inputValue_w; // total amount of input money +reg [7:0] serviceValue_w; // total amount of service money +reg [1:0] serviceCoinType_w;// type of the coin for the service +reg exchangeReady_w; // ready for exchange in BUSY + +wire [7:0] outExchange; // the output exchange amount, for verification + +// Property Logic +/***** whether the change is right *****/ +assign p = initialized && (serviceTypeOut == `SERVICE_OFF) && (itemTypeOut == `ITEM_NONE) && (outExchange != inputValue); // catch the bug + +assign outExchange = (`VALUE_NTD_50 * {5'd0, coinOutNTD_50}) + + (`VALUE_NTD_10 * {5'd0, coinOutNTD_10}) + + (`VALUE_NTD_5 * {5'd0, coinOutNTD_5 }) + + (`VALUE_NTD_1 * {5'd0, coinOutNTD_1 }); + +always @ (*) begin + coinOutNTD_50_w = coinOutNTD_50; + coinOutNTD_10_w = coinOutNTD_10; + coinOutNTD_5_w = coinOutNTD_5; + coinOutNTD_1_w = coinOutNTD_1; + itemTypeOut_w = itemTypeOut; + serviceTypeOut_w = serviceTypeOut; + countNTD_50_w = countNTD_50; + countNTD_10_w = countNTD_10; + countNTD_5_w = countNTD_5; + countNTD_1_w = countNTD_1; + inputValue_w = inputValue; + serviceValue_w = serviceValue; + serviceCoinType_w = serviceCoinType; + exchangeReady_w = exchangeReady; + + case (serviceTypeOut) + `SERVICE_ON : begin + if (itemTypeIn != `ITEM_NONE) begin // valid request + coinOutNTD_50_w = 3'd0; + coinOutNTD_10_w = 3'd0; + coinOutNTD_5_w = 3'd0; + coinOutNTD_1_w = 3'd0; + itemTypeOut_w = itemTypeIn; + serviceTypeOut_w = `SERVICE_BUSY; + countNTD_50_w = (({1'b0, countNTD_50} + {2'd0, coinInNTD_50}) >= {1'b0, 3'b111}) ? + 3'b111 : (countNTD_50 + {1'b0, coinInNTD_50}); + countNTD_10_w = (({1'b0, countNTD_10} + {2'd0, coinInNTD_10}) >= {1'b0, 3'b111}) ? + 3'b111 : (countNTD_10 + {1'b0, coinInNTD_10}); + countNTD_5_w = (({1'b0, countNTD_5 } + {2'd0, coinInNTD_5 }) >= {1'b0, 3'b111}) ? + 3'b111 : (countNTD_5 + {1'b0, coinInNTD_5 }); + countNTD_1_w = (({1'b0, countNTD_1 } + {2'd0, coinInNTD_1 }) >= {1'b0, 3'b111}) ? + 3'b111 : (countNTD_1 + {1'b0, coinInNTD_1 }); + inputValue_w = (`VALUE_NTD_50 * {6'd0, coinInNTD_50}) + + (`VALUE_NTD_10 * {6'd0, coinInNTD_10}) + + (`VALUE_NTD_5 * {6'd0, coinInNTD_5 }) + + (`VALUE_NTD_1 * {6'd0, coinInNTD_1 }); + serviceValue_w = (itemTypeIn == `ITEM_A) ? `COST_A : + (itemTypeIn == `ITEM_B) ? `COST_B : + (itemTypeIn == `ITEM_C) ? `COST_C : 8'd0; + serviceCoinType_w = `NTD_50; + exchangeReady_w = 1'b0; + end + end + `SERVICE_OFF : begin // Output change and item + coinOutNTD_50_w = 3'd0; + coinOutNTD_10_w = 3'd0; + coinOutNTD_5_w = 3'd0; + coinOutNTD_1_w = 3'd0; + itemTypeOut_w = `ITEM_NONE; + serviceTypeOut_w = `SERVICE_ON; + end + default : begin // check change for the item + if (!exchangeReady) begin + if (inputValue < serviceValue) begin // too few money for the item + serviceValue_w = inputValue; + itemTypeOut_w = `ITEM_NONE; + exchangeReady_w = 1'b1; + end else begin + serviceValue_w = inputValue - serviceValue; + exchangeReady_w = 1'b1; + end + end else begin + case (serviceCoinType) + `NTD_50 : begin + if (serviceValue >= `VALUE_NTD_50) begin + if (countNTD_50 == 3'd0) begin + serviceCoinType_w = `NTD_10; + end else begin + coinOutNTD_50_w = coinOutNTD_50 + 3'd1; + countNTD_50_w = countNTD_50 - 3'd1; + serviceValue_w = serviceValue - `VALUE_NTD_50; + end + end else begin + serviceCoinType_w = `NTD_10; + end + end + `NTD_10 : begin + if (serviceValue >= `VALUE_NTD_10) begin + if (countNTD_10 == 3'd0) begin + serviceCoinType_w = `NTD_5; + end else begin + coinOutNTD_10_w = coinOutNTD_10 + 3'd1; + countNTD_10_w = countNTD_10 - 3'd1; + serviceValue_w = serviceValue - `VALUE_NTD_10; + end + end else begin + serviceCoinType_w = `NTD_5; + end + end + `NTD_5 : begin + if (serviceValue >= `VALUE_NTD_5) begin + if (countNTD_5 == 3'd0) begin + serviceCoinType_w = `NTD_1; + end else begin + coinOutNTD_5_w = coinOutNTD_5 + 3'd1; + countNTD_5_w = countNTD_5 - 3'd1; + serviceValue_w = serviceValue - `VALUE_NTD_5; + end + end else begin + serviceCoinType_w = `NTD_1; + end + end + `NTD_1 : begin + if (serviceValue >= `VALUE_NTD_1) begin + if (countNTD_1 == 3'd0) begin + serviceValue_w = inputValue; + itemTypeOut_w = `ITEM_NONE; + serviceCoinType_w = `NTD_50; + countNTD_50_w = countNTD_50 + coinOutNTD_50; + countNTD_10_w = countNTD_10 + coinOutNTD_10; + countNTD_5_w = countNTD_5 + coinOutNTD_5; + countNTD_1_w = countNTD_1 + coinOutNTD_1; + coinOutNTD_50_w = 3'd0; + coinOutNTD_10_w = 3'd0; + coinOutNTD_5_w = 3'd0; + coinOutNTD_1_w = 3'd0; + serviceTypeOut_w = `SERVICE_OFF; // bug 1 + end else begin + coinOutNTD_1_w = coinOutNTD_1 + 3'd1; + countNTD_1_w = countNTD_1 - 3'd1; + serviceValue_w = serviceValue - `VALUE_NTD_1; + end + end else begin // exchangeable + serviceTypeOut_w = `SERVICE_OFF; + end + end + endcase + end + end + endcase +end + +always @ (posedge clk) begin + if (!reset) begin + coinOutNTD_50 <= 3'd0; + coinOutNTD_10 <= 3'd0; + coinOutNTD_5 <= 3'd0; + coinOutNTD_1 <= 3'd0; + itemTypeOut <= `ITEM_NONE; + serviceTypeOut <= `SERVICE_ON; + countNTD_50 <= 3'd2; + countNTD_10 <= 3'd2; + countNTD_5 <= 3'd2; + countNTD_1 <= 3'd2; + inputValue <= 8'd0; + serviceValue <= 8'd0; + serviceCoinType <= `NTD_50; + exchangeReady <= 1'b0; + initialized <= 1'b1; + end + else begin + coinOutNTD_50 <= coinOutNTD_50_w; + coinOutNTD_10 <= coinOutNTD_10_w; + coinOutNTD_5 <= coinOutNTD_5_w; + coinOutNTD_1 <= coinOutNTD_1_w; + itemTypeOut <= itemTypeOut_w; + serviceTypeOut <= serviceTypeOut_w; + countNTD_50 <= countNTD_50_w; + countNTD_10 <= countNTD_10_w; + countNTD_5 <= countNTD_5_w; + countNTD_1 <= countNTD_1_w; + inputValue <= inputValue_w; + serviceValue <= serviceValue_w; + serviceCoinType <= serviceCoinType_w; + exchangeReady <= exchangeReady_w; + initialized <= initialized; + end +end + +endmodule diff --git a/design/V3/alu/alu.aig b/designs/V3/alu/alu.aig similarity index 100% rename from design/V3/alu/alu.aig rename to designs/V3/alu/alu.aig diff --git a/design/V3/alu/alu.blif b/designs/V3/alu/alu.blif similarity index 100% rename from design/V3/alu/alu.blif rename to designs/V3/alu/alu.blif diff --git a/design/V3/alu/alu.v b/designs/V3/alu/alu.v similarity index 100% rename from design/V3/alu/alu.v rename to designs/V3/alu/alu.v diff --git a/design/V3/philosopher/ph64.v b/designs/V3/philosopher/ph64.v similarity index 100% rename from design/V3/philosopher/ph64.v rename to designs/V3/philosopher/ph64.v diff --git a/design/V3/philosopher/philosopher.v b/designs/V3/philosopher/philosopher.v similarity index 100% rename from design/V3/philosopher/philosopher.v rename to designs/V3/philosopher/philosopher.v diff --git a/design/V3/quteTK6280/quteTK6280.aig b/designs/V3/quteTK6280/quteTK6280.aig similarity index 100% rename from design/V3/quteTK6280/quteTK6280.aig rename to designs/V3/quteTK6280/quteTK6280.aig diff --git a/design/V3/quteTK6280/quteTK6280.btor b/designs/V3/quteTK6280/quteTK6280.btor similarity index 100% rename from design/V3/quteTK6280/quteTK6280.btor rename to designs/V3/quteTK6280/quteTK6280.btor diff --git a/design/V3/traffic/traffic.v b/designs/V3/traffic/traffic.v similarity index 100% rename from design/V3/traffic/traffic.v rename to designs/V3/traffic/traffic.v diff --git a/designs/V3/vending/vending.v b/designs/V3/vending/vending.v new file mode 100644 index 00000000..9693abb9 --- /dev/null +++ b/designs/V3/vending/vending.v @@ -0,0 +1,267 @@ +/* + Source : vending/vending.v + Synopsis : A sample vending machine design. + Authors : Cheng-Yin Wu, NTUGIEE + Date : 2013/02/20 + Version : 1.0 +*/ + +// Service Types +`define SERVICE_OFF 2'b00 // vending machine outputs items and changes +`define SERVICE_ON 2'b01 // vending machine waits external requests +`define SERVICE_BUSY 2'b10 // vending machine processes requests +// Coin Types +`define COIN_A 2'b00 +`define COIN_B 2'b01 +`define COIN_C 2'b10 +`define COIN_D 2'b11 +// Coin Values +`define VALUE_COIN_A 13'd50 +`define VALUE_COIN_B 13'd10 +`define VALUE_COIN_C 13'd5 +`define VALUE_COIN_D 13'd1 +// Item Types +`define ITEM_A 2'b00 +`define ITEM_B 2'b01 +`define ITEM_C 2'b10 +`define ITEM_D 2'b11 +// Item Costs +`define COST_ITEM_A 13'd15 +`define COST_ITEM_B 13'd25 +`define COST_ITEM_C 13'd75 +`define COST_ITEM_D 13'd100 + +module vendingMachine( + // General I/O Ports + clk, + reset, + // Input Ports + coinInA, + coinInB, + coinInC, + coinInD, + itemTypeIn, + itemNumberIn, + forceIn, + // Output Ports + coinOutA, + coinOutB, + coinOutC, + coinOutD, + itemTypeOut, + itemNumberOut, + serviceTypeOut +); + +// General I/O Ports +input clk; +input reset; +// Input Ports +input [5:0] coinInA; // input number of COIN_A +input [5:0] coinInB; // input number of COIN_B +input [5:0] coinInC; // input number of COIN_C +input [5:0] coinInD; // input number of COIN_D +input [1:0] itemTypeIn; // type of an item +input [2:0] itemNumberIn; // number of the item +input forceIn; // service max as possible +// Output Ports +output [5:0] coinOutA; // output number of COIN_A +output [5:0] coinOutB; // output number of COIN_B +output [5:0] coinOutC; // output number of COIN_C +output [5:0] coinOutD; // output number of COIN_D +output [1:0] itemTypeOut; // type of an item +output [2:0] itemNumberOut; // number of the item +output [1:0] serviceTypeOut; // type of the service + +reg [5:0] coinOutA; // number of COIN_A +reg [5:0] coinOutB; // number of COIN_B +reg [5:0] coinOutC; // number of COIN_C +reg [5:0] coinOutD; // number of COIN_D + +reg [1:0] itemTypeOut; // type of an item +reg [2:0] itemNumberOut; // number of the item +reg [1:0] serviceTypeOut; // type of the service +reg forceService; // service max as possible + +reg [5:0] countA; // number of stored COIN_A +reg [5:0] countB; // number of stored COIN_B +reg [5:0] countC; // number of stored COIN_C +reg [5:0] countD; // number of stored COIN_D + +reg [12:0] inputValue; // total value of input coins +reg [12:0] serviceValue; // total cost of items to be serviced + +reg [1:0] serviceCoinType; // type of the coin for the service +reg changeReady; // ready for change in SERVICE_BUSY +reg initialized; // system initialized or not (i.e. reset) + +always @ (posedge clk) begin + if (!reset) begin + coinOutA <= 6'd0; + coinOutB <= 6'd0; + coinOutC <= 6'd0; + coinOutD <= 6'd0; + itemTypeOut <= `ITEM_A; + itemNumberOut <= 3'd0; + serviceTypeOut <= `SERVICE_ON; + forceService <= 1'b0; + countA <= 6'd5; + countB <= 6'd30; + countC <= 6'd10; + countD <= 6'd20; + inputValue <= 13'd0; + serviceValue <= 13'd0; + serviceCoinType <= 2'd0; + changeReady <= 1'b0; + initialized <= 1'b1; + end + else if (initialized) begin + case (serviceTypeOut) + `SERVICE_ON : begin + if (itemNumberIn != 3'd0) begin // valid request + coinOutA <= 6'd0; + coinOutB <= 6'd0; + coinOutC <= 6'd0; + coinOutD <= 6'd0; + itemTypeOut <= itemTypeIn; + itemNumberOut <= itemNumberIn; + serviceTypeOut <= `SERVICE_BUSY; + forceService <= forceIn; + countA <= (({1'b0, countA} + {1'b0, coinInA}) >= {1'b0, 6'b111111}) ? 6'b111111 : + (countA + coinInA); + countB <= (({1'b0, countB} + {1'b0, coinInB}) >= {1'b0, 6'b111111}) ? 6'b111111 : + (countB + coinInB); + countC <= (({1'b0, countC} + {1'b0, coinInC}) >= {1'b0, 6'b111111}) ? 6'b111111 : + (countC + coinInC); + countD <= (({1'b0, countD} + {1'b0, coinInD}) >= {1'b0, 6'b111111}) ? 6'b111111 : + (countD + coinInD); + inputValue <= (`VALUE_COIN_A * {7'd0, coinInA}) + + (`VALUE_COIN_B * {7'd0, coinInB}) + + (`VALUE_COIN_C * {7'd0, coinInC}) + + (`VALUE_COIN_D * {7'd0, coinInD}); + serviceValue <= (itemTypeIn == `ITEM_A) ? ({10'd0, itemNumberIn} * `COST_ITEM_A) : + (itemTypeIn == `ITEM_B) ? ({10'd0, itemNumberIn} * `COST_ITEM_B) : + (itemTypeIn == `ITEM_C) ? ({10'd0, itemNumberIn} * `COST_ITEM_C) : + (itemTypeIn == `ITEM_D) ? ({10'd0, itemNumberIn} * `COST_ITEM_D) : 13'd0; + serviceCoinType <= `COIN_A; + changeReady <= 1'b0; + end + end + `SERVICE_OFF : begin + serviceTypeOut <= `SERVICE_ON; + end + default : begin + if (!changeReady) begin + if (inputValue < serviceValue) begin + if (forceService) begin + itemNumberOut <= itemNumberOut - 3'd1; + serviceValue <= (itemTypeOut == `ITEM_A) ? (serviceValue - `COST_ITEM_A) : + (itemTypeOut == `ITEM_B) ? (serviceValue - `COST_ITEM_B) : + (itemTypeOut == `ITEM_C) ? (serviceValue - `COST_ITEM_C) : + (itemTypeOut == `ITEM_D) ? (serviceValue - `COST_ITEM_D) : 13'd0; + end + else begin + changeReady <= 1'b1; + serviceValue <= inputValue; + itemNumberOut <= 3'd0; + end + end + else begin + changeReady <= 1'b1; + serviceValue <= inputValue - serviceValue; + end + end + else begin + case (serviceCoinType) + `COIN_A : begin + if (serviceValue >= `VALUE_COIN_A) begin + if (countA == 6'd0) begin + serviceCoinType <= `COIN_B; + end + else begin + coinOutA <= coinOutA + 6'd1; + countA <= countA - 6'd1; + serviceValue <= serviceValue - `VALUE_COIN_A; + end + end + else begin + serviceCoinType <= `COIN_B; + end + end + `COIN_B : begin + if (serviceValue >= `VALUE_COIN_B) begin + if (countB == 6'd0) begin + serviceCoinType <= `COIN_C; + end + else begin + coinOutB <= coinOutB + 6'd1; + countB <= countB - 6'd1; + serviceValue <= serviceValue - `VALUE_COIN_B; + end + end + else begin + serviceCoinType <= `COIN_C; + end + end + `COIN_C : begin + if (serviceValue >= `VALUE_COIN_C) begin + if (countC == 6'd0) begin + serviceCoinType <= `COIN_D; + end + else begin + coinOutC <= coinOutC + 6'd1; + countC <= countC - 6'd1; + serviceValue <= serviceValue - `VALUE_COIN_C; + end + end + else begin + serviceCoinType <= `COIN_D; + end + end + `COIN_D : begin + if (serviceValue >= `VALUE_COIN_D) begin + if (countD == 6'd0) begin + coinOutA <= 6'd0; + coinOutB <= 6'd0; + coinOutC <= 6'd0; + coinOutD <= 6'd0; + countA <= (countA + coinOutA); + countB <= (countB + coinOutB); + countC <= (countC + coinOutC); + countD <= (countD + coinOutD); + serviceCoinType <= `COIN_A; + if (forceService) begin + itemNumberOut <= itemNumberOut - 3'd1; + serviceValue <= (`VALUE_COIN_A * {7'd0, coinOutA}) + + (`VALUE_COIN_B * {7'd0, coinOutB}) + + (`VALUE_COIN_C * {7'd0, coinOutC}) + + (`VALUE_COIN_D * {7'd0, coinOutD}) + + serviceValue + ( + (itemTypeOut == `ITEM_A) ? `COST_ITEM_A : + (itemTypeOut == `ITEM_B) ? `COST_ITEM_B : + (itemTypeOut == `ITEM_C) ? `COST_ITEM_C : + (itemTypeOut == `ITEM_D) ? `COST_ITEM_D : 13'd0); + end + else begin + serviceValue <= inputValue; + itemNumberOut <= 3'd0; + end + end + else begin + coinOutD <= coinOutD + 6'd1; + countD <= countD - 6'd1; + serviceValue <= serviceValue - `VALUE_COIN_D; + end + end + else begin + serviceTypeOut <= `SERVICE_OFF; + end + end + endcase + end + end + endcase + end +end + +endmodule diff --git a/docs/BUILD_TUTORIAL.md b/docs/BUILD_TUTORIAL.md new file mode 100644 index 00000000..8de97361 --- /dev/null +++ b/docs/BUILD_TUTORIAL.md @@ -0,0 +1,220 @@ +# GV Building Process Tutorial + +This document serves as a guide to understand the building process of GV, focusing on the CMakeLists. + +## Introduction + +This document outlines the steps involved in building GV using CMakeLists. + +

+image +

+ +## Get the Engines source + +We utilize ExternalProject_Add to acquire third-party engines since Yosys doesn't currently support CMake. + +### Example: ExternalProject_Add Engine ABC + +Below is an example demonstrating how we utilize ExternalProject_Add to obtain the source files of the ABC engine: + +- **Git Integration**: We use Git to fetch the source files. +- **Version Tag**: The `GIT_TAG` parameter ensures we stay on a specific version of ABC. +- **Build Configuration**: Setting `BUILD_IN_SOURCE` to 1 allows us to compile ABC directly within its source tree. +- **Command Configuration**: Customizing `CONFIGURE_COMMAND`, `INSTALL_COMMAND`, and `UPDATE_COMMAND` to ensure that only code compilation occurs, without configuring, installing, or updating. + +```cmake +# * Git clone the ABC repo at build time +# * Run the BUILD_COMMAND "make libabc.a" for creating the ABC static library +set(LIBABC_NAME libabc.a) +ExternalProject_Add( + engine-abc + GIT_REPOSITORY https://github.com/berkeley-abc/abc.git + GIT_TAG 6ca7eab + GIT_PROGRESS TRUE + PREFIX engines + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + INSTALL_COMMAND "" + UPDATE_COMMAND "" + UPDATE_DISCONNECTED TRUE + BUILD_COMMAND $(MAKE) ${LIBABC_NAME} + LOG_CONFIGURE ON + LOG_INSTALL ON + # LOG_BUILD ON +) +``` + +## Patching the Yosys Engine + +When integrating Yosys into GV, it's necessary to apply patches to its Makefile. Below, we outline how to patch the Yosys engine during the build process. + +### Using PATCH_COMMAND for Patching + +To facilitate patching, we utilize CMake and its ExternalProject_Add module. The PATCH_COMMAND within ExternalProject_Add allows us to apply modifications to the Yosys Makefile before building it. + +PATCH_COMMAND will run the patches/yosys_patch.cmake module. + +```cmake +# Set the directory containing patch files +set(PATCH_DIR ${CMAKE_SOURCE_DIR}/patches) +# Specify the name of the CMake script for patching +set(YOSYS_PATCH_CMAKE yosys_patch.cmake) +# Define the name of the Yosys shared library +set(LIBYOSYS_NAME libyosys.so) + +# Add the external project for Yosys, including patching step +ExternalProject_Add( + engine-yosys + // ... + PATCH_COMMAND ${CMAKE_COMMAND} -P ${PATCH_DIR}/${YOSYS_PATCH_CMAKE} +) +``` + +### yosys_patch.cmake + +The yosys_patch.cmake script is responsible for handling the patching process. It selects the appropriate patch file based on the operating system (Linux/MacOS) and applies it to the Yosys Makefile. + +```cmake +# Path to the yosys patch +if(APPLE) + message(STATUS "Using Mac Patch") + set(YOSYS_PATCH_FILE yosys_mac.patch) +else() + message(STATUS "Using Linux Patch") + set(YOSYS_PATCH_FILE yosys_linux.patch) +endif() + +set(OUTPUT_REDIRECT "/dev/null") + +# Command for checking the patch is applied or not +set(YOSYS_PATCH_CHECK git apply --check ${CMAKE_CURRENT_LIST_DIR}/${YOSYS_PATCH_FILE}) +# Command for applying the patch +set(YOSYS_PATCH git apply ${CMAKE_CURRENT_LIST_DIR}/${YOSYS_PATCH_FILE}) + +# * Get the exit status of "git apply --check" +# * Output the log message to the /dev/null +execute_process( + COMMAND ${YOSYS_PATCH_CHECK} + RESULT_VARIABLE STATUS + OUTPUT_VARIABLE OUTPUT + OUTPUT_FILE ${OUTPUT_REDIRECT} + ERROR_FILE ${OUTPUT_REDIRECT}) + +# Patch has not been applied +if(STATUS EQUAL "0") + # Apply the patch to the Yosys Makefile + message(STATUS "Applying the yosys patch") + execute_process(COMMAND ${YOSYS_PATCH}) +else() + # Patch has been applied + message(STATUS "Skip the patch step\nPatch has been applied") +endif() +``` + +## Collecting GV Source Files + +In this section, we outline the process of collecting all the cpp and header files from the `src/` folder of GV for later compilation. + +### Gathering Source Files + +We use `file(GLOB_RECURSE ...)` command to recursively search for all `.cpp` and `.h` files under the `src/` directory. + +```cmake +# Collect all the cpp and header files under src/ +file( + GLOB_RECURSE SOURCES + RELATIVE ${CMAKE_SOURCE_DIR} + "src/**/*.cpp" "src/**/*.h") +add_executable(${CMAKE_PROJECT_NAME} ${SOURCES}) +``` + +### Include Header Files + +To ensure proper inclusion of header files without using relative paths, we specify the header file paths explicitly. This approach simplifies header file inclusion throughout the project. Here's how we achieve this in CMake: + +```cmake +# Collect all directories under src/ +file( + GLOB SRC_DIR + RELATIVE ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/*) + +# Include all header files under the src/ directory +foreach(DIR ${SRC_DIR}) + if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/${DIR}) + target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/${DIR}) + endif() +endforeach() + +``` + +For example, including the header file becomes simpler, as shown below: + +```cpp +// Instead of: #include "src/cir/cirMgr.h" +#include "cirMgr.h" +// ... +``` + +### Include Engines Header Files + +Additionally, we need to specify the header file paths for the engine components: + +- ABC_DIR: build/engines/src/engine-abc/src/ +- YOSYS_DIR: build/engines/src/engine-yosys/ + +```cmake +# Include all the header files under the engine Yosys +target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${YOSYS_DIR}) +# Include all the header files under the engine ABC +target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${ABC_DIR}/src) +``` + +## Compiling Yosys Extension + +In this section, we describe the process of compiling Yosys extensions by adding the `src/ext/` directory as a subdirectory. This allows us to compile the `.cc` files under `src/ext/` into a `.so` shared library based on the CMakeLists file located in `src/ext/`. + +```cmake +# Set the path to the Yosys extension CMake file +set(YOSYS_PLUGIN_PATH src/ext/) +# Add the Yosys extension directory as a subdirectory +add_subdirectory(${YOSYS_PLUGIN_PATH}) +``` + +Below is the modified `CMakeLists.txt` file located at `src/ext/CMakeLists.txt`. In this file, we have incorporated changes to include platform-specific compile options based on the operating system. Additionally, we ensure that the Yosys engine dependency (`engine-yosys`) is built before building the extension. + +```cmake +# Collect all source files +file(GLOB MY_SOURCES "./*.cc") + +# Define the shared library suffix +set(CMAKE_SHARED_LIBRARY_SUFFIX ".so") + +# Compile each .cc file into a .so file +foreach(source_file ${MY_SOURCES}) + # Extract the file name (without path and extension) + get_filename_component(name ${source_file} NAME_WE) + # Compile each .cc file into a .so file + add_library(${name} SHARED ${source_file}) + # Ensure position independent code + set_property(TARGET ${name} PROPERTY POSITION_INDEPENDENT_CODE ON) + # Include Yosys engine directory + target_include_directories(${name} PRIVATE ${YOSYS_DIR}) + + # Platform-specific compile options + if(APPLE) + # macOS specific options + target_link_options(${name} PRIVATE "-dynamic" "-undefined" "dynamic_lookup") + else() + # Linux specific options + target_link_options(${name} PRIVATE "-rdynamic") + endif() + + # Define _YOSYS_ symbol for compilation + target_compile_definitions(${name} PRIVATE _YOSYS_) + + # Ensure Yosys engine dependency is built before building the extension + add_dependencies(${name} engine-yosys) +endforeach() +``` diff --git a/doc/GV_tutorial.pdf b/docs/GV_tutorial.pdf similarity index 100% rename from doc/GV_tutorial.pdf rename to docs/GV_tutorial.pdf diff --git a/doc/README.md b/docs/README.md similarity index 100% rename from doc/README.md rename to docs/README.md diff --git a/docs/imgs/build_flow.png b/docs/imgs/build_flow.png new file mode 100644 index 00000000..96436723 Binary files /dev/null and b/docs/imgs/build_flow.png differ diff --git a/docs/imgs/gv_abc_mgr.png b/docs/imgs/gv_abc_mgr.png new file mode 100644 index 00000000..590a10ee Binary files /dev/null and b/docs/imgs/gv_abc_mgr.png differ diff --git a/docs/imgs/gv_circuit_hierarchy.png b/docs/imgs/gv_circuit_hierarchy.png new file mode 100644 index 00000000..9e2f66ee Binary files /dev/null and b/docs/imgs/gv_circuit_hierarchy.png differ diff --git a/docs/imgs/gv_flow.png b/docs/imgs/gv_flow.png new file mode 100644 index 00000000..aa961913 Binary files /dev/null and b/docs/imgs/gv_flow.png differ diff --git a/docs/imgs/gv_utility_engine.png b/docs/imgs/gv_utility_engine.png new file mode 100644 index 00000000..9398781a Binary files /dev/null and b/docs/imgs/gv_utility_engine.png differ diff --git a/docs/imgs/gv_yosys_mgr.png b/docs/imgs/gv_yosys_mgr.png new file mode 100644 index 00000000..b628623c Binary files /dev/null and b/docs/imgs/gv_yosys_mgr.png differ diff --git a/engine/abc.script b/engine/abc.script deleted file mode 100755 index 5c10f68f..00000000 --- a/engine/abc.script +++ /dev/null @@ -1,32 +0,0 @@ -# abc -git clone https://github.com/berkeley-abc/abc -cd abc - -# switch to stable commit(581c58b) -git reset 581c58b - -# make abc -make -j12 - -# make "abc" static library -make libabc.a - -# rename the "abc" static library -mv libabc.a libabcc.a - -# copy "abc" static library to /gv_src -mkdir gv_src; mv libabcc.a gv_src; - -# include all hierarchical folder with only "header file" under gv_src/ -echo "Copying files to gv_src/ ..." -cp -r src/* gv_src/ -cd gv_src/ -rm *.c -find ./ -name "*.c" | xargs rm -find ./ -name "*.o" | xargs rm -find ./ -name "*.d" | xargs rm -find ./ -name "*.make" | xargs rm - -# go to src/eng and create symbol link -echo "Creating softlink from engine/abc/gv_src to src/eng/abcc ..."; -cd ../../../src/eng; ln -fs ../../engine/abc/gv_src ./abcc diff --git a/engine/boolector.script b/engine/boolector.script deleted file mode 100755 index d1d5e15d..00000000 --- a/engine/boolector.script +++ /dev/null @@ -1,35 +0,0 @@ -# boolector -git clone https://github.com/Boolector/boolector.git -cd boolector - -# switch to stable commit(13a8a06) -git reset 13a8a06 - -# build dependend tool -./contrib/setup-lingeling.sh -./contrib/setup-btor2tools.sh - -# build boolector -./configure.sh --no-minisat; cd build; make; - -# back to engine/boolector -cd ../ - -# create directory -mkdir gv_src_boolector/ -mkdir gv_src_btor2parser/ -mkdir gv_src_lgl/ - -# copy library and header file to gv_src/ -cp ./build/lib/libboolector.a gv_src_boolector/ -cp ./src/boolector.h gv_src_boolector/ -cp ./src/btortypes.h gv_src_boolector/ -cp ./deps/install/lib/libbtor2parser.a gv_src_btor2parser/ -cp ./deps/install/lib/liblgl.a gv_src_lgl - -# go to src/eng and create symbol link -echo "Creating softlink from engine/boolector/gv_src to src/eng/boolector ..."; -cd ../../src/eng; ln -fs ../../engine/boolector/gv_src_boolector ./boolector -cd ../../src/eng; ln -fs ../../engine/boolector/gv_src_btor2parser ./btor2parser -cd ../../src/eng; ln -fs ../../engine/boolector/gv_src_lgl ./lgl - diff --git a/engine/install.script b/engine/install.script deleted file mode 100755 index eaf993ce..00000000 --- a/engine/install.script +++ /dev/null @@ -1,18 +0,0 @@ -# abc -git clone https://github.com/berkeley-abc/abc -cd abc -make -j8 -cd ../ - -# yosys -git clone https://github.com/YosysHQ/yosys.git -cd yosys; -sudo apt-get install build-essential clang bison flex \ - libreadline-dev gawk tcl-dev libffi-dev git \ - graphviz xdot pkg-config python3 libboost-system-dev \ - libboost-python-dev libboost-filesystem-dev zlib1g-dev; -make config-clang; make -j8; -sudo make install; - -# clear -clear \ No newline at end of file diff --git a/engine/yosys.script b/engine/yosys.script deleted file mode 100755 index 93d18af9..00000000 --- a/engine/yosys.script +++ /dev/null @@ -1,37 +0,0 @@ -# yosys -git clone https://github.com/YosysHQ/yosys.git - -# go to yosys/ -cd yosys/; - -# switch to version 0.23 of yosys -git checkout yosys-0.23 - -# enable the libyosys.so flag -sed -i -e "s/ENABLE_LIBYOSYS := 0/ENABLE_LIBYOSYS := 1/g" Makefile; -# modify the libyosys.so path -sed -i -e "s/-install_name,\$(LIBDIR)\/libyosys.so/-install_name,\@rpath\/libyosys.so/g" Makefile; -sed -i -e "s/-Wl,-soname,\$(LIBDIR)\/libyosys.so//g" Makefile; - -# make "yosys" shared library -make config-gcc; make -j12; make libyosys.so; make install; - -# create gv_src/ directory -mkdir gv_src; - -# copy "yosys" shared library to gv_src/ directory -mv libyosys.so gv_src/; - -# copy "yosys" header files to gv_src/ directory -cp -rf share/include/kernel gv_src/; - -# back to gv0/ -cd ../../ - -# create the yosys-config and yosys-abc symbolink -ln -fs engine/yosys/yosys-config ./yosys-config -ln -fs engine/yosys/yosys-abc ./yosys-abc - -# go to src/eng and create symbol link -echo "Creating softlink from engine/yosys/gv_src to src/eng/yosys ..."; -cd ./src/eng/; ln -fs ../../engine/yosys/gv_src ./yosys diff --git a/include/Alg.h b/include/Alg.h deleted file mode 120000 index 76b58a6e..00000000 --- a/include/Alg.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/Alg.h \ No newline at end of file diff --git a/include/Alloc.h b/include/Alloc.h deleted file mode 120000 index 361a0e07..00000000 --- a/include/Alloc.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/Alloc.h \ No newline at end of file diff --git a/include/Dimacs.h b/include/Dimacs.h deleted file mode 120000 index a6a4b291..00000000 --- a/include/Dimacs.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/Dimacs.h \ No newline at end of file diff --git a/include/File.h b/include/File.h deleted file mode 120000 index a8557d15..00000000 --- a/include/File.h +++ /dev/null @@ -1 +0,0 @@ -../src/sat/File.h \ No newline at end of file diff --git a/include/Global.h b/include/Global.h deleted file mode 120000 index 42433d70..00000000 --- a/include/Global.h +++ /dev/null @@ -1 +0,0 @@ -../src/sat/Global.h \ No newline at end of file diff --git a/include/IntMap.h b/include/IntMap.h deleted file mode 120000 index da9f0009..00000000 --- a/include/IntMap.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/IntMap.h \ No newline at end of file diff --git a/include/IntTypes.h b/include/IntTypes.h deleted file mode 120000 index 39ccc3da..00000000 --- a/include/IntTypes.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/IntTypes.h \ No newline at end of file diff --git a/include/Makefile b/include/Makefile deleted file mode 120000 index f38fb1e2..00000000 --- a/include/Makefile +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/Makefile \ No newline at end of file diff --git a/include/Map.h b/include/Map.h deleted file mode 120000 index cb858141..00000000 --- a/include/Map.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/Map.h \ No newline at end of file diff --git a/include/Options.h b/include/Options.h deleted file mode 120000 index 71f48f65..00000000 --- a/include/Options.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/Options.h \ No newline at end of file diff --git a/include/ParseUtils.h b/include/ParseUtils.h deleted file mode 120000 index 2237bdc8..00000000 --- a/include/ParseUtils.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/ParseUtils.h \ No newline at end of file diff --git a/include/Proof.h b/include/Proof.h deleted file mode 120000 index 85617511..00000000 --- a/include/Proof.h +++ /dev/null @@ -1 +0,0 @@ -../src/sat/Proof.h \ No newline at end of file diff --git a/include/Queue.h b/include/Queue.h deleted file mode 120000 index 771c6be4..00000000 --- a/include/Queue.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/Queue.h \ No newline at end of file diff --git a/include/Rnd.h b/include/Rnd.h deleted file mode 120000 index 6bd8969d..00000000 --- a/include/Rnd.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/Rnd.h \ No newline at end of file diff --git a/include/System.h b/include/System.h deleted file mode 120000 index 5270c7d0..00000000 --- a/include/System.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/System.h \ No newline at end of file diff --git a/include/VarOrder.h b/include/VarOrder.h deleted file mode 120000 index a4921241..00000000 --- a/include/VarOrder.h +++ /dev/null @@ -1 +0,0 @@ -../src/sat/VarOrder.h \ No newline at end of file diff --git a/include/Vec.h b/include/Vec.h deleted file mode 120000 index 03ffe03a..00000000 --- a/include/Vec.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/Vec.h \ No newline at end of file diff --git a/include/XAlloc.h b/include/XAlloc.h deleted file mode 120000 index b0d84152..00000000 --- a/include/XAlloc.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/minisat/XAlloc.h \ No newline at end of file diff --git a/include/binding.h b/include/binding.h deleted file mode 120000 index fc86922b..00000000 --- a/include/binding.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/binding.h \ No newline at end of file diff --git a/include/bitpattern.h b/include/bitpattern.h deleted file mode 120000 index dee0d984..00000000 --- a/include/bitpattern.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/bitpattern.h \ No newline at end of file diff --git a/include/boolector.h b/include/boolector.h deleted file mode 120000 index f6fa9c0d..00000000 --- a/include/boolector.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/boolector/boolector.h \ No newline at end of file diff --git a/include/cellaigs.h b/include/cellaigs.h deleted file mode 120000 index 76dcb57e..00000000 --- a/include/cellaigs.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/cellaigs.h \ No newline at end of file diff --git a/include/celledges.h b/include/celledges.h deleted file mode 120000 index 45b37afc..00000000 --- a/include/celledges.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/celledges.h \ No newline at end of file diff --git a/include/celltypes.h b/include/celltypes.h deleted file mode 120000 index 7512b6b9..00000000 --- a/include/celltypes.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/celltypes.h \ No newline at end of file diff --git a/include/cmdCharDef.h b/include/cmdCharDef.h deleted file mode 120000 index e5242f07..00000000 --- a/include/cmdCharDef.h +++ /dev/null @@ -1 +0,0 @@ -../src/cmd/cmdCharDef.h \ No newline at end of file diff --git a/include/cmdParser.h b/include/cmdParser.h deleted file mode 120000 index a1136fdf..00000000 --- a/include/cmdParser.h +++ /dev/null @@ -1 +0,0 @@ -../src/cmd/cmdParser.h \ No newline at end of file diff --git a/include/consteval.h b/include/consteval.h deleted file mode 120000 index 7de04432..00000000 --- a/include/consteval.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/consteval.h \ No newline at end of file diff --git a/include/constids.inc b/include/constids.inc deleted file mode 120000 index d9fd3dab..00000000 --- a/include/constids.inc +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/constids.inc \ No newline at end of file diff --git a/include/cost.h b/include/cost.h deleted file mode 120000 index 766db1d9..00000000 --- a/include/cost.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/cost.h \ No newline at end of file diff --git a/include/ezminisat.h b/include/ezminisat.h deleted file mode 120000 index 0d881f1e..00000000 --- a/include/ezminisat.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/ezminisat.h \ No newline at end of file diff --git a/include/ff.h b/include/ff.h deleted file mode 120000 index 4386000e..00000000 --- a/include/ff.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/ff.h \ No newline at end of file diff --git a/include/ffinit.h b/include/ffinit.h deleted file mode 120000 index 7a0a3673..00000000 --- a/include/ffinit.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/ffinit.h \ No newline at end of file diff --git a/include/ffmerge.h b/include/ffmerge.h deleted file mode 120000 index df9ef56a..00000000 --- a/include/ffmerge.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/ffmerge.h \ No newline at end of file diff --git a/include/fstdata.h b/include/fstdata.h deleted file mode 120000 index b075442e..00000000 --- a/include/fstdata.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/fstdata.h \ No newline at end of file diff --git a/include/gmp.h b/include/gmp.h deleted file mode 100644 index c5258d47..00000000 --- a/include/gmp.h +++ /dev/null @@ -1,2336 +0,0 @@ -/* Definitions for GNU multiple precision functions. -*- mode: c -*- - -Copyright 1991, 1993-1997, 1999-2016, 2020 Free Software Foundation, Inc. - -This file is part of the GNU MP Library. - -The GNU MP Library is free software; you can redistribute it and/or modify -it under the terms of either: - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your - option) any later version. - -or - - * the GNU General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - -or both in parallel, as here. - -The GNU MP Library is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received copies of the GNU General Public License and the -GNU Lesser General Public License along with the GNU MP Library. If not, -see https://www.gnu.org/licenses/. */ - -#ifndef __GMP_H__ - -#if defined (__cplusplus) -#include /* for std::istream, std::ostream, std::string */ -#include -#endif - - -/* Instantiated by configure. */ -#if ! defined (__GMP_WITHIN_CONFIGURE) -#define __GMP_HAVE_HOST_CPU_FAMILY_power 0 -#define __GMP_HAVE_HOST_CPU_FAMILY_powerpc 0 -#define GMP_LIMB_BITS 64 -#define GMP_NAIL_BITS 0 -#endif -#define GMP_NUMB_BITS (GMP_LIMB_BITS - GMP_NAIL_BITS) -#define GMP_NUMB_MASK ((~ __GMP_CAST (mp_limb_t, 0)) >> GMP_NAIL_BITS) -#define GMP_NUMB_MAX GMP_NUMB_MASK -#define GMP_NAIL_MASK (~ GMP_NUMB_MASK) - - -#ifndef __GNU_MP__ -#define __GNU_MP__ 6 - -#include /* for size_t */ -#include - -/* Instantiated by configure. */ -#if ! defined (__GMP_WITHIN_CONFIGURE) -/* #undef _LONG_LONG_LIMB */ -#define __GMP_LIBGMP_DLL 0 -#endif - - -/* __GMP_DECLSPEC supports Windows DLL versions of libgmp, and is empty in - all other circumstances. - - When compiling objects for libgmp, __GMP_DECLSPEC is an export directive, - or when compiling for an application it's an import directive. The two - cases are differentiated by __GMP_WITHIN_GMP defined by the GMP Makefiles - (and not defined from an application). - - __GMP_DECLSPEC_XX is similarly used for libgmpxx. __GMP_WITHIN_GMPXX - indicates when building libgmpxx, and in that case libgmpxx functions are - exports, but libgmp functions which might get called are imports. - - Libtool DLL_EXPORT define is not used. - - There's no attempt to support GMP built both static and DLL. Doing so - would mean applications would have to tell us which of the two is going - to be used when linking, and that seems very tedious and error prone if - using GMP by hand, and equally tedious from a package since autoconf and - automake don't give much help. - - __GMP_DECLSPEC is required on all documented global functions and - variables, the various internals in gmp-impl.h etc can be left unadorned. - But internals used by the test programs or speed measuring programs - should have __GMP_DECLSPEC, and certainly constants or variables must - have it or the wrong address will be resolved. - - In gcc __declspec can go at either the start or end of a prototype. - - In Microsoft C __declspec must go at the start, or after the type like - void __declspec(...) *foo()". There's no __dllexport or anything to - guard against someone foolish #defining dllexport. _export used to be - available, but no longer. - - In Borland C _export still exists, but needs to go after the type, like - "void _export foo();". Would have to change the __GMP_DECLSPEC syntax to - make use of that. Probably more trouble than it's worth. */ - -#if defined (__GNUC__) -#define __GMP_DECLSPEC_EXPORT __declspec(__dllexport__) -#define __GMP_DECLSPEC_IMPORT __declspec(__dllimport__) -#endif -#if defined (_MSC_VER) || defined (__BORLANDC__) -#define __GMP_DECLSPEC_EXPORT __declspec(dllexport) -#define __GMP_DECLSPEC_IMPORT __declspec(dllimport) -#endif -#ifdef __WATCOMC__ -#define __GMP_DECLSPEC_EXPORT __export -#define __GMP_DECLSPEC_IMPORT __import -#endif -#ifdef __IBMC__ -#define __GMP_DECLSPEC_EXPORT _Export -#define __GMP_DECLSPEC_IMPORT _Import -#endif - -#if __GMP_LIBGMP_DLL -#ifdef __GMP_WITHIN_GMP -/* compiling to go into a DLL libgmp */ -#define __GMP_DECLSPEC __GMP_DECLSPEC_EXPORT -#else -/* compiling to go into an application which will link to a DLL libgmp */ -#define __GMP_DECLSPEC __GMP_DECLSPEC_IMPORT -#endif -#else -/* all other cases */ -#define __GMP_DECLSPEC -#endif - - -#ifdef __GMP_SHORT_LIMB -typedef unsigned int mp_limb_t; -typedef int mp_limb_signed_t; -#else -#ifdef _LONG_LONG_LIMB -typedef unsigned long long int mp_limb_t; -typedef long long int mp_limb_signed_t; -#else -typedef unsigned long int mp_limb_t; -typedef long int mp_limb_signed_t; -#endif -#endif -typedef unsigned long int mp_bitcnt_t; - -/* For reference, note that the name __mpz_struct gets into C++ mangled - function names, which means although the "__" suggests an internal, we - must leave this name for binary compatibility. */ -typedef struct -{ - int _mp_alloc; /* Number of *limbs* allocated and pointed - to by the _mp_d field. */ - int _mp_size; /* abs(_mp_size) is the number of limbs the - last field points to. If _mp_size is - negative this is a negative number. */ - mp_limb_t *_mp_d; /* Pointer to the limbs. */ -} __mpz_struct; - -#endif /* __GNU_MP__ */ - - -typedef __mpz_struct MP_INT; /* gmp 1 source compatibility */ -typedef __mpz_struct mpz_t[1]; - -typedef mp_limb_t * mp_ptr; -typedef const mp_limb_t * mp_srcptr; -#if defined (_CRAY) && ! defined (_CRAYMPP) -/* plain `int' is much faster (48 bits) */ -#define __GMP_MP_SIZE_T_INT 1 -typedef int mp_size_t; -typedef int mp_exp_t; -#else -#define __GMP_MP_SIZE_T_INT 0 -typedef long int mp_size_t; -typedef long int mp_exp_t; -#endif - -typedef struct -{ - __mpz_struct _mp_num; - __mpz_struct _mp_den; -} __mpq_struct; - -typedef __mpq_struct MP_RAT; /* gmp 1 source compatibility */ -typedef __mpq_struct mpq_t[1]; - -typedef struct -{ - int _mp_prec; /* Max precision, in number of `mp_limb_t's. - Set by mpf_init and modified by - mpf_set_prec. The area pointed to by the - _mp_d field contains `prec' + 1 limbs. */ - int _mp_size; /* abs(_mp_size) is the number of limbs the - last field points to. If _mp_size is - negative this is a negative number. */ - mp_exp_t _mp_exp; /* Exponent, in the base of `mp_limb_t'. */ - mp_limb_t *_mp_d; /* Pointer to the limbs. */ -} __mpf_struct; - -/* typedef __mpf_struct MP_FLOAT; */ -typedef __mpf_struct mpf_t[1]; - -/* Available random number generation algorithms. */ -typedef enum -{ - GMP_RAND_ALG_DEFAULT = 0, - GMP_RAND_ALG_LC = GMP_RAND_ALG_DEFAULT /* Linear congruential. */ -} gmp_randalg_t; - -/* Random state struct. */ -typedef struct -{ - mpz_t _mp_seed; /* _mp_d member points to state of the generator. */ - gmp_randalg_t _mp_alg; /* Currently unused. */ - union { - void *_mp_lc; /* Pointer to function pointers structure. */ - } _mp_algdata; -} __gmp_randstate_struct; -typedef __gmp_randstate_struct gmp_randstate_t[1]; - -/* Types for function declarations in gmp files. */ -/* ??? Should not pollute user name space with these ??? */ -typedef const __mpz_struct *mpz_srcptr; -typedef __mpz_struct *mpz_ptr; -typedef const __mpf_struct *mpf_srcptr; -typedef __mpf_struct *mpf_ptr; -typedef const __mpq_struct *mpq_srcptr; -typedef __mpq_struct *mpq_ptr; - - -#if __GMP_LIBGMP_DLL -#ifdef __GMP_WITHIN_GMPXX -/* compiling to go into a DLL libgmpxx */ -#define __GMP_DECLSPEC_XX __GMP_DECLSPEC_EXPORT -#else -/* compiling to go into a application which will link to a DLL libgmpxx */ -#define __GMP_DECLSPEC_XX __GMP_DECLSPEC_IMPORT -#endif -#else -/* all other cases */ -#define __GMP_DECLSPEC_XX -#endif - - -#ifndef __MPN -#define __MPN(x) __gmpn_##x -#endif - -/* For reference, "defined(EOF)" cannot be used here. In g++ 2.95.4, - defines EOF but not FILE. */ -#if defined (FILE) \ - || defined (H_STDIO) \ - || defined (_H_STDIO) /* AIX */ \ - || defined (_STDIO_H) /* glibc, Sun, SCO */ \ - || defined (_STDIO_H_) /* BSD, OSF */ \ - || defined (__STDIO_H) /* Borland */ \ - || defined (__STDIO_H__) /* IRIX */ \ - || defined (_STDIO_INCLUDED) /* HPUX */ \ - || defined (__dj_include_stdio_h_) /* DJGPP */ \ - || defined (_FILE_DEFINED) /* Microsoft */ \ - || defined (__STDIO__) /* Apple MPW MrC */ \ - || defined (_MSL_STDIO_H) /* Metrowerks */ \ - || defined (_STDIO_H_INCLUDED) /* QNX4 */ \ - || defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \ - || defined (__STDIO_LOADED) /* VMS */ \ - || defined (__DEFINED_FILE) /* musl */ -#define _GMP_H_HAVE_FILE 1 -#endif - -/* In ISO C, if a prototype involving "struct obstack *" is given without - that structure defined, then the struct is scoped down to just the - prototype, causing a conflict if it's subsequently defined for real. So - only give prototypes if we've got obstack.h. */ -#if defined (_OBSTACK_H) /* glibc */ -#define _GMP_H_HAVE_OBSTACK 1 -#endif - -/* The prototypes for gmp_vprintf etc are provided only if va_list is defined, - via an application having included . Usually va_list is a typedef - so can't be tested directly, but C99 specifies that va_start is a macro. - - will define some sort of va_list for vprintf and vfprintf, but - let's not bother trying to use that since it's not standard and since - application uses for gmp_vprintf etc will almost certainly require the - whole anyway. */ - -#ifdef va_start -#define _GMP_H_HAVE_VA_LIST 1 -#endif - -/* Test for gcc >= maj.min, as per __GNUC_PREREQ in glibc */ -#if defined (__GNUC__) && defined (__GNUC_MINOR__) -#define __GMP_GNUC_PREREQ(maj, min) \ - ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) -#else -#define __GMP_GNUC_PREREQ(maj, min) 0 -#endif - -/* "pure" is in gcc 2.96 and up, see "(gcc)Function Attributes". Basically - it means a function does nothing but examine its arguments and memory - (global or via arguments) to generate a return value, but changes nothing - and has no side-effects. __GMP_NO_ATTRIBUTE_CONST_PURE lets - tune/common.c etc turn this off when trying to write timing loops. */ -#if __GMP_GNUC_PREREQ (2,96) && ! defined (__GMP_NO_ATTRIBUTE_CONST_PURE) -#define __GMP_ATTRIBUTE_PURE __attribute__ ((__pure__)) -#else -#define __GMP_ATTRIBUTE_PURE -#endif - - -/* __GMP_CAST allows us to use static_cast in C++, so our macros are clean - to "g++ -Wold-style-cast". - - Casts in "extern inline" code within an extern "C" block don't induce - these warnings, so __GMP_CAST only needs to be used on documented - macros. */ - -#ifdef __cplusplus -#define __GMP_CAST(type, expr) (static_cast (expr)) -#else -#define __GMP_CAST(type, expr) ((type) (expr)) -#endif - - -/* An empty "throw ()" means the function doesn't throw any C++ exceptions, - this can save some stack frame info in applications. - - Currently it's given only on functions which never divide-by-zero etc, - don't allocate memory, and are expected to never need to allocate memory. - This leaves open the possibility of a C++ throw from a future GMP - exceptions scheme. - - mpz_set_ui etc are omitted to leave open the lazy allocation scheme - described in doc/tasks.html. mpz_get_d etc are omitted to leave open - exceptions for float overflows. - - Note that __GMP_NOTHROW must be given on any inlines the same as on their - prototypes (for g++ at least, where they're used together). Note also - that g++ 3.0 demands that __GMP_NOTHROW is before other attributes like - __GMP_ATTRIBUTE_PURE. */ - -#if defined (__cplusplus) -#if __cplusplus >= 201103L -#define __GMP_NOTHROW noexcept -#else -#define __GMP_NOTHROW throw () -#endif -#else -#define __GMP_NOTHROW -#endif - - -/* PORTME: What other compilers have a useful "extern inline"? "static - inline" would be an acceptable substitute if the compiler (or linker) - discards unused statics. */ - - /* gcc has __inline__ in all modes, including strict ansi. Give a prototype - for an inline too, so as to correctly specify "dllimport" on windows, in - case the function is called rather than inlined. - GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 - inline semantics, unless -fgnu89-inline is used. */ -#ifdef __GNUC__ -#if (defined __GNUC_STDC_INLINE__) || (__GNUC__ == 4 && __GNUC_MINOR__ == 2) \ - || (defined __GNUC_GNU_INLINE__ && defined __cplusplus) -#define __GMP_EXTERN_INLINE extern __inline__ __attribute__ ((__gnu_inline__)) -#else -#define __GMP_EXTERN_INLINE extern __inline__ -#endif -#define __GMP_INLINE_PROTOTYPES 1 -#endif - -/* DEC C (eg. version 5.9) supports "static __inline foo()", even in -std1 - strict ANSI mode. Inlining is done even when not optimizing (ie. -O0 - mode, which is the default), but an unnecessary local copy of foo is - emitted unless -O is used. "extern __inline" is accepted, but the - "extern" appears to be ignored, ie. it becomes a plain global function - but which is inlined within its file. Don't know if all old versions of - DEC C supported __inline, but as a start let's do the right thing for - current versions. */ -#ifdef __DECC -#define __GMP_EXTERN_INLINE static __inline -#endif - -/* SCO OpenUNIX 8 cc supports "static inline foo()" but not in -Xc strict - ANSI mode (__STDC__ is 1 in that mode). Inlining only actually takes - place under -O. Without -O "foo" seems to be emitted whether it's used - or not, which is wasteful. "extern inline foo()" isn't useful, the - "extern" is apparently ignored, so foo is inlined if possible but also - emitted as a global, which causes multiple definition errors when - building a shared libgmp. */ -#ifdef __SCO_VERSION__ -#if __SCO_VERSION__ > 400000000 && __STDC__ != 1 \ - && ! defined (__GMP_EXTERN_INLINE) -#define __GMP_EXTERN_INLINE static inline -#endif -#endif - -/* Microsoft's C compiler accepts __inline */ -#ifdef _MSC_VER -#define __GMP_EXTERN_INLINE __inline -#endif - -/* Recent enough Sun C compilers want "inline" */ -#if defined (__SUNPRO_C) && __SUNPRO_C >= 0x560 \ - && ! defined (__GMP_EXTERN_INLINE) -#define __GMP_EXTERN_INLINE inline -#endif - -/* Somewhat older Sun C compilers want "static inline" */ -#if defined (__SUNPRO_C) && __SUNPRO_C >= 0x540 \ - && ! defined (__GMP_EXTERN_INLINE) -#define __GMP_EXTERN_INLINE static inline -#endif - - -/* C++ always has "inline" and since it's a normal feature the linker should - discard duplicate non-inlined copies, or if it doesn't then that's a - problem for everyone, not just GMP. */ -#if defined (__cplusplus) && ! defined (__GMP_EXTERN_INLINE) -#define __GMP_EXTERN_INLINE inline -#endif - -/* Don't do any inlining within a configure run, since if the compiler ends - up emitting copies of the code into the object file it can end up - demanding the various support routines (like mpn_popcount) for linking, - making the "alloca" test and perhaps others fail. And on hppa ia64 a - pre-release gcc 3.2 was seen not respecting the "extern" in "extern - __inline__", triggering this problem too. */ -#if defined (__GMP_WITHIN_CONFIGURE) && ! __GMP_WITHIN_CONFIGURE_INLINE -#undef __GMP_EXTERN_INLINE -#endif - -/* By default, don't give a prototype when there's going to be an inline - version. Note in particular that Cray C++ objects to the combination of - prototype and inline. */ -#ifdef __GMP_EXTERN_INLINE -#ifndef __GMP_INLINE_PROTOTYPES -#define __GMP_INLINE_PROTOTYPES 0 -#endif -#else -#define __GMP_INLINE_PROTOTYPES 1 -#endif - - -#define __GMP_ABS(x) ((x) >= 0 ? (x) : -(x)) -#define __GMP_MAX(h,i) ((h) > (i) ? (h) : (i)) - - -/* __builtin_expect is in gcc 3.0, and not in 2.95. */ -#if __GMP_GNUC_PREREQ (3,0) -#define __GMP_LIKELY(cond) __builtin_expect ((cond) != 0, 1) -#define __GMP_UNLIKELY(cond) __builtin_expect ((cond) != 0, 0) -#else -#define __GMP_LIKELY(cond) (cond) -#define __GMP_UNLIKELY(cond) (cond) -#endif - -#ifdef _CRAY -#define __GMP_CRAY_Pragma(str) _Pragma (str) -#else -#define __GMP_CRAY_Pragma(str) -#endif - - -/* Allow direct user access to numerator and denominator of an mpq_t object. */ -#define mpq_numref(Q) (&((Q)->_mp_num)) -#define mpq_denref(Q) (&((Q)->_mp_den)) - - -#if defined (__cplusplus) -extern "C" { -using std::FILE; -#endif - -#define mp_set_memory_functions __gmp_set_memory_functions -__GMP_DECLSPEC void mp_set_memory_functions (void *(*) (size_t), - void *(*) (void *, size_t, size_t), - void (*) (void *, size_t)) __GMP_NOTHROW; - -#define mp_get_memory_functions __gmp_get_memory_functions -__GMP_DECLSPEC void mp_get_memory_functions (void *(**) (size_t), - void *(**) (void *, size_t, size_t), - void (**) (void *, size_t)) __GMP_NOTHROW; - -#define mp_bits_per_limb __gmp_bits_per_limb -__GMP_DECLSPEC extern const int mp_bits_per_limb; - -#define gmp_errno __gmp_errno -__GMP_DECLSPEC extern int gmp_errno; - -#define gmp_version __gmp_version -__GMP_DECLSPEC extern const char * const gmp_version; - - -/**************** Random number routines. ****************/ - -/* obsolete */ -#define gmp_randinit __gmp_randinit -__GMP_DECLSPEC void gmp_randinit (gmp_randstate_t, gmp_randalg_t, ...); - -#define gmp_randinit_default __gmp_randinit_default -__GMP_DECLSPEC void gmp_randinit_default (gmp_randstate_t); - -#define gmp_randinit_lc_2exp __gmp_randinit_lc_2exp -__GMP_DECLSPEC void gmp_randinit_lc_2exp (gmp_randstate_t, mpz_srcptr, unsigned long int, mp_bitcnt_t); - -#define gmp_randinit_lc_2exp_size __gmp_randinit_lc_2exp_size -__GMP_DECLSPEC int gmp_randinit_lc_2exp_size (gmp_randstate_t, mp_bitcnt_t); - -#define gmp_randinit_mt __gmp_randinit_mt -__GMP_DECLSPEC void gmp_randinit_mt (gmp_randstate_t); - -#define gmp_randinit_set __gmp_randinit_set -__GMP_DECLSPEC void gmp_randinit_set (gmp_randstate_t, const __gmp_randstate_struct *); - -#define gmp_randseed __gmp_randseed -__GMP_DECLSPEC void gmp_randseed (gmp_randstate_t, mpz_srcptr); - -#define gmp_randseed_ui __gmp_randseed_ui -__GMP_DECLSPEC void gmp_randseed_ui (gmp_randstate_t, unsigned long int); - -#define gmp_randclear __gmp_randclear -__GMP_DECLSPEC void gmp_randclear (gmp_randstate_t); - -#define gmp_urandomb_ui __gmp_urandomb_ui -__GMP_DECLSPEC unsigned long gmp_urandomb_ui (gmp_randstate_t, unsigned long); - -#define gmp_urandomm_ui __gmp_urandomm_ui -__GMP_DECLSPEC unsigned long gmp_urandomm_ui (gmp_randstate_t, unsigned long); - - -/**************** Formatted output routines. ****************/ - -#define gmp_asprintf __gmp_asprintf -__GMP_DECLSPEC int gmp_asprintf (char **, const char *, ...); - -#define gmp_fprintf __gmp_fprintf -#ifdef _GMP_H_HAVE_FILE -__GMP_DECLSPEC int gmp_fprintf (FILE *, const char *, ...); -#endif - -#define gmp_obstack_printf __gmp_obstack_printf -#if defined (_GMP_H_HAVE_OBSTACK) -__GMP_DECLSPEC int gmp_obstack_printf (struct obstack *, const char *, ...); -#endif - -#define gmp_obstack_vprintf __gmp_obstack_vprintf -#if defined (_GMP_H_HAVE_OBSTACK) && defined (_GMP_H_HAVE_VA_LIST) -__GMP_DECLSPEC int gmp_obstack_vprintf (struct obstack *, const char *, va_list); -#endif - -#define gmp_printf __gmp_printf -__GMP_DECLSPEC int gmp_printf (const char *, ...); - -#define gmp_snprintf __gmp_snprintf -__GMP_DECLSPEC int gmp_snprintf (char *, size_t, const char *, ...); - -#define gmp_sprintf __gmp_sprintf -__GMP_DECLSPEC int gmp_sprintf (char *, const char *, ...); - -#define gmp_vasprintf __gmp_vasprintf -#if defined (_GMP_H_HAVE_VA_LIST) -__GMP_DECLSPEC int gmp_vasprintf (char **, const char *, va_list); -#endif - -#define gmp_vfprintf __gmp_vfprintf -#if defined (_GMP_H_HAVE_FILE) && defined (_GMP_H_HAVE_VA_LIST) -__GMP_DECLSPEC int gmp_vfprintf (FILE *, const char *, va_list); -#endif - -#define gmp_vprintf __gmp_vprintf -#if defined (_GMP_H_HAVE_VA_LIST) -__GMP_DECLSPEC int gmp_vprintf (const char *, va_list); -#endif - -#define gmp_vsnprintf __gmp_vsnprintf -#if defined (_GMP_H_HAVE_VA_LIST) -__GMP_DECLSPEC int gmp_vsnprintf (char *, size_t, const char *, va_list); -#endif - -#define gmp_vsprintf __gmp_vsprintf -#if defined (_GMP_H_HAVE_VA_LIST) -__GMP_DECLSPEC int gmp_vsprintf (char *, const char *, va_list); -#endif - - -/**************** Formatted input routines. ****************/ - -#define gmp_fscanf __gmp_fscanf -#ifdef _GMP_H_HAVE_FILE -__GMP_DECLSPEC int gmp_fscanf (FILE *, const char *, ...); -#endif - -#define gmp_scanf __gmp_scanf -__GMP_DECLSPEC int gmp_scanf (const char *, ...); - -#define gmp_sscanf __gmp_sscanf -__GMP_DECLSPEC int gmp_sscanf (const char *, const char *, ...); - -#define gmp_vfscanf __gmp_vfscanf -#if defined (_GMP_H_HAVE_FILE) && defined (_GMP_H_HAVE_VA_LIST) -__GMP_DECLSPEC int gmp_vfscanf (FILE *, const char *, va_list); -#endif - -#define gmp_vscanf __gmp_vscanf -#if defined (_GMP_H_HAVE_VA_LIST) -__GMP_DECLSPEC int gmp_vscanf (const char *, va_list); -#endif - -#define gmp_vsscanf __gmp_vsscanf -#if defined (_GMP_H_HAVE_VA_LIST) -__GMP_DECLSPEC int gmp_vsscanf (const char *, const char *, va_list); -#endif - - -/**************** Integer (i.e. Z) routines. ****************/ - -#define _mpz_realloc __gmpz_realloc -#define mpz_realloc __gmpz_realloc -__GMP_DECLSPEC void *_mpz_realloc (mpz_ptr, mp_size_t); - -#define mpz_abs __gmpz_abs -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_abs) -__GMP_DECLSPEC void mpz_abs (mpz_ptr, mpz_srcptr); -#endif - -#define mpz_add __gmpz_add -__GMP_DECLSPEC void mpz_add (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_add_ui __gmpz_add_ui -__GMP_DECLSPEC void mpz_add_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_addmul __gmpz_addmul -__GMP_DECLSPEC void mpz_addmul (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_addmul_ui __gmpz_addmul_ui -__GMP_DECLSPEC void mpz_addmul_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_and __gmpz_and -__GMP_DECLSPEC void mpz_and (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_array_init __gmpz_array_init -__GMP_DECLSPEC void mpz_array_init (mpz_ptr, mp_size_t, mp_size_t); - -#define mpz_bin_ui __gmpz_bin_ui -__GMP_DECLSPEC void mpz_bin_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_bin_uiui __gmpz_bin_uiui -__GMP_DECLSPEC void mpz_bin_uiui (mpz_ptr, unsigned long int, unsigned long int); - -#define mpz_cdiv_q __gmpz_cdiv_q -__GMP_DECLSPEC void mpz_cdiv_q (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_cdiv_q_2exp __gmpz_cdiv_q_2exp -__GMP_DECLSPEC void mpz_cdiv_q_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t); - -#define mpz_cdiv_q_ui __gmpz_cdiv_q_ui -__GMP_DECLSPEC unsigned long int mpz_cdiv_q_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_cdiv_qr __gmpz_cdiv_qr -__GMP_DECLSPEC void mpz_cdiv_qr (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_cdiv_qr_ui __gmpz_cdiv_qr_ui -__GMP_DECLSPEC unsigned long int mpz_cdiv_qr_ui (mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_cdiv_r __gmpz_cdiv_r -__GMP_DECLSPEC void mpz_cdiv_r (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_cdiv_r_2exp __gmpz_cdiv_r_2exp -__GMP_DECLSPEC void mpz_cdiv_r_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t); - -#define mpz_cdiv_r_ui __gmpz_cdiv_r_ui -__GMP_DECLSPEC unsigned long int mpz_cdiv_r_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_cdiv_ui __gmpz_cdiv_ui -__GMP_DECLSPEC unsigned long int mpz_cdiv_ui (mpz_srcptr, unsigned long int) __GMP_ATTRIBUTE_PURE; - -#define mpz_clear __gmpz_clear -__GMP_DECLSPEC void mpz_clear (mpz_ptr); - -#define mpz_clears __gmpz_clears -__GMP_DECLSPEC void mpz_clears (mpz_ptr, ...); - -#define mpz_clrbit __gmpz_clrbit -__GMP_DECLSPEC void mpz_clrbit (mpz_ptr, mp_bitcnt_t); - -#define mpz_cmp __gmpz_cmp -__GMP_DECLSPEC int mpz_cmp (mpz_srcptr, mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_cmp_d __gmpz_cmp_d -__GMP_DECLSPEC int mpz_cmp_d (mpz_srcptr, double) __GMP_ATTRIBUTE_PURE; - -#define _mpz_cmp_si __gmpz_cmp_si -__GMP_DECLSPEC int _mpz_cmp_si (mpz_srcptr, signed long int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define _mpz_cmp_ui __gmpz_cmp_ui -__GMP_DECLSPEC int _mpz_cmp_ui (mpz_srcptr, unsigned long int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_cmpabs __gmpz_cmpabs -__GMP_DECLSPEC int mpz_cmpabs (mpz_srcptr, mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_cmpabs_d __gmpz_cmpabs_d -__GMP_DECLSPEC int mpz_cmpabs_d (mpz_srcptr, double) __GMP_ATTRIBUTE_PURE; - -#define mpz_cmpabs_ui __gmpz_cmpabs_ui -__GMP_DECLSPEC int mpz_cmpabs_ui (mpz_srcptr, unsigned long int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_com __gmpz_com -__GMP_DECLSPEC void mpz_com (mpz_ptr, mpz_srcptr); - -#define mpz_combit __gmpz_combit -__GMP_DECLSPEC void mpz_combit (mpz_ptr, mp_bitcnt_t); - -#define mpz_congruent_p __gmpz_congruent_p -__GMP_DECLSPEC int mpz_congruent_p (mpz_srcptr, mpz_srcptr, mpz_srcptr) __GMP_ATTRIBUTE_PURE; - -#define mpz_congruent_2exp_p __gmpz_congruent_2exp_p -__GMP_DECLSPEC int mpz_congruent_2exp_p (mpz_srcptr, mpz_srcptr, mp_bitcnt_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_congruent_ui_p __gmpz_congruent_ui_p -__GMP_DECLSPEC int mpz_congruent_ui_p (mpz_srcptr, unsigned long, unsigned long) __GMP_ATTRIBUTE_PURE; - -#define mpz_divexact __gmpz_divexact -__GMP_DECLSPEC void mpz_divexact (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_divexact_ui __gmpz_divexact_ui -__GMP_DECLSPEC void mpz_divexact_ui (mpz_ptr, mpz_srcptr, unsigned long); - -#define mpz_divisible_p __gmpz_divisible_p -__GMP_DECLSPEC int mpz_divisible_p (mpz_srcptr, mpz_srcptr) __GMP_ATTRIBUTE_PURE; - -#define mpz_divisible_ui_p __gmpz_divisible_ui_p -__GMP_DECLSPEC int mpz_divisible_ui_p (mpz_srcptr, unsigned long) __GMP_ATTRIBUTE_PURE; - -#define mpz_divisible_2exp_p __gmpz_divisible_2exp_p -__GMP_DECLSPEC int mpz_divisible_2exp_p (mpz_srcptr, mp_bitcnt_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_dump __gmpz_dump -__GMP_DECLSPEC void mpz_dump (mpz_srcptr); - -#define mpz_export __gmpz_export -__GMP_DECLSPEC void *mpz_export (void *, size_t *, int, size_t, int, size_t, mpz_srcptr); - -#define mpz_fac_ui __gmpz_fac_ui -__GMP_DECLSPEC void mpz_fac_ui (mpz_ptr, unsigned long int); - -#define mpz_2fac_ui __gmpz_2fac_ui -__GMP_DECLSPEC void mpz_2fac_ui (mpz_ptr, unsigned long int); - -#define mpz_mfac_uiui __gmpz_mfac_uiui -__GMP_DECLSPEC void mpz_mfac_uiui (mpz_ptr, unsigned long int, unsigned long int); - -#define mpz_primorial_ui __gmpz_primorial_ui -__GMP_DECLSPEC void mpz_primorial_ui (mpz_ptr, unsigned long int); - -#define mpz_fdiv_q __gmpz_fdiv_q -__GMP_DECLSPEC void mpz_fdiv_q (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_fdiv_q_2exp __gmpz_fdiv_q_2exp -__GMP_DECLSPEC void mpz_fdiv_q_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t); - -#define mpz_fdiv_q_ui __gmpz_fdiv_q_ui -__GMP_DECLSPEC unsigned long int mpz_fdiv_q_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_fdiv_qr __gmpz_fdiv_qr -__GMP_DECLSPEC void mpz_fdiv_qr (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_fdiv_qr_ui __gmpz_fdiv_qr_ui -__GMP_DECLSPEC unsigned long int mpz_fdiv_qr_ui (mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_fdiv_r __gmpz_fdiv_r -__GMP_DECLSPEC void mpz_fdiv_r (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_fdiv_r_2exp __gmpz_fdiv_r_2exp -__GMP_DECLSPEC void mpz_fdiv_r_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t); - -#define mpz_fdiv_r_ui __gmpz_fdiv_r_ui -__GMP_DECLSPEC unsigned long int mpz_fdiv_r_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_fdiv_ui __gmpz_fdiv_ui -__GMP_DECLSPEC unsigned long int mpz_fdiv_ui (mpz_srcptr, unsigned long int) __GMP_ATTRIBUTE_PURE; - -#define mpz_fib_ui __gmpz_fib_ui -__GMP_DECLSPEC void mpz_fib_ui (mpz_ptr, unsigned long int); - -#define mpz_fib2_ui __gmpz_fib2_ui -__GMP_DECLSPEC void mpz_fib2_ui (mpz_ptr, mpz_ptr, unsigned long int); - -#define mpz_fits_sint_p __gmpz_fits_sint_p -__GMP_DECLSPEC int mpz_fits_sint_p (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_fits_slong_p __gmpz_fits_slong_p -__GMP_DECLSPEC int mpz_fits_slong_p (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_fits_sshort_p __gmpz_fits_sshort_p -__GMP_DECLSPEC int mpz_fits_sshort_p (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_fits_uint_p __gmpz_fits_uint_p -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_fits_uint_p) -__GMP_DECLSPEC int mpz_fits_uint_p (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; -#endif - -#define mpz_fits_ulong_p __gmpz_fits_ulong_p -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_fits_ulong_p) -__GMP_DECLSPEC int mpz_fits_ulong_p (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; -#endif - -#define mpz_fits_ushort_p __gmpz_fits_ushort_p -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_fits_ushort_p) -__GMP_DECLSPEC int mpz_fits_ushort_p (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; -#endif - -#define mpz_gcd __gmpz_gcd -__GMP_DECLSPEC void mpz_gcd (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_gcd_ui __gmpz_gcd_ui -__GMP_DECLSPEC unsigned long int mpz_gcd_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_gcdext __gmpz_gcdext -__GMP_DECLSPEC void mpz_gcdext (mpz_ptr, mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_get_d __gmpz_get_d -__GMP_DECLSPEC double mpz_get_d (mpz_srcptr) __GMP_ATTRIBUTE_PURE; - -#define mpz_get_d_2exp __gmpz_get_d_2exp -__GMP_DECLSPEC double mpz_get_d_2exp (signed long int *, mpz_srcptr); - -#define mpz_get_si __gmpz_get_si -__GMP_DECLSPEC /* signed */ long int mpz_get_si (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_get_str __gmpz_get_str -__GMP_DECLSPEC char *mpz_get_str (char *, int, mpz_srcptr); - -#define mpz_get_ui __gmpz_get_ui -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_get_ui) -__GMP_DECLSPEC unsigned long int mpz_get_ui (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; -#endif - -#define mpz_getlimbn __gmpz_getlimbn -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_getlimbn) -__GMP_DECLSPEC mp_limb_t mpz_getlimbn (mpz_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; -#endif - -#define mpz_hamdist __gmpz_hamdist -__GMP_DECLSPEC mp_bitcnt_t mpz_hamdist (mpz_srcptr, mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_import __gmpz_import -__GMP_DECLSPEC void mpz_import (mpz_ptr, size_t, int, size_t, int, size_t, const void *); - -#define mpz_init __gmpz_init -__GMP_DECLSPEC void mpz_init (mpz_ptr) __GMP_NOTHROW; - -#define mpz_init2 __gmpz_init2 -__GMP_DECLSPEC void mpz_init2 (mpz_ptr, mp_bitcnt_t); - -#define mpz_inits __gmpz_inits -__GMP_DECLSPEC void mpz_inits (mpz_ptr, ...) __GMP_NOTHROW; - -#define mpz_init_set __gmpz_init_set -__GMP_DECLSPEC void mpz_init_set (mpz_ptr, mpz_srcptr); - -#define mpz_init_set_d __gmpz_init_set_d -__GMP_DECLSPEC void mpz_init_set_d (mpz_ptr, double); - -#define mpz_init_set_si __gmpz_init_set_si -__GMP_DECLSPEC void mpz_init_set_si (mpz_ptr, signed long int); - -#define mpz_init_set_str __gmpz_init_set_str -__GMP_DECLSPEC int mpz_init_set_str (mpz_ptr, const char *, int); - -#define mpz_init_set_ui __gmpz_init_set_ui -__GMP_DECLSPEC void mpz_init_set_ui (mpz_ptr, unsigned long int); - -#define mpz_inp_raw __gmpz_inp_raw -#ifdef _GMP_H_HAVE_FILE -__GMP_DECLSPEC size_t mpz_inp_raw (mpz_ptr, FILE *); -#endif - -#define mpz_inp_str __gmpz_inp_str -#ifdef _GMP_H_HAVE_FILE -__GMP_DECLSPEC size_t mpz_inp_str (mpz_ptr, FILE *, int); -#endif - -#define mpz_invert __gmpz_invert -__GMP_DECLSPEC int mpz_invert (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_ior __gmpz_ior -__GMP_DECLSPEC void mpz_ior (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_jacobi __gmpz_jacobi -__GMP_DECLSPEC int mpz_jacobi (mpz_srcptr, mpz_srcptr) __GMP_ATTRIBUTE_PURE; - -#define mpz_kronecker mpz_jacobi /* alias */ - -#define mpz_kronecker_si __gmpz_kronecker_si -__GMP_DECLSPEC int mpz_kronecker_si (mpz_srcptr, long) __GMP_ATTRIBUTE_PURE; - -#define mpz_kronecker_ui __gmpz_kronecker_ui -__GMP_DECLSPEC int mpz_kronecker_ui (mpz_srcptr, unsigned long) __GMP_ATTRIBUTE_PURE; - -#define mpz_si_kronecker __gmpz_si_kronecker -__GMP_DECLSPEC int mpz_si_kronecker (long, mpz_srcptr) __GMP_ATTRIBUTE_PURE; - -#define mpz_ui_kronecker __gmpz_ui_kronecker -__GMP_DECLSPEC int mpz_ui_kronecker (unsigned long, mpz_srcptr) __GMP_ATTRIBUTE_PURE; - -#define mpz_lcm __gmpz_lcm -__GMP_DECLSPEC void mpz_lcm (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_lcm_ui __gmpz_lcm_ui -__GMP_DECLSPEC void mpz_lcm_ui (mpz_ptr, mpz_srcptr, unsigned long); - -#define mpz_legendre mpz_jacobi /* alias */ - -#define mpz_lucnum_ui __gmpz_lucnum_ui -__GMP_DECLSPEC void mpz_lucnum_ui (mpz_ptr, unsigned long int); - -#define mpz_lucnum2_ui __gmpz_lucnum2_ui -__GMP_DECLSPEC void mpz_lucnum2_ui (mpz_ptr, mpz_ptr, unsigned long int); - -#define mpz_millerrabin __gmpz_millerrabin -__GMP_DECLSPEC int mpz_millerrabin (mpz_srcptr, int) __GMP_ATTRIBUTE_PURE; - -#define mpz_mod __gmpz_mod -__GMP_DECLSPEC void mpz_mod (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_mod_ui mpz_fdiv_r_ui /* same as fdiv_r because divisor unsigned */ - -#define mpz_mul __gmpz_mul -__GMP_DECLSPEC void mpz_mul (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_mul_2exp __gmpz_mul_2exp -__GMP_DECLSPEC void mpz_mul_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t); - -#define mpz_mul_si __gmpz_mul_si -__GMP_DECLSPEC void mpz_mul_si (mpz_ptr, mpz_srcptr, long int); - -#define mpz_mul_ui __gmpz_mul_ui -__GMP_DECLSPEC void mpz_mul_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_neg __gmpz_neg -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_neg) -__GMP_DECLSPEC void mpz_neg (mpz_ptr, mpz_srcptr); -#endif - -#define mpz_nextprime __gmpz_nextprime -__GMP_DECLSPEC void mpz_nextprime (mpz_ptr, mpz_srcptr); - -#define mpz_out_raw __gmpz_out_raw -#ifdef _GMP_H_HAVE_FILE -__GMP_DECLSPEC size_t mpz_out_raw (FILE *, mpz_srcptr); -#endif - -#define mpz_out_str __gmpz_out_str -#ifdef _GMP_H_HAVE_FILE -__GMP_DECLSPEC size_t mpz_out_str (FILE *, int, mpz_srcptr); -#endif - -#define mpz_perfect_power_p __gmpz_perfect_power_p -__GMP_DECLSPEC int mpz_perfect_power_p (mpz_srcptr) __GMP_ATTRIBUTE_PURE; - -#define mpz_perfect_square_p __gmpz_perfect_square_p -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_perfect_square_p) -__GMP_DECLSPEC int mpz_perfect_square_p (mpz_srcptr) __GMP_ATTRIBUTE_PURE; -#endif - -#define mpz_popcount __gmpz_popcount -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_popcount) -__GMP_DECLSPEC mp_bitcnt_t mpz_popcount (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; -#endif - -#define mpz_pow_ui __gmpz_pow_ui -__GMP_DECLSPEC void mpz_pow_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_powm __gmpz_powm -__GMP_DECLSPEC void mpz_powm (mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr); - -#define mpz_powm_sec __gmpz_powm_sec -__GMP_DECLSPEC void mpz_powm_sec (mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr); - -#define mpz_powm_ui __gmpz_powm_ui -__GMP_DECLSPEC void mpz_powm_ui (mpz_ptr, mpz_srcptr, unsigned long int, mpz_srcptr); - -#define mpz_probab_prime_p __gmpz_probab_prime_p -__GMP_DECLSPEC int mpz_probab_prime_p (mpz_srcptr, int) __GMP_ATTRIBUTE_PURE; - -#define mpz_random __gmpz_random -__GMP_DECLSPEC void mpz_random (mpz_ptr, mp_size_t); - -#define mpz_random2 __gmpz_random2 -__GMP_DECLSPEC void mpz_random2 (mpz_ptr, mp_size_t); - -#define mpz_realloc2 __gmpz_realloc2 -__GMP_DECLSPEC void mpz_realloc2 (mpz_ptr, mp_bitcnt_t); - -#define mpz_remove __gmpz_remove -__GMP_DECLSPEC mp_bitcnt_t mpz_remove (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_root __gmpz_root -__GMP_DECLSPEC int mpz_root (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_rootrem __gmpz_rootrem -__GMP_DECLSPEC void mpz_rootrem (mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_rrandomb __gmpz_rrandomb -__GMP_DECLSPEC void mpz_rrandomb (mpz_ptr, gmp_randstate_t, mp_bitcnt_t); - -#define mpz_scan0 __gmpz_scan0 -__GMP_DECLSPEC mp_bitcnt_t mpz_scan0 (mpz_srcptr, mp_bitcnt_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_scan1 __gmpz_scan1 -__GMP_DECLSPEC mp_bitcnt_t mpz_scan1 (mpz_srcptr, mp_bitcnt_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_set __gmpz_set -__GMP_DECLSPEC void mpz_set (mpz_ptr, mpz_srcptr); - -#define mpz_set_d __gmpz_set_d -__GMP_DECLSPEC void mpz_set_d (mpz_ptr, double); - -#define mpz_set_f __gmpz_set_f -__GMP_DECLSPEC void mpz_set_f (mpz_ptr, mpf_srcptr); - -#define mpz_set_q __gmpz_set_q -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_set_q) -__GMP_DECLSPEC void mpz_set_q (mpz_ptr, mpq_srcptr); -#endif - -#define mpz_set_si __gmpz_set_si -__GMP_DECLSPEC void mpz_set_si (mpz_ptr, signed long int); - -#define mpz_set_str __gmpz_set_str -__GMP_DECLSPEC int mpz_set_str (mpz_ptr, const char *, int); - -#define mpz_set_ui __gmpz_set_ui -__GMP_DECLSPEC void mpz_set_ui (mpz_ptr, unsigned long int); - -#define mpz_setbit __gmpz_setbit -__GMP_DECLSPEC void mpz_setbit (mpz_ptr, mp_bitcnt_t); - -#define mpz_size __gmpz_size -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_size) -__GMP_DECLSPEC size_t mpz_size (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; -#endif - -#define mpz_sizeinbase __gmpz_sizeinbase -__GMP_DECLSPEC size_t mpz_sizeinbase (mpz_srcptr, int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_sqrt __gmpz_sqrt -__GMP_DECLSPEC void mpz_sqrt (mpz_ptr, mpz_srcptr); - -#define mpz_sqrtrem __gmpz_sqrtrem -__GMP_DECLSPEC void mpz_sqrtrem (mpz_ptr, mpz_ptr, mpz_srcptr); - -#define mpz_sub __gmpz_sub -__GMP_DECLSPEC void mpz_sub (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_sub_ui __gmpz_sub_ui -__GMP_DECLSPEC void mpz_sub_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_ui_sub __gmpz_ui_sub -__GMP_DECLSPEC void mpz_ui_sub (mpz_ptr, unsigned long int, mpz_srcptr); - -#define mpz_submul __gmpz_submul -__GMP_DECLSPEC void mpz_submul (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_submul_ui __gmpz_submul_ui -__GMP_DECLSPEC void mpz_submul_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_swap __gmpz_swap -__GMP_DECLSPEC void mpz_swap (mpz_ptr, mpz_ptr) __GMP_NOTHROW; - -#define mpz_tdiv_ui __gmpz_tdiv_ui -__GMP_DECLSPEC unsigned long int mpz_tdiv_ui (mpz_srcptr, unsigned long int) __GMP_ATTRIBUTE_PURE; - -#define mpz_tdiv_q __gmpz_tdiv_q -__GMP_DECLSPEC void mpz_tdiv_q (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_tdiv_q_2exp __gmpz_tdiv_q_2exp -__GMP_DECLSPEC void mpz_tdiv_q_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t); - -#define mpz_tdiv_q_ui __gmpz_tdiv_q_ui -__GMP_DECLSPEC unsigned long int mpz_tdiv_q_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_tdiv_qr __gmpz_tdiv_qr -__GMP_DECLSPEC void mpz_tdiv_qr (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_tdiv_qr_ui __gmpz_tdiv_qr_ui -__GMP_DECLSPEC unsigned long int mpz_tdiv_qr_ui (mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_tdiv_r __gmpz_tdiv_r -__GMP_DECLSPEC void mpz_tdiv_r (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_tdiv_r_2exp __gmpz_tdiv_r_2exp -__GMP_DECLSPEC void mpz_tdiv_r_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t); - -#define mpz_tdiv_r_ui __gmpz_tdiv_r_ui -__GMP_DECLSPEC unsigned long int mpz_tdiv_r_ui (mpz_ptr, mpz_srcptr, unsigned long int); - -#define mpz_tstbit __gmpz_tstbit -__GMP_DECLSPEC int mpz_tstbit (mpz_srcptr, mp_bitcnt_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpz_ui_pow_ui __gmpz_ui_pow_ui -__GMP_DECLSPEC void mpz_ui_pow_ui (mpz_ptr, unsigned long int, unsigned long int); - -#define mpz_urandomb __gmpz_urandomb -__GMP_DECLSPEC void mpz_urandomb (mpz_ptr, gmp_randstate_t, mp_bitcnt_t); - -#define mpz_urandomm __gmpz_urandomm -__GMP_DECLSPEC void mpz_urandomm (mpz_ptr, gmp_randstate_t, mpz_srcptr); - -#define mpz_xor __gmpz_xor -#define mpz_eor __gmpz_xor -__GMP_DECLSPEC void mpz_xor (mpz_ptr, mpz_srcptr, mpz_srcptr); - -#define mpz_limbs_read __gmpz_limbs_read -__GMP_DECLSPEC mp_srcptr mpz_limbs_read (mpz_srcptr); - -#define mpz_limbs_write __gmpz_limbs_write -__GMP_DECLSPEC mp_ptr mpz_limbs_write (mpz_ptr, mp_size_t); - -#define mpz_limbs_modify __gmpz_limbs_modify -__GMP_DECLSPEC mp_ptr mpz_limbs_modify (mpz_ptr, mp_size_t); - -#define mpz_limbs_finish __gmpz_limbs_finish -__GMP_DECLSPEC void mpz_limbs_finish (mpz_ptr, mp_size_t); - -#define mpz_roinit_n __gmpz_roinit_n -__GMP_DECLSPEC mpz_srcptr mpz_roinit_n (mpz_ptr, mp_srcptr, mp_size_t); - -#define MPZ_ROINIT_N(xp, xs) {{0, (xs),(xp) }} - -/**************** Rational (i.e. Q) routines. ****************/ - -#define mpq_abs __gmpq_abs -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpq_abs) -__GMP_DECLSPEC void mpq_abs (mpq_ptr, mpq_srcptr); -#endif - -#define mpq_add __gmpq_add -__GMP_DECLSPEC void mpq_add (mpq_ptr, mpq_srcptr, mpq_srcptr); - -#define mpq_canonicalize __gmpq_canonicalize -__GMP_DECLSPEC void mpq_canonicalize (mpq_ptr); - -#define mpq_clear __gmpq_clear -__GMP_DECLSPEC void mpq_clear (mpq_ptr); - -#define mpq_clears __gmpq_clears -__GMP_DECLSPEC void mpq_clears (mpq_ptr, ...); - -#define mpq_cmp __gmpq_cmp -__GMP_DECLSPEC int mpq_cmp (mpq_srcptr, mpq_srcptr) __GMP_ATTRIBUTE_PURE; - -#define _mpq_cmp_si __gmpq_cmp_si -__GMP_DECLSPEC int _mpq_cmp_si (mpq_srcptr, long, unsigned long) __GMP_ATTRIBUTE_PURE; - -#define _mpq_cmp_ui __gmpq_cmp_ui -__GMP_DECLSPEC int _mpq_cmp_ui (mpq_srcptr, unsigned long int, unsigned long int) __GMP_ATTRIBUTE_PURE; - -#define mpq_cmp_z __gmpq_cmp_z -__GMP_DECLSPEC int mpq_cmp_z (mpq_srcptr, mpz_srcptr) __GMP_ATTRIBUTE_PURE; - -#define mpq_div __gmpq_div -__GMP_DECLSPEC void mpq_div (mpq_ptr, mpq_srcptr, mpq_srcptr); - -#define mpq_div_2exp __gmpq_div_2exp -__GMP_DECLSPEC void mpq_div_2exp (mpq_ptr, mpq_srcptr, mp_bitcnt_t); - -#define mpq_equal __gmpq_equal -__GMP_DECLSPEC int mpq_equal (mpq_srcptr, mpq_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpq_get_num __gmpq_get_num -__GMP_DECLSPEC void mpq_get_num (mpz_ptr, mpq_srcptr); - -#define mpq_get_den __gmpq_get_den -__GMP_DECLSPEC void mpq_get_den (mpz_ptr, mpq_srcptr); - -#define mpq_get_d __gmpq_get_d -__GMP_DECLSPEC double mpq_get_d (mpq_srcptr) __GMP_ATTRIBUTE_PURE; - -#define mpq_get_str __gmpq_get_str -__GMP_DECLSPEC char *mpq_get_str (char *, int, mpq_srcptr); - -#define mpq_init __gmpq_init -__GMP_DECLSPEC void mpq_init (mpq_ptr); - -#define mpq_inits __gmpq_inits -__GMP_DECLSPEC void mpq_inits (mpq_ptr, ...); - -#define mpq_inp_str __gmpq_inp_str -#ifdef _GMP_H_HAVE_FILE -__GMP_DECLSPEC size_t mpq_inp_str (mpq_ptr, FILE *, int); -#endif - -#define mpq_inv __gmpq_inv -__GMP_DECLSPEC void mpq_inv (mpq_ptr, mpq_srcptr); - -#define mpq_mul __gmpq_mul -__GMP_DECLSPEC void mpq_mul (mpq_ptr, mpq_srcptr, mpq_srcptr); - -#define mpq_mul_2exp __gmpq_mul_2exp -__GMP_DECLSPEC void mpq_mul_2exp (mpq_ptr, mpq_srcptr, mp_bitcnt_t); - -#define mpq_neg __gmpq_neg -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpq_neg) -__GMP_DECLSPEC void mpq_neg (mpq_ptr, mpq_srcptr); -#endif - -#define mpq_out_str __gmpq_out_str -#ifdef _GMP_H_HAVE_FILE -__GMP_DECLSPEC size_t mpq_out_str (FILE *, int, mpq_srcptr); -#endif - -#define mpq_set __gmpq_set -__GMP_DECLSPEC void mpq_set (mpq_ptr, mpq_srcptr); - -#define mpq_set_d __gmpq_set_d -__GMP_DECLSPEC void mpq_set_d (mpq_ptr, double); - -#define mpq_set_den __gmpq_set_den -__GMP_DECLSPEC void mpq_set_den (mpq_ptr, mpz_srcptr); - -#define mpq_set_f __gmpq_set_f -__GMP_DECLSPEC void mpq_set_f (mpq_ptr, mpf_srcptr); - -#define mpq_set_num __gmpq_set_num -__GMP_DECLSPEC void mpq_set_num (mpq_ptr, mpz_srcptr); - -#define mpq_set_si __gmpq_set_si -__GMP_DECLSPEC void mpq_set_si (mpq_ptr, signed long int, unsigned long int); - -#define mpq_set_str __gmpq_set_str -__GMP_DECLSPEC int mpq_set_str (mpq_ptr, const char *, int); - -#define mpq_set_ui __gmpq_set_ui -__GMP_DECLSPEC void mpq_set_ui (mpq_ptr, unsigned long int, unsigned long int); - -#define mpq_set_z __gmpq_set_z -__GMP_DECLSPEC void mpq_set_z (mpq_ptr, mpz_srcptr); - -#define mpq_sub __gmpq_sub -__GMP_DECLSPEC void mpq_sub (mpq_ptr, mpq_srcptr, mpq_srcptr); - -#define mpq_swap __gmpq_swap -__GMP_DECLSPEC void mpq_swap (mpq_ptr, mpq_ptr) __GMP_NOTHROW; - - -/**************** Float (i.e. F) routines. ****************/ - -#define mpf_abs __gmpf_abs -__GMP_DECLSPEC void mpf_abs (mpf_ptr, mpf_srcptr); - -#define mpf_add __gmpf_add -__GMP_DECLSPEC void mpf_add (mpf_ptr, mpf_srcptr, mpf_srcptr); - -#define mpf_add_ui __gmpf_add_ui -__GMP_DECLSPEC void mpf_add_ui (mpf_ptr, mpf_srcptr, unsigned long int); -#define mpf_ceil __gmpf_ceil -__GMP_DECLSPEC void mpf_ceil (mpf_ptr, mpf_srcptr); - -#define mpf_clear __gmpf_clear -__GMP_DECLSPEC void mpf_clear (mpf_ptr); - -#define mpf_clears __gmpf_clears -__GMP_DECLSPEC void mpf_clears (mpf_ptr, ...); - -#define mpf_cmp __gmpf_cmp -__GMP_DECLSPEC int mpf_cmp (mpf_srcptr, mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_cmp_z __gmpf_cmp_z -__GMP_DECLSPEC int mpf_cmp_z (mpf_srcptr, mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_cmp_d __gmpf_cmp_d -__GMP_DECLSPEC int mpf_cmp_d (mpf_srcptr, double) __GMP_ATTRIBUTE_PURE; - -#define mpf_cmp_si __gmpf_cmp_si -__GMP_DECLSPEC int mpf_cmp_si (mpf_srcptr, signed long int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_cmp_ui __gmpf_cmp_ui -__GMP_DECLSPEC int mpf_cmp_ui (mpf_srcptr, unsigned long int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_div __gmpf_div -__GMP_DECLSPEC void mpf_div (mpf_ptr, mpf_srcptr, mpf_srcptr); - -#define mpf_div_2exp __gmpf_div_2exp -__GMP_DECLSPEC void mpf_div_2exp (mpf_ptr, mpf_srcptr, mp_bitcnt_t); - -#define mpf_div_ui __gmpf_div_ui -__GMP_DECLSPEC void mpf_div_ui (mpf_ptr, mpf_srcptr, unsigned long int); - -#define mpf_dump __gmpf_dump -__GMP_DECLSPEC void mpf_dump (mpf_srcptr); - -#define mpf_eq __gmpf_eq -__GMP_DECLSPEC int mpf_eq (mpf_srcptr, mpf_srcptr, mp_bitcnt_t) __GMP_ATTRIBUTE_PURE; - -#define mpf_fits_sint_p __gmpf_fits_sint_p -__GMP_DECLSPEC int mpf_fits_sint_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_fits_slong_p __gmpf_fits_slong_p -__GMP_DECLSPEC int mpf_fits_slong_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_fits_sshort_p __gmpf_fits_sshort_p -__GMP_DECLSPEC int mpf_fits_sshort_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_fits_uint_p __gmpf_fits_uint_p -__GMP_DECLSPEC int mpf_fits_uint_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_fits_ulong_p __gmpf_fits_ulong_p -__GMP_DECLSPEC int mpf_fits_ulong_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_fits_ushort_p __gmpf_fits_ushort_p -__GMP_DECLSPEC int mpf_fits_ushort_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_floor __gmpf_floor -__GMP_DECLSPEC void mpf_floor (mpf_ptr, mpf_srcptr); - -#define mpf_get_d __gmpf_get_d -__GMP_DECLSPEC double mpf_get_d (mpf_srcptr) __GMP_ATTRIBUTE_PURE; - -#define mpf_get_d_2exp __gmpf_get_d_2exp -__GMP_DECLSPEC double mpf_get_d_2exp (signed long int *, mpf_srcptr); - -#define mpf_get_default_prec __gmpf_get_default_prec -__GMP_DECLSPEC mp_bitcnt_t mpf_get_default_prec (void) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_get_prec __gmpf_get_prec -__GMP_DECLSPEC mp_bitcnt_t mpf_get_prec (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_get_si __gmpf_get_si -__GMP_DECLSPEC long mpf_get_si (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_get_str __gmpf_get_str -__GMP_DECLSPEC char *mpf_get_str (char *, mp_exp_t *, int, size_t, mpf_srcptr); - -#define mpf_get_ui __gmpf_get_ui -__GMP_DECLSPEC unsigned long mpf_get_ui (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_init __gmpf_init -__GMP_DECLSPEC void mpf_init (mpf_ptr); - -#define mpf_init2 __gmpf_init2 -__GMP_DECLSPEC void mpf_init2 (mpf_ptr, mp_bitcnt_t); - -#define mpf_inits __gmpf_inits -__GMP_DECLSPEC void mpf_inits (mpf_ptr, ...); - -#define mpf_init_set __gmpf_init_set -__GMP_DECLSPEC void mpf_init_set (mpf_ptr, mpf_srcptr); - -#define mpf_init_set_d __gmpf_init_set_d -__GMP_DECLSPEC void mpf_init_set_d (mpf_ptr, double); - -#define mpf_init_set_si __gmpf_init_set_si -__GMP_DECLSPEC void mpf_init_set_si (mpf_ptr, signed long int); - -#define mpf_init_set_str __gmpf_init_set_str -__GMP_DECLSPEC int mpf_init_set_str (mpf_ptr, const char *, int); - -#define mpf_init_set_ui __gmpf_init_set_ui -__GMP_DECLSPEC void mpf_init_set_ui (mpf_ptr, unsigned long int); - -#define mpf_inp_str __gmpf_inp_str -#ifdef _GMP_H_HAVE_FILE -__GMP_DECLSPEC size_t mpf_inp_str (mpf_ptr, FILE *, int); -#endif - -#define mpf_integer_p __gmpf_integer_p -__GMP_DECLSPEC int mpf_integer_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_mul __gmpf_mul -__GMP_DECLSPEC void mpf_mul (mpf_ptr, mpf_srcptr, mpf_srcptr); - -#define mpf_mul_2exp __gmpf_mul_2exp -__GMP_DECLSPEC void mpf_mul_2exp (mpf_ptr, mpf_srcptr, mp_bitcnt_t); - -#define mpf_mul_ui __gmpf_mul_ui -__GMP_DECLSPEC void mpf_mul_ui (mpf_ptr, mpf_srcptr, unsigned long int); - -#define mpf_neg __gmpf_neg -__GMP_DECLSPEC void mpf_neg (mpf_ptr, mpf_srcptr); - -#define mpf_out_str __gmpf_out_str -#ifdef _GMP_H_HAVE_FILE -__GMP_DECLSPEC size_t mpf_out_str (FILE *, int, size_t, mpf_srcptr); -#endif - -#define mpf_pow_ui __gmpf_pow_ui -__GMP_DECLSPEC void mpf_pow_ui (mpf_ptr, mpf_srcptr, unsigned long int); - -#define mpf_random2 __gmpf_random2 -__GMP_DECLSPEC void mpf_random2 (mpf_ptr, mp_size_t, mp_exp_t); - -#define mpf_reldiff __gmpf_reldiff -__GMP_DECLSPEC void mpf_reldiff (mpf_ptr, mpf_srcptr, mpf_srcptr); - -#define mpf_set __gmpf_set -__GMP_DECLSPEC void mpf_set (mpf_ptr, mpf_srcptr); - -#define mpf_set_d __gmpf_set_d -__GMP_DECLSPEC void mpf_set_d (mpf_ptr, double); - -#define mpf_set_default_prec __gmpf_set_default_prec -__GMP_DECLSPEC void mpf_set_default_prec (mp_bitcnt_t) __GMP_NOTHROW; - -#define mpf_set_prec __gmpf_set_prec -__GMP_DECLSPEC void mpf_set_prec (mpf_ptr, mp_bitcnt_t); - -#define mpf_set_prec_raw __gmpf_set_prec_raw -__GMP_DECLSPEC void mpf_set_prec_raw (mpf_ptr, mp_bitcnt_t) __GMP_NOTHROW; - -#define mpf_set_q __gmpf_set_q -__GMP_DECLSPEC void mpf_set_q (mpf_ptr, mpq_srcptr); - -#define mpf_set_si __gmpf_set_si -__GMP_DECLSPEC void mpf_set_si (mpf_ptr, signed long int); - -#define mpf_set_str __gmpf_set_str -__GMP_DECLSPEC int mpf_set_str (mpf_ptr, const char *, int); - -#define mpf_set_ui __gmpf_set_ui -__GMP_DECLSPEC void mpf_set_ui (mpf_ptr, unsigned long int); - -#define mpf_set_z __gmpf_set_z -__GMP_DECLSPEC void mpf_set_z (mpf_ptr, mpz_srcptr); - -#define mpf_size __gmpf_size -__GMP_DECLSPEC size_t mpf_size (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpf_sqrt __gmpf_sqrt -__GMP_DECLSPEC void mpf_sqrt (mpf_ptr, mpf_srcptr); - -#define mpf_sqrt_ui __gmpf_sqrt_ui -__GMP_DECLSPEC void mpf_sqrt_ui (mpf_ptr, unsigned long int); - -#define mpf_sub __gmpf_sub -__GMP_DECLSPEC void mpf_sub (mpf_ptr, mpf_srcptr, mpf_srcptr); - -#define mpf_sub_ui __gmpf_sub_ui -__GMP_DECLSPEC void mpf_sub_ui (mpf_ptr, mpf_srcptr, unsigned long int); - -#define mpf_swap __gmpf_swap -__GMP_DECLSPEC void mpf_swap (mpf_ptr, mpf_ptr) __GMP_NOTHROW; - -#define mpf_trunc __gmpf_trunc -__GMP_DECLSPEC void mpf_trunc (mpf_ptr, mpf_srcptr); - -#define mpf_ui_div __gmpf_ui_div -__GMP_DECLSPEC void mpf_ui_div (mpf_ptr, unsigned long int, mpf_srcptr); - -#define mpf_ui_sub __gmpf_ui_sub -__GMP_DECLSPEC void mpf_ui_sub (mpf_ptr, unsigned long int, mpf_srcptr); - -#define mpf_urandomb __gmpf_urandomb -__GMP_DECLSPEC void mpf_urandomb (mpf_t, gmp_randstate_t, mp_bitcnt_t); - - -/************ Low level positive-integer (i.e. N) routines. ************/ - -/* This is ugly, but we need to make user calls reach the prefixed function. */ - -#define mpn_add __MPN(add) -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_add) -__GMP_DECLSPEC mp_limb_t mpn_add (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); -#endif - -#define mpn_add_1 __MPN(add_1) -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_add_1) -__GMP_DECLSPEC mp_limb_t mpn_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t) __GMP_NOTHROW; -#endif - -#define mpn_add_n __MPN(add_n) -__GMP_DECLSPEC mp_limb_t mpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); - -#define mpn_addmul_1 __MPN(addmul_1) -__GMP_DECLSPEC mp_limb_t mpn_addmul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); - -#define mpn_cmp __MPN(cmp) -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_cmp) -__GMP_DECLSPEC int mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; -#endif - -#define mpn_zero_p __MPN(zero_p) -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_zero_p) -__GMP_DECLSPEC int mpn_zero_p (mp_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; -#endif - -#define mpn_divexact_1 __MPN(divexact_1) -__GMP_DECLSPEC void mpn_divexact_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); - -#define mpn_divexact_by3(dst,src,size) \ - mpn_divexact_by3c (dst, src, size, __GMP_CAST (mp_limb_t, 0)) - -#define mpn_divexact_by3c __MPN(divexact_by3c) -__GMP_DECLSPEC mp_limb_t mpn_divexact_by3c (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); - -#define mpn_divmod_1(qp,np,nsize,dlimb) \ - mpn_divrem_1 (qp, __GMP_CAST (mp_size_t, 0), np, nsize, dlimb) - -#define mpn_divrem __MPN(divrem) -__GMP_DECLSPEC mp_limb_t mpn_divrem (mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr, mp_size_t); - -#define mpn_divrem_1 __MPN(divrem_1) -__GMP_DECLSPEC mp_limb_t mpn_divrem_1 (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t); - -#define mpn_divrem_2 __MPN(divrem_2) -__GMP_DECLSPEC mp_limb_t mpn_divrem_2 (mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr); - -#define mpn_div_qr_1 __MPN(div_qr_1) -__GMP_DECLSPEC mp_limb_t mpn_div_qr_1 (mp_ptr, mp_limb_t *, mp_srcptr, mp_size_t, mp_limb_t); - -#define mpn_div_qr_2 __MPN(div_qr_2) -__GMP_DECLSPEC mp_limb_t mpn_div_qr_2 (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_srcptr); - -#define mpn_gcd __MPN(gcd) -__GMP_DECLSPEC mp_size_t mpn_gcd (mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t); - -#define mpn_gcd_11 __MPN(gcd_11) -__GMP_DECLSPEC mp_limb_t mpn_gcd_11 (mp_limb_t, mp_limb_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_gcd_1 __MPN(gcd_1) -__GMP_DECLSPEC mp_limb_t mpn_gcd_1 (mp_srcptr, mp_size_t, mp_limb_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_gcdext_1 __MPN(gcdext_1) -__GMP_DECLSPEC mp_limb_t mpn_gcdext_1 (mp_limb_signed_t *, mp_limb_signed_t *, mp_limb_t, mp_limb_t); - -#define mpn_gcdext __MPN(gcdext) -__GMP_DECLSPEC mp_size_t mpn_gcdext (mp_ptr, mp_ptr, mp_size_t *, mp_ptr, mp_size_t, mp_ptr, mp_size_t); - -#define mpn_get_str __MPN(get_str) -__GMP_DECLSPEC size_t mpn_get_str (unsigned char *, int, mp_ptr, mp_size_t); - -#define mpn_hamdist __MPN(hamdist) -__GMP_DECLSPEC mp_bitcnt_t mpn_hamdist (mp_srcptr, mp_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpn_lshift __MPN(lshift) -__GMP_DECLSPEC mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); - -#define mpn_mod_1 __MPN(mod_1) -__GMP_DECLSPEC mp_limb_t mpn_mod_1 (mp_srcptr, mp_size_t, mp_limb_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_mul __MPN(mul) -__GMP_DECLSPEC mp_limb_t mpn_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); - -#define mpn_mul_1 __MPN(mul_1) -__GMP_DECLSPEC mp_limb_t mpn_mul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); - -#define mpn_mul_n __MPN(mul_n) -__GMP_DECLSPEC void mpn_mul_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); - -#define mpn_sqr __MPN(sqr) -__GMP_DECLSPEC void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t); - -#define mpn_neg __MPN(neg) -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_neg) -__GMP_DECLSPEC mp_limb_t mpn_neg (mp_ptr, mp_srcptr, mp_size_t); -#endif - -#define mpn_com __MPN(com) -__GMP_DECLSPEC void mpn_com (mp_ptr, mp_srcptr, mp_size_t); - -#define mpn_perfect_square_p __MPN(perfect_square_p) -__GMP_DECLSPEC int mpn_perfect_square_p (mp_srcptr, mp_size_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_perfect_power_p __MPN(perfect_power_p) -__GMP_DECLSPEC int mpn_perfect_power_p (mp_srcptr, mp_size_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_popcount __MPN(popcount) -__GMP_DECLSPEC mp_bitcnt_t mpn_popcount (mp_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE; - -#define mpn_pow_1 __MPN(pow_1) -__GMP_DECLSPEC mp_size_t mpn_pow_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr); - -/* undocumented now, but retained here for upward compatibility */ -#define mpn_preinv_mod_1 __MPN(preinv_mod_1) -__GMP_DECLSPEC mp_limb_t mpn_preinv_mod_1 (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_random __MPN(random) -__GMP_DECLSPEC void mpn_random (mp_ptr, mp_size_t); - -#define mpn_random2 __MPN(random2) -__GMP_DECLSPEC void mpn_random2 (mp_ptr, mp_size_t); - -#define mpn_rshift __MPN(rshift) -__GMP_DECLSPEC mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); - -#define mpn_scan0 __MPN(scan0) -__GMP_DECLSPEC mp_bitcnt_t mpn_scan0 (mp_srcptr, mp_bitcnt_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_scan1 __MPN(scan1) -__GMP_DECLSPEC mp_bitcnt_t mpn_scan1 (mp_srcptr, mp_bitcnt_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_set_str __MPN(set_str) -__GMP_DECLSPEC mp_size_t mpn_set_str (mp_ptr, const unsigned char *, size_t, int); - -#define mpn_sizeinbase __MPN(sizeinbase) -__GMP_DECLSPEC size_t mpn_sizeinbase (mp_srcptr, mp_size_t, int); - -#define mpn_sqrtrem __MPN(sqrtrem) -__GMP_DECLSPEC mp_size_t mpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t); - -#define mpn_sub __MPN(sub) -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_sub) -__GMP_DECLSPEC mp_limb_t mpn_sub (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); -#endif - -#define mpn_sub_1 __MPN(sub_1) -#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_sub_1) -__GMP_DECLSPEC mp_limb_t mpn_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t) __GMP_NOTHROW; -#endif - -#define mpn_sub_n __MPN(sub_n) -__GMP_DECLSPEC mp_limb_t mpn_sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); - -#define mpn_submul_1 __MPN(submul_1) -__GMP_DECLSPEC mp_limb_t mpn_submul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); - -#define mpn_tdiv_qr __MPN(tdiv_qr) -__GMP_DECLSPEC void mpn_tdiv_qr (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); - -#define mpn_and_n __MPN(and_n) -__GMP_DECLSPEC void mpn_and_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); -#define mpn_andn_n __MPN(andn_n) -__GMP_DECLSPEC void mpn_andn_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); -#define mpn_nand_n __MPN(nand_n) -__GMP_DECLSPEC void mpn_nand_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); -#define mpn_ior_n __MPN(ior_n) -__GMP_DECLSPEC void mpn_ior_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); -#define mpn_iorn_n __MPN(iorn_n) -__GMP_DECLSPEC void mpn_iorn_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); -#define mpn_nior_n __MPN(nior_n) -__GMP_DECLSPEC void mpn_nior_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); -#define mpn_xor_n __MPN(xor_n) -__GMP_DECLSPEC void mpn_xor_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); -#define mpn_xnor_n __MPN(xnor_n) -__GMP_DECLSPEC void mpn_xnor_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); - -#define mpn_copyi __MPN(copyi) -__GMP_DECLSPEC void mpn_copyi (mp_ptr, mp_srcptr, mp_size_t); -#define mpn_copyd __MPN(copyd) -__GMP_DECLSPEC void mpn_copyd (mp_ptr, mp_srcptr, mp_size_t); -#define mpn_zero __MPN(zero) -__GMP_DECLSPEC void mpn_zero (mp_ptr, mp_size_t); - -#define mpn_cnd_add_n __MPN(cnd_add_n) -__GMP_DECLSPEC mp_limb_t mpn_cnd_add_n (mp_limb_t, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); -#define mpn_cnd_sub_n __MPN(cnd_sub_n) -__GMP_DECLSPEC mp_limb_t mpn_cnd_sub_n (mp_limb_t, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); - -#define mpn_sec_add_1 __MPN(sec_add_1) -__GMP_DECLSPEC mp_limb_t mpn_sec_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr); -#define mpn_sec_add_1_itch __MPN(sec_add_1_itch) -__GMP_DECLSPEC mp_size_t mpn_sec_add_1_itch (mp_size_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_sec_sub_1 __MPN(sec_sub_1) -__GMP_DECLSPEC mp_limb_t mpn_sec_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr); -#define mpn_sec_sub_1_itch __MPN(sec_sub_1_itch) -__GMP_DECLSPEC mp_size_t mpn_sec_sub_1_itch (mp_size_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_cnd_swap __MPN(cnd_swap) -__GMP_DECLSPEC void mpn_cnd_swap (mp_limb_t, volatile mp_limb_t *, volatile mp_limb_t *, mp_size_t); - -#define mpn_sec_mul __MPN(sec_mul) -__GMP_DECLSPEC void mpn_sec_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr); -#define mpn_sec_mul_itch __MPN(sec_mul_itch) -__GMP_DECLSPEC mp_size_t mpn_sec_mul_itch (mp_size_t, mp_size_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_sec_sqr __MPN(sec_sqr) -__GMP_DECLSPEC void mpn_sec_sqr (mp_ptr, mp_srcptr, mp_size_t, mp_ptr); -#define mpn_sec_sqr_itch __MPN(sec_sqr_itch) -__GMP_DECLSPEC mp_size_t mpn_sec_sqr_itch (mp_size_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_sec_powm __MPN(sec_powm) -__GMP_DECLSPEC void mpn_sec_powm (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_bitcnt_t, mp_srcptr, mp_size_t, mp_ptr); -#define mpn_sec_powm_itch __MPN(sec_powm_itch) -__GMP_DECLSPEC mp_size_t mpn_sec_powm_itch (mp_size_t, mp_bitcnt_t, mp_size_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_sec_tabselect __MPN(sec_tabselect) -__GMP_DECLSPEC void mpn_sec_tabselect (volatile mp_limb_t *, volatile const mp_limb_t *, mp_size_t, mp_size_t, mp_size_t); - -#define mpn_sec_div_qr __MPN(sec_div_qr) -__GMP_DECLSPEC mp_limb_t mpn_sec_div_qr (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr); -#define mpn_sec_div_qr_itch __MPN(sec_div_qr_itch) -__GMP_DECLSPEC mp_size_t mpn_sec_div_qr_itch (mp_size_t, mp_size_t) __GMP_ATTRIBUTE_PURE; -#define mpn_sec_div_r __MPN(sec_div_r) -__GMP_DECLSPEC void mpn_sec_div_r (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr); -#define mpn_sec_div_r_itch __MPN(sec_div_r_itch) -__GMP_DECLSPEC mp_size_t mpn_sec_div_r_itch (mp_size_t, mp_size_t) __GMP_ATTRIBUTE_PURE; - -#define mpn_sec_invert __MPN(sec_invert) -__GMP_DECLSPEC int mpn_sec_invert (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_bitcnt_t, mp_ptr); -#define mpn_sec_invert_itch __MPN(sec_invert_itch) -__GMP_DECLSPEC mp_size_t mpn_sec_invert_itch (mp_size_t) __GMP_ATTRIBUTE_PURE; - - -/**************** mpz inlines ****************/ - -/* The following are provided as inlines where possible, but always exist as - library functions too, for binary compatibility. - - Within gmp itself this inlining generally isn't relied on, since it - doesn't get done for all compilers, whereas if something is worth - inlining then it's worth arranging always. - - There are two styles of inlining here. When the same bit of code is - wanted for the inline as for the library version, then __GMP_FORCE_foo - arranges for that code to be emitted and the __GMP_EXTERN_INLINE - directive suppressed, eg. mpz_fits_uint_p. When a different bit of code - is wanted for the inline than for the library version, then - __GMP_FORCE_foo arranges the inline to be suppressed, eg. mpz_abs. */ - -#if defined (__GMP_EXTERN_INLINE) && ! defined (__GMP_FORCE_mpz_abs) -__GMP_EXTERN_INLINE void -mpz_abs (mpz_ptr __gmp_w, mpz_srcptr __gmp_u) -{ - if (__gmp_w != __gmp_u) - mpz_set (__gmp_w, __gmp_u); - __gmp_w->_mp_size = __GMP_ABS (__gmp_w->_mp_size); -} -#endif - -#if GMP_NAIL_BITS == 0 -#define __GMPZ_FITS_UTYPE_P(z,maxval) \ - mp_size_t __gmp_n = z->_mp_size; \ - mp_ptr __gmp_p = z->_mp_d; \ - return (__gmp_n == 0 || (__gmp_n == 1 && __gmp_p[0] <= maxval)); -#else -#define __GMPZ_FITS_UTYPE_P(z,maxval) \ - mp_size_t __gmp_n = z->_mp_size; \ - mp_ptr __gmp_p = z->_mp_d; \ - return (__gmp_n == 0 || (__gmp_n == 1 && __gmp_p[0] <= maxval) \ - || (__gmp_n == 2 && __gmp_p[1] <= ((mp_limb_t) maxval >> GMP_NUMB_BITS))); -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_fits_uint_p) -#if ! defined (__GMP_FORCE_mpz_fits_uint_p) -__GMP_EXTERN_INLINE -#endif -int -mpz_fits_uint_p (mpz_srcptr __gmp_z) __GMP_NOTHROW -{ - __GMPZ_FITS_UTYPE_P (__gmp_z, UINT_MAX); -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_fits_ulong_p) -#if ! defined (__GMP_FORCE_mpz_fits_ulong_p) -__GMP_EXTERN_INLINE -#endif -int -mpz_fits_ulong_p (mpz_srcptr __gmp_z) __GMP_NOTHROW -{ - __GMPZ_FITS_UTYPE_P (__gmp_z, ULONG_MAX); -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_fits_ushort_p) -#if ! defined (__GMP_FORCE_mpz_fits_ushort_p) -__GMP_EXTERN_INLINE -#endif -int -mpz_fits_ushort_p (mpz_srcptr __gmp_z) __GMP_NOTHROW -{ - __GMPZ_FITS_UTYPE_P (__gmp_z, USHRT_MAX); -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_get_ui) -#if ! defined (__GMP_FORCE_mpz_get_ui) -__GMP_EXTERN_INLINE -#endif -unsigned long -mpz_get_ui (mpz_srcptr __gmp_z) __GMP_NOTHROW -{ - mp_ptr __gmp_p = __gmp_z->_mp_d; - mp_size_t __gmp_n = __gmp_z->_mp_size; - mp_limb_t __gmp_l = __gmp_p[0]; - /* This is a "#if" rather than a plain "if" so as to avoid gcc warnings - about "<< GMP_NUMB_BITS" exceeding the type size, and to avoid Borland - C++ 6.0 warnings about condition always true for something like - "ULONG_MAX < GMP_NUMB_MASK". */ -#if GMP_NAIL_BITS == 0 || defined (_LONG_LONG_LIMB) - /* limb==long and no nails, or limb==longlong, one limb is enough */ - return (__gmp_n != 0 ? __gmp_l : 0); -#else - /* limb==long and nails, need two limbs when available */ - __gmp_n = __GMP_ABS (__gmp_n); - if (__gmp_n <= 1) - return (__gmp_n != 0 ? __gmp_l : 0); - else - return __gmp_l + (__gmp_p[1] << GMP_NUMB_BITS); -#endif -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_getlimbn) -#if ! defined (__GMP_FORCE_mpz_getlimbn) -__GMP_EXTERN_INLINE -#endif -mp_limb_t -mpz_getlimbn (mpz_srcptr __gmp_z, mp_size_t __gmp_n) __GMP_NOTHROW -{ - mp_limb_t __gmp_result = 0; - if (__GMP_LIKELY (__gmp_n >= 0 && __gmp_n < __GMP_ABS (__gmp_z->_mp_size))) - __gmp_result = __gmp_z->_mp_d[__gmp_n]; - return __gmp_result; -} -#endif - -#if defined (__GMP_EXTERN_INLINE) && ! defined (__GMP_FORCE_mpz_neg) -__GMP_EXTERN_INLINE void -mpz_neg (mpz_ptr __gmp_w, mpz_srcptr __gmp_u) -{ - if (__gmp_w != __gmp_u) - mpz_set (__gmp_w, __gmp_u); - __gmp_w->_mp_size = - __gmp_w->_mp_size; -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_perfect_square_p) -#if ! defined (__GMP_FORCE_mpz_perfect_square_p) -__GMP_EXTERN_INLINE -#endif -int -mpz_perfect_square_p (mpz_srcptr __gmp_a) -{ - mp_size_t __gmp_asize; - int __gmp_result; - - __gmp_asize = __gmp_a->_mp_size; - __gmp_result = (__gmp_asize >= 0); /* zero is a square, negatives are not */ - if (__GMP_LIKELY (__gmp_asize > 0)) - __gmp_result = mpn_perfect_square_p (__gmp_a->_mp_d, __gmp_asize); - return __gmp_result; -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_popcount) -#if ! defined (__GMP_FORCE_mpz_popcount) -__GMP_EXTERN_INLINE -#endif -mp_bitcnt_t -mpz_popcount (mpz_srcptr __gmp_u) __GMP_NOTHROW -{ - mp_size_t __gmp_usize; - mp_bitcnt_t __gmp_result; - - __gmp_usize = __gmp_u->_mp_size; - __gmp_result = (__gmp_usize < 0 ? ~ __GMP_CAST (mp_bitcnt_t, 0) : __GMP_CAST (mp_bitcnt_t, 0)); - if (__GMP_LIKELY (__gmp_usize > 0)) - __gmp_result = mpn_popcount (__gmp_u->_mp_d, __gmp_usize); - return __gmp_result; -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_set_q) -#if ! defined (__GMP_FORCE_mpz_set_q) -__GMP_EXTERN_INLINE -#endif -void -mpz_set_q (mpz_ptr __gmp_w, mpq_srcptr __gmp_u) -{ - mpz_tdiv_q (__gmp_w, mpq_numref (__gmp_u), mpq_denref (__gmp_u)); -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_size) -#if ! defined (__GMP_FORCE_mpz_size) -__GMP_EXTERN_INLINE -#endif -size_t -mpz_size (mpz_srcptr __gmp_z) __GMP_NOTHROW -{ - return __GMP_ABS (__gmp_z->_mp_size); -} -#endif - - -/**************** mpq inlines ****************/ - -#if defined (__GMP_EXTERN_INLINE) && ! defined (__GMP_FORCE_mpq_abs) -__GMP_EXTERN_INLINE void -mpq_abs (mpq_ptr __gmp_w, mpq_srcptr __gmp_u) -{ - if (__gmp_w != __gmp_u) - mpq_set (__gmp_w, __gmp_u); - __gmp_w->_mp_num._mp_size = __GMP_ABS (__gmp_w->_mp_num._mp_size); -} -#endif - -#if defined (__GMP_EXTERN_INLINE) && ! defined (__GMP_FORCE_mpq_neg) -__GMP_EXTERN_INLINE void -mpq_neg (mpq_ptr __gmp_w, mpq_srcptr __gmp_u) -{ - if (__gmp_w != __gmp_u) - mpq_set (__gmp_w, __gmp_u); - __gmp_w->_mp_num._mp_size = - __gmp_w->_mp_num._mp_size; -} -#endif - - -/**************** mpn inlines ****************/ - -/* The comments with __GMPN_ADD_1 below apply here too. - - The test for FUNCTION returning 0 should predict well. If it's assumed - {yp,ysize} will usually have a random number of bits then the high limb - won't be full and a carry out will occur a good deal less than 50% of the - time. - - ysize==0 isn't a documented feature, but is used internally in a few - places. - - Producing cout last stops it using up a register during the main part of - the calculation, though gcc (as of 3.0) on an "if (mpn_add (...))" - doesn't seem able to move the true and false legs of the conditional up - to the two places cout is generated. */ - -#define __GMPN_AORS(cout, wp, xp, xsize, yp, ysize, FUNCTION, TEST) \ - do { \ - mp_size_t __gmp_i; \ - mp_limb_t __gmp_x; \ - \ - /* ASSERT ((ysize) >= 0); */ \ - /* ASSERT ((xsize) >= (ysize)); */ \ - /* ASSERT (MPN_SAME_OR_SEPARATE2_P (wp, xsize, xp, xsize)); */ \ - /* ASSERT (MPN_SAME_OR_SEPARATE2_P (wp, xsize, yp, ysize)); */ \ - \ - __gmp_i = (ysize); \ - if (__gmp_i != 0) \ - { \ - if (FUNCTION (wp, xp, yp, __gmp_i)) \ - { \ - do \ - { \ - if (__gmp_i >= (xsize)) \ - { \ - (cout) = 1; \ - goto __gmp_done; \ - } \ - __gmp_x = (xp)[__gmp_i]; \ - } \ - while (TEST); \ - } \ - } \ - if ((wp) != (xp)) \ - __GMPN_COPY_REST (wp, xp, xsize, __gmp_i); \ - (cout) = 0; \ - __gmp_done: \ - ; \ - } while (0) - -#define __GMPN_ADD(cout, wp, xp, xsize, yp, ysize) \ - __GMPN_AORS (cout, wp, xp, xsize, yp, ysize, mpn_add_n, \ - (((wp)[__gmp_i++] = (__gmp_x + 1) & GMP_NUMB_MASK) == 0)) -#define __GMPN_SUB(cout, wp, xp, xsize, yp, ysize) \ - __GMPN_AORS (cout, wp, xp, xsize, yp, ysize, mpn_sub_n, \ - (((wp)[__gmp_i++] = (__gmp_x - 1) & GMP_NUMB_MASK), __gmp_x == 0)) - - -/* The use of __gmp_i indexing is designed to ensure a compile time src==dst - remains nice and clear to the compiler, so that __GMPN_COPY_REST can - disappear, and the load/add/store gets a chance to become a - read-modify-write on CISC CPUs. - - Alternatives: - - Using a pair of pointers instead of indexing would be possible, but gcc - isn't able to recognise compile-time src==dst in that case, even when the - pointers are incremented more or less together. Other compilers would - very likely have similar difficulty. - - gcc could use "if (__builtin_constant_p(src==dst) && src==dst)" or - similar to detect a compile-time src==dst. This works nicely on gcc - 2.95.x, it's not good on gcc 3.0 where __builtin_constant_p(p==p) seems - to be always false, for a pointer p. But the current code form seems - good enough for src==dst anyway. - - gcc on x86 as usual doesn't give particularly good flags handling for the - carry/borrow detection. It's tempting to want some multi instruction asm - blocks to help it, and this was tried, but in truth there's only a few - instructions to save and any gain is all too easily lost by register - juggling setting up for the asm. */ - -#if GMP_NAIL_BITS == 0 -#define __GMPN_AORS_1(cout, dst, src, n, v, OP, CB) \ - do { \ - mp_size_t __gmp_i; \ - mp_limb_t __gmp_x, __gmp_r; \ - \ - /* ASSERT ((n) >= 1); */ \ - /* ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, n)); */ \ - \ - __gmp_x = (src)[0]; \ - __gmp_r = __gmp_x OP (v); \ - (dst)[0] = __gmp_r; \ - if (CB (__gmp_r, __gmp_x, (v))) \ - { \ - (cout) = 1; \ - for (__gmp_i = 1; __gmp_i < (n);) \ - { \ - __gmp_x = (src)[__gmp_i]; \ - __gmp_r = __gmp_x OP 1; \ - (dst)[__gmp_i] = __gmp_r; \ - ++__gmp_i; \ - if (!CB (__gmp_r, __gmp_x, 1)) \ - { \ - if ((src) != (dst)) \ - __GMPN_COPY_REST (dst, src, n, __gmp_i); \ - (cout) = 0; \ - break; \ - } \ - } \ - } \ - else \ - { \ - if ((src) != (dst)) \ - __GMPN_COPY_REST (dst, src, n, 1); \ - (cout) = 0; \ - } \ - } while (0) -#endif - -#if GMP_NAIL_BITS >= 1 -#define __GMPN_AORS_1(cout, dst, src, n, v, OP, CB) \ - do { \ - mp_size_t __gmp_i; \ - mp_limb_t __gmp_x, __gmp_r; \ - \ - /* ASSERT ((n) >= 1); */ \ - /* ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, n)); */ \ - \ - __gmp_x = (src)[0]; \ - __gmp_r = __gmp_x OP (v); \ - (dst)[0] = __gmp_r & GMP_NUMB_MASK; \ - if (__gmp_r >> GMP_NUMB_BITS != 0) \ - { \ - (cout) = 1; \ - for (__gmp_i = 1; __gmp_i < (n);) \ - { \ - __gmp_x = (src)[__gmp_i]; \ - __gmp_r = __gmp_x OP 1; \ - (dst)[__gmp_i] = __gmp_r & GMP_NUMB_MASK; \ - ++__gmp_i; \ - if (__gmp_r >> GMP_NUMB_BITS == 0) \ - { \ - if ((src) != (dst)) \ - __GMPN_COPY_REST (dst, src, n, __gmp_i); \ - (cout) = 0; \ - break; \ - } \ - } \ - } \ - else \ - { \ - if ((src) != (dst)) \ - __GMPN_COPY_REST (dst, src, n, 1); \ - (cout) = 0; \ - } \ - } while (0) -#endif - -#define __GMPN_ADDCB(r,x,y) ((r) < (y)) -#define __GMPN_SUBCB(r,x,y) ((x) < (y)) - -#define __GMPN_ADD_1(cout, dst, src, n, v) \ - __GMPN_AORS_1(cout, dst, src, n, v, +, __GMPN_ADDCB) -#define __GMPN_SUB_1(cout, dst, src, n, v) \ - __GMPN_AORS_1(cout, dst, src, n, v, -, __GMPN_SUBCB) - - -/* Compare {xp,size} and {yp,size}, setting "result" to positive, zero or - negative. size==0 is allowed. On random data usually only one limb will - need to be examined to get a result, so it's worth having it inline. */ -#define __GMPN_CMP(result, xp, yp, size) \ - do { \ - mp_size_t __gmp_i; \ - mp_limb_t __gmp_x, __gmp_y; \ - \ - /* ASSERT ((size) >= 0); */ \ - \ - (result) = 0; \ - __gmp_i = (size); \ - while (--__gmp_i >= 0) \ - { \ - __gmp_x = (xp)[__gmp_i]; \ - __gmp_y = (yp)[__gmp_i]; \ - if (__gmp_x != __gmp_y) \ - { \ - /* Cannot use __gmp_x - __gmp_y, may overflow an "int" */ \ - (result) = (__gmp_x > __gmp_y ? 1 : -1); \ - break; \ - } \ - } \ - } while (0) - - -#if defined (__GMPN_COPY) && ! defined (__GMPN_COPY_REST) -#define __GMPN_COPY_REST(dst, src, size, start) \ - do { \ - /* ASSERT ((start) >= 0); */ \ - /* ASSERT ((start) <= (size)); */ \ - __GMPN_COPY ((dst)+(start), (src)+(start), (size)-(start)); \ - } while (0) -#endif - -/* Copy {src,size} to {dst,size}, starting at "start". This is designed to - keep the indexing dst[j] and src[j] nice and simple for __GMPN_ADD_1, - __GMPN_ADD, etc. */ -#if ! defined (__GMPN_COPY_REST) -#define __GMPN_COPY_REST(dst, src, size, start) \ - do { \ - mp_size_t __gmp_j; \ - /* ASSERT ((size) >= 0); */ \ - /* ASSERT ((start) >= 0); */ \ - /* ASSERT ((start) <= (size)); */ \ - /* ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, size)); */ \ - __GMP_CRAY_Pragma ("_CRI ivdep"); \ - for (__gmp_j = (start); __gmp_j < (size); __gmp_j++) \ - (dst)[__gmp_j] = (src)[__gmp_j]; \ - } while (0) -#endif - -/* Enhancement: Use some of the smarter code from gmp-impl.h. Maybe use - mpn_copyi if there's a native version, and if we don't mind demanding - binary compatibility for it (on targets which use it). */ - -#if ! defined (__GMPN_COPY) -#define __GMPN_COPY(dst, src, size) __GMPN_COPY_REST (dst, src, size, 0) -#endif - - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_add) -#if ! defined (__GMP_FORCE_mpn_add) -__GMP_EXTERN_INLINE -#endif -mp_limb_t -mpn_add (mp_ptr __gmp_wp, mp_srcptr __gmp_xp, mp_size_t __gmp_xsize, mp_srcptr __gmp_yp, mp_size_t __gmp_ysize) -{ - mp_limb_t __gmp_c; - __GMPN_ADD (__gmp_c, __gmp_wp, __gmp_xp, __gmp_xsize, __gmp_yp, __gmp_ysize); - return __gmp_c; -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_add_1) -#if ! defined (__GMP_FORCE_mpn_add_1) -__GMP_EXTERN_INLINE -#endif -mp_limb_t -mpn_add_1 (mp_ptr __gmp_dst, mp_srcptr __gmp_src, mp_size_t __gmp_size, mp_limb_t __gmp_n) __GMP_NOTHROW -{ - mp_limb_t __gmp_c; - __GMPN_ADD_1 (__gmp_c, __gmp_dst, __gmp_src, __gmp_size, __gmp_n); - return __gmp_c; -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_cmp) -#if ! defined (__GMP_FORCE_mpn_cmp) -__GMP_EXTERN_INLINE -#endif -int -mpn_cmp (mp_srcptr __gmp_xp, mp_srcptr __gmp_yp, mp_size_t __gmp_size) __GMP_NOTHROW -{ - int __gmp_result; - __GMPN_CMP (__gmp_result, __gmp_xp, __gmp_yp, __gmp_size); - return __gmp_result; -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_zero_p) -#if ! defined (__GMP_FORCE_mpn_zero_p) -__GMP_EXTERN_INLINE -#endif -int -mpn_zero_p (mp_srcptr __gmp_p, mp_size_t __gmp_n) __GMP_NOTHROW -{ - /* if (__GMP_LIKELY (__gmp_n > 0)) */ - do { - if (__gmp_p[--__gmp_n] != 0) - return 0; - } while (__gmp_n != 0); - return 1; -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_sub) -#if ! defined (__GMP_FORCE_mpn_sub) -__GMP_EXTERN_INLINE -#endif -mp_limb_t -mpn_sub (mp_ptr __gmp_wp, mp_srcptr __gmp_xp, mp_size_t __gmp_xsize, mp_srcptr __gmp_yp, mp_size_t __gmp_ysize) -{ - mp_limb_t __gmp_c; - __GMPN_SUB (__gmp_c, __gmp_wp, __gmp_xp, __gmp_xsize, __gmp_yp, __gmp_ysize); - return __gmp_c; -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_sub_1) -#if ! defined (__GMP_FORCE_mpn_sub_1) -__GMP_EXTERN_INLINE -#endif -mp_limb_t -mpn_sub_1 (mp_ptr __gmp_dst, mp_srcptr __gmp_src, mp_size_t __gmp_size, mp_limb_t __gmp_n) __GMP_NOTHROW -{ - mp_limb_t __gmp_c; - __GMPN_SUB_1 (__gmp_c, __gmp_dst, __gmp_src, __gmp_size, __gmp_n); - return __gmp_c; -} -#endif - -#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_neg) -#if ! defined (__GMP_FORCE_mpn_neg) -__GMP_EXTERN_INLINE -#endif -mp_limb_t -mpn_neg (mp_ptr __gmp_rp, mp_srcptr __gmp_up, mp_size_t __gmp_n) -{ - while (*__gmp_up == 0) /* Low zero limbs are unchanged by negation. */ - { - *__gmp_rp = 0; - if (!--__gmp_n) /* All zero */ - return 0; - ++__gmp_up; ++__gmp_rp; - } - - *__gmp_rp = (- *__gmp_up) & GMP_NUMB_MASK; - - if (--__gmp_n) /* Higher limbs get complemented. */ - mpn_com (++__gmp_rp, ++__gmp_up, __gmp_n); - - return 1; -} -#endif - -#if defined (__cplusplus) -} -#endif - - -/* Allow faster testing for negative, zero, and positive. */ -#define mpz_sgn(Z) ((Z)->_mp_size < 0 ? -1 : (Z)->_mp_size > 0) -#define mpf_sgn(F) ((F)->_mp_size < 0 ? -1 : (F)->_mp_size > 0) -#define mpq_sgn(Q) ((Q)->_mp_num._mp_size < 0 ? -1 : (Q)->_mp_num._mp_size > 0) - -/* When using GCC, optimize certain common comparisons. */ -#if defined (__GNUC__) && __GNUC__ >= 2 -#define mpz_cmp_ui(Z,UI) \ - (__builtin_constant_p (UI) && (UI) == 0 \ - ? mpz_sgn (Z) : _mpz_cmp_ui (Z,UI)) -#define mpz_cmp_si(Z,SI) \ - (__builtin_constant_p ((SI) >= 0) && (SI) >= 0 \ - ? mpz_cmp_ui (Z, __GMP_CAST (unsigned long, SI)) \ - : _mpz_cmp_si (Z,SI)) -#define mpq_cmp_ui(Q,NUI,DUI) \ - (__builtin_constant_p (NUI) && (NUI) == 0 ? mpq_sgn (Q) \ - : __builtin_constant_p ((NUI) == (DUI)) && (NUI) == (DUI) \ - ? mpz_cmp (mpq_numref (Q), mpq_denref (Q)) \ - : _mpq_cmp_ui (Q,NUI,DUI)) -#define mpq_cmp_si(q,n,d) \ - (__builtin_constant_p ((n) >= 0) && (n) >= 0 \ - ? mpq_cmp_ui (q, __GMP_CAST (unsigned long, n), d) \ - : _mpq_cmp_si (q, n, d)) -#else -#define mpz_cmp_ui(Z,UI) _mpz_cmp_ui (Z,UI) -#define mpz_cmp_si(Z,UI) _mpz_cmp_si (Z,UI) -#define mpq_cmp_ui(Q,NUI,DUI) _mpq_cmp_ui (Q,NUI,DUI) -#define mpq_cmp_si(q,n,d) _mpq_cmp_si(q,n,d) -#endif - - -/* Using "&" rather than "&&" means these can come out branch-free. Every - mpz_t has at least one limb allocated, so fetching the low limb is always - allowed. */ -#define mpz_odd_p(z) (((z)->_mp_size != 0) & __GMP_CAST (int, (z)->_mp_d[0])) -#define mpz_even_p(z) (! mpz_odd_p (z)) - - -/**************** C++ routines ****************/ - -#ifdef __cplusplus -__GMP_DECLSPEC_XX std::ostream& operator<< (std::ostream &, mpz_srcptr); -__GMP_DECLSPEC_XX std::ostream& operator<< (std::ostream &, mpq_srcptr); -__GMP_DECLSPEC_XX std::ostream& operator<< (std::ostream &, mpf_srcptr); -__GMP_DECLSPEC_XX std::istream& operator>> (std::istream &, mpz_ptr); -__GMP_DECLSPEC_XX std::istream& operator>> (std::istream &, mpq_ptr); -__GMP_DECLSPEC_XX std::istream& operator>> (std::istream &, mpf_ptr); -#endif - - -/* Source-level compatibility with GMP 2 and earlier. */ -#define mpn_divmod(qp,np,nsize,dp,dsize) \ - mpn_divrem (qp, __GMP_CAST (mp_size_t, 0), np, nsize, dp, dsize) - -/* Source-level compatibility with GMP 1. */ -#define mpz_mdiv mpz_fdiv_q -#define mpz_mdivmod mpz_fdiv_qr -#define mpz_mmod mpz_fdiv_r -#define mpz_mdiv_ui mpz_fdiv_q_ui -#define mpz_mdivmod_ui(q,r,n,d) \ - (((r) == 0) ? mpz_fdiv_q_ui (q,n,d) : mpz_fdiv_qr_ui (q,r,n,d)) -#define mpz_mmod_ui(r,n,d) \ - (((r) == 0) ? mpz_fdiv_ui (n,d) : mpz_fdiv_r_ui (r,n,d)) - -/* Useful synonyms, but not quite compatible with GMP 1. */ -#define mpz_div mpz_fdiv_q -#define mpz_divmod mpz_fdiv_qr -#define mpz_div_ui mpz_fdiv_q_ui -#define mpz_divmod_ui mpz_fdiv_qr_ui -#define mpz_div_2exp mpz_fdiv_q_2exp -#define mpz_mod_2exp mpz_fdiv_r_2exp - -enum -{ - GMP_ERROR_NONE = 0, - GMP_ERROR_UNSUPPORTED_ARGUMENT = 1, - GMP_ERROR_DIVISION_BY_ZERO = 2, - GMP_ERROR_SQRT_OF_NEGATIVE = 4, - GMP_ERROR_INVALID_ARGUMENT = 8 -}; - -/* Define CC and CFLAGS which were used to build this version of GMP */ -#define __GMP_CC "gcc" -#define __GMP_CFLAGS "-O2 -pedantic -march=armv8-a" - -/* Major version number is the value of __GNU_MP__ too, above. */ -#define __GNU_MP_VERSION 6 -#define __GNU_MP_VERSION_MINOR 2 -#define __GNU_MP_VERSION_PATCHLEVEL 1 -#define __GNU_MP_RELEASE (__GNU_MP_VERSION * 10000 + __GNU_MP_VERSION_MINOR * 100 + __GNU_MP_VERSION_PATCHLEVEL) - -#define __GMP_H__ -#endif /* __GMP_H__ */ diff --git a/include/gmpxx.h b/include/gmpxx.h deleted file mode 100644 index 0342116e..00000000 --- a/include/gmpxx.h +++ /dev/null @@ -1,3703 +0,0 @@ -/* gmpxx.h -- C++ class wrapper for GMP types. -*- C++ -*- - -Copyright 2001-2003, 2006, 2008, 2011-2015, 2018 Free Software -Foundation, Inc. - -This file is part of the GNU MP Library. - -The GNU MP Library is free software; you can redistribute it and/or modify -it under the terms of either: - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your - option) any later version. - -or - - * the GNU General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - -or both in parallel, as here. - -The GNU MP Library is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received copies of the GNU General Public License and the -GNU Lesser General Public License along with the GNU MP Library. If not, -see https://www.gnu.org/licenses/. */ - -#ifndef __GMP_PLUSPLUS__ -#define __GMP_PLUSPLUS__ - -#include - -#include /* for strlen */ -#include /* numeric_limits */ -#include -#include /* swap */ -#include -#include -#include -#include - -// wrapper for gcc's __builtin_constant_p -// __builtin_constant_p has been in gcc since forever, -// but g++-3.4 miscompiles it. -#if __GMP_GNUC_PREREQ(4, 2) -#define __GMPXX_CONSTANT(X) __builtin_constant_p(X) -#else -#define __GMPXX_CONSTANT(X) false -#endif -#define __GMPXX_CONSTANT_TRUE(X) (__GMPXX_CONSTANT(X) && (X)) - -// Use C++11 features -#ifndef __GMPXX_USE_CXX11 -#if __cplusplus >= 201103L -#define __GMPXX_USE_CXX11 1 -#else -#define __GMPXX_USE_CXX11 0 -#endif -#endif - -#if __GMPXX_USE_CXX11 -#define __GMPXX_NOEXCEPT noexcept -#include // for common_type -#else -#define __GMPXX_NOEXCEPT -#endif - -// Max allocations for plain types when converted to GMP types -#if GMP_NAIL_BITS != 0 && ! defined _LONG_LONG_LIMB -#define __GMPZ_ULI_LIMBS 2 -#else -#define __GMPZ_ULI_LIMBS 1 -#endif - -#define __GMPXX_BITS_TO_LIMBS(n) (((n) + (GMP_NUMB_BITS - 1)) / GMP_NUMB_BITS) -#define __GMPZ_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MAX_EXP)+1 -#define __GMPQ_NUM_DBL_LIMBS __GMPZ_DBL_LIMBS -#define __GMPQ_DEN_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MANT_DIG+1-DBL_MIN_EXP)+1 -// The final +1s are a security margin. The current implementation of -// mpq_set_d seems to need it for the denominator. - -inline void __mpz_set_ui_safe(mpz_ptr p, unsigned long l) -{ - p->_mp_size = (l != 0); - p->_mp_d[0] = l & GMP_NUMB_MASK; -#if __GMPZ_ULI_LIMBS > 1 - l >>= GMP_NUMB_BITS; - p->_mp_d[1] = l; - p->_mp_size += (l != 0); -#endif -} - -inline void __mpz_set_si_safe(mpz_ptr p, long l) -{ - if(l < 0) - { - __mpz_set_ui_safe(p, -static_cast(l)); - mpz_neg(p, p); - } - else - __mpz_set_ui_safe(p, l); - // Note: we know the high bit of l is 0 so we could do slightly better -} - -// Fake temporary variables -#define __GMPXX_TMPZ_UI \ - mpz_t temp; \ - mp_limb_t limbs[__GMPZ_ULI_LIMBS]; \ - temp->_mp_d = limbs; \ - __mpz_set_ui_safe (temp, l) -#define __GMPXX_TMPZ_SI \ - mpz_t temp; \ - mp_limb_t limbs[__GMPZ_ULI_LIMBS]; \ - temp->_mp_d = limbs; \ - __mpz_set_si_safe (temp, l) -#define __GMPXX_TMPZ_D \ - mpz_t temp; \ - mp_limb_t limbs[__GMPZ_DBL_LIMBS]; \ - temp->_mp_d = limbs; \ - temp->_mp_alloc = __GMPZ_DBL_LIMBS; \ - mpz_set_d (temp, d) - -#define __GMPXX_TMPQ_UI \ - mpq_t temp; \ - mp_limb_t limbs[__GMPZ_ULI_LIMBS+1]; \ - mpq_numref(temp)->_mp_d = limbs; \ - __mpz_set_ui_safe (mpq_numref(temp), l); \ - mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS; \ - mpq_denref(temp)->_mp_size = 1; \ - mpq_denref(temp)->_mp_d[0] = 1 -#define __GMPXX_TMPQ_SI \ - mpq_t temp; \ - mp_limb_t limbs[__GMPZ_ULI_LIMBS+1]; \ - mpq_numref(temp)->_mp_d = limbs; \ - __mpz_set_si_safe (mpq_numref(temp), l); \ - mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS; \ - mpq_denref(temp)->_mp_size = 1; \ - mpq_denref(temp)->_mp_d[0] = 1 -#define __GMPXX_TMPQ_D \ - mpq_t temp; \ - mp_limb_t limbs[__GMPQ_NUM_DBL_LIMBS + __GMPQ_DEN_DBL_LIMBS]; \ - mpq_numref(temp)->_mp_d = limbs; \ - mpq_numref(temp)->_mp_alloc = __GMPQ_NUM_DBL_LIMBS; \ - mpq_denref(temp)->_mp_d = limbs + __GMPQ_NUM_DBL_LIMBS; \ - mpq_denref(temp)->_mp_alloc = __GMPQ_DEN_DBL_LIMBS; \ - mpq_set_d (temp, d) - -inline unsigned long __gmpxx_abs_ui (signed long l) -{ - return l >= 0 ? static_cast(l) - : -static_cast(l); -} - -/**************** Function objects ****************/ -/* Any evaluation of a __gmp_expr ends up calling one of these functions - all intermediate functions being inline, the evaluation should optimize - to a direct call to the relevant function, thus yielding no overhead - over the C interface. */ - -struct __gmp_unary_plus -{ - static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); } - static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); } - static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); } -}; - -struct __gmp_unary_minus -{ - static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); } - static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); } - static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); } -}; - -struct __gmp_unary_com -{ - static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); } -}; - -struct __gmp_binary_plus -{ - static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) - { mpz_add(z, w, v); } - - static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) - { - // Ideally, those checks should happen earlier so that the tree - // generated for a+0+b would just be sum(a,b). - if (__GMPXX_CONSTANT(l) && l == 0) - { - if (z != w) mpz_set(z, w); - } - else - mpz_add_ui(z, w, l); - } - static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) - { - if (l >= 0) - eval(z, w, static_cast(l)); - else - mpz_sub_ui(z, w, -static_cast(l)); - } - static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, double d) - { __GMPXX_TMPZ_D; mpz_add (z, w, temp); } - static void eval(mpz_ptr z, double d, mpz_srcptr w) - { eval(z, w, d); } - - static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s) - { mpq_add(q, r, s); } - - static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l) - { - if (__GMPXX_CONSTANT(l) && l == 0) - { - if (q != r) mpq_set(q, r); - } - else if (__GMPXX_CONSTANT(l) && l == 1) - { - mpz_add (mpq_numref(q), mpq_numref(r), mpq_denref(r)); - if (q != r) mpz_set(mpq_denref(q), mpq_denref(r)); - } - else - { - if (q == r) - mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); - else - { - mpz_mul_ui(mpq_numref(q), mpq_denref(r), l); - mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r)); - mpz_set(mpq_denref(q), mpq_denref(r)); - } - } - } - static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r) - { eval(q, r, l); } - static inline void eval(mpq_ptr q, mpq_srcptr r, signed long int l); - // defined after __gmp_binary_minus - static void eval(mpq_ptr q, signed long int l, mpq_srcptr r) - { eval(q, r, l); } - static void eval(mpq_ptr q, mpq_srcptr r, double d) - { __GMPXX_TMPQ_D; mpq_add (q, r, temp); } - static void eval(mpq_ptr q, double d, mpq_srcptr r) - { eval(q, r, d); } - - static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z) - { - if (q == r) - mpz_addmul(mpq_numref(q), mpq_denref(q), z); - else - { - mpz_mul(mpq_numref(q), mpq_denref(r), z); - mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r)); - mpz_set(mpq_denref(q), mpq_denref(r)); - } - } - static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r) - { eval(q, r, z); } - - static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h) - { mpf_add(f, g, h); } - - static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l) - { mpf_add_ui(f, g, l); } - static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g) - { mpf_add_ui(f, g, l); } - static void eval(mpf_ptr f, mpf_srcptr g, signed long int l) - { - if (l >= 0) - mpf_add_ui(f, g, l); - else - mpf_sub_ui(f, g, -static_cast(l)); - } - static void eval(mpf_ptr f, signed long int l, mpf_srcptr g) - { eval(f, g, l); } - static void eval(mpf_ptr f, mpf_srcptr g, double d) - { - mpf_t temp; - mpf_init2(temp, 8*sizeof(double)); - mpf_set_d(temp, d); - mpf_add(f, g, temp); - mpf_clear(temp); - } - static void eval(mpf_ptr f, double d, mpf_srcptr g) - { eval(f, g, d); } -}; - -struct __gmp_binary_minus -{ - static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) - { mpz_sub(z, w, v); } - - static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) - { - if (__GMPXX_CONSTANT(l) && l == 0) - { - if (z != w) mpz_set(z, w); - } - else - mpz_sub_ui(z, w, l); - } - static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) - { - if (__GMPXX_CONSTANT(l) && l == 0) - { - mpz_neg(z, w); - } - else - mpz_ui_sub(z, l, w); - } - static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) - { - if (l >= 0) - eval(z, w, static_cast(l)); - else - mpz_add_ui(z, w, -static_cast(l)); - } - static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) - { - if (l >= 0) - eval(z, static_cast(l), w); - else - { - mpz_add_ui(z, w, -static_cast(l)); - mpz_neg(z, z); - } - } - static void eval(mpz_ptr z, mpz_srcptr w, double d) - { __GMPXX_TMPZ_D; mpz_sub (z, w, temp); } - static void eval(mpz_ptr z, double d, mpz_srcptr w) - { __GMPXX_TMPZ_D; mpz_sub (z, temp, w); } - - static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s) - { mpq_sub(q, r, s); } - - static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l) - { - if (__GMPXX_CONSTANT(l) && l == 0) - { - if (q != r) mpq_set(q, r); - } - else if (__GMPXX_CONSTANT(l) && l == 1) - { - mpz_sub (mpq_numref(q), mpq_numref(r), mpq_denref(r)); - if (q != r) mpz_set(mpq_denref(q), mpq_denref(r)); - } - else - { - if (q == r) - mpz_submul_ui(mpq_numref(q), mpq_denref(q), l); - else - { - mpz_mul_ui(mpq_numref(q), mpq_denref(r), l); - mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q)); - mpz_set(mpq_denref(q), mpq_denref(r)); - } - } - } - static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r) - { eval(q, r, l); mpq_neg(q, q); } - static void eval(mpq_ptr q, mpq_srcptr r, signed long int l) - { - if (l >= 0) - eval(q, r, static_cast(l)); - else - __gmp_binary_plus::eval(q, r, -static_cast(l)); - } - static void eval(mpq_ptr q, signed long int l, mpq_srcptr r) - { eval(q, r, l); mpq_neg(q, q); } - static void eval(mpq_ptr q, mpq_srcptr r, double d) - { __GMPXX_TMPQ_D; mpq_sub (q, r, temp); } - static void eval(mpq_ptr q, double d, mpq_srcptr r) - { __GMPXX_TMPQ_D; mpq_sub (q, temp, r); } - - static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z) - { - if (q == r) - mpz_submul(mpq_numref(q), mpq_denref(q), z); - else - { - mpz_mul(mpq_numref(q), mpq_denref(r), z); - mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q)); - mpz_set(mpq_denref(q), mpq_denref(r)); - } - } - static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r) - { eval(q, r, z); mpq_neg(q, q); } - - static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h) - { mpf_sub(f, g, h); } - - static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l) - { mpf_sub_ui(f, g, l); } - static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g) - { mpf_ui_sub(f, l, g); } - static void eval(mpf_ptr f, mpf_srcptr g, signed long int l) - { - if (l >= 0) - mpf_sub_ui(f, g, l); - else - mpf_add_ui(f, g, -static_cast(l)); - } - static void eval(mpf_ptr f, signed long int l, mpf_srcptr g) - { - if (l >= 0) - mpf_sub_ui(f, g, l); - else - mpf_add_ui(f, g, -static_cast(l)); - mpf_neg(f, f); - } - static void eval(mpf_ptr f, mpf_srcptr g, double d) - { - mpf_t temp; - mpf_init2(temp, 8*sizeof(double)); - mpf_set_d(temp, d); - mpf_sub(f, g, temp); - mpf_clear(temp); - } - static void eval(mpf_ptr f, double d, mpf_srcptr g) - { - mpf_t temp; - mpf_init2(temp, 8*sizeof(double)); - mpf_set_d(temp, d); - mpf_sub(f, temp, g); - mpf_clear(temp); - } -}; - -// defined here so it can reference __gmp_binary_minus -inline void -__gmp_binary_plus::eval(mpq_ptr q, mpq_srcptr r, signed long int l) -{ - if (l >= 0) - eval(q, r, static_cast(l)); - else - __gmp_binary_minus::eval(q, r, -static_cast(l)); -} - -struct __gmp_binary_lshift -{ - static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l) - { - if (__GMPXX_CONSTANT(l) && (l == 0)) - { - if (z != w) mpz_set(z, w); - } - else - mpz_mul_2exp(z, w, l); - } - static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l) - { - if (__GMPXX_CONSTANT(l) && (l == 0)) - { - if (q != r) mpq_set(q, r); - } - else - mpq_mul_2exp(q, r, l); - } - static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l) - { mpf_mul_2exp(f, g, l); } -}; - -struct __gmp_binary_rshift -{ - static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l) - { - if (__GMPXX_CONSTANT(l) && (l == 0)) - { - if (z != w) mpz_set(z, w); - } - else - mpz_fdiv_q_2exp(z, w, l); - } - static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l) - { - if (__GMPXX_CONSTANT(l) && (l == 0)) - { - if (q != r) mpq_set(q, r); - } - else - mpq_div_2exp(q, r, l); - } - static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l) - { mpf_div_2exp(f, g, l); } -}; - -struct __gmp_binary_multiplies -{ - static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) - { mpz_mul(z, w, v); } - - static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) - { -// gcc-3.3 doesn't have __builtin_ctzl. Don't bother optimizing for old gcc. -#if __GMP_GNUC_PREREQ(3, 4) - if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0) - { - if (l == 0) - { - z->_mp_size = 0; - } - else - { - __gmp_binary_lshift::eval(z, w, __builtin_ctzl(l)); - } - } - else -#endif - mpz_mul_ui(z, w, l); - } - static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) - { - if (__GMPXX_CONSTANT_TRUE(l >= 0)) - eval(z, w, static_cast(l)); - else if (__GMPXX_CONSTANT_TRUE(l <= 0)) - { - eval(z, w, -static_cast(l)); - mpz_neg(z, z); - } - else - mpz_mul_si (z, w, l); - } - static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, double d) - { __GMPXX_TMPZ_D; mpz_mul (z, w, temp); } - static void eval(mpz_ptr z, double d, mpz_srcptr w) - { eval(z, w, d); } - - static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s) - { mpq_mul(q, r, s); } - - static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l) - { -#if __GMP_GNUC_PREREQ(3, 4) - if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0) - { - if (l == 0) - { - mpq_set_ui(q, 0, 1); - } - else - { - __gmp_binary_lshift::eval(q, r, __builtin_ctzl(l)); - } - } - else -#endif - { - __GMPXX_TMPQ_UI; - mpq_mul (q, r, temp); - } - } - static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r) - { eval(q, r, l); } - static void eval(mpq_ptr q, mpq_srcptr r, signed long int l) - { - if (__GMPXX_CONSTANT_TRUE(l >= 0)) - eval(q, r, static_cast(l)); - else if (__GMPXX_CONSTANT_TRUE(l <= 0)) - { - eval(q, r, -static_cast(l)); - mpq_neg(q, q); - } - else - { - __GMPXX_TMPQ_SI; - mpq_mul (q, r, temp); - } - } - static void eval(mpq_ptr q, signed long int l, mpq_srcptr r) - { eval(q, r, l); } - static void eval(mpq_ptr q, mpq_srcptr r, double d) - { __GMPXX_TMPQ_D; mpq_mul (q, r, temp); } - static void eval(mpq_ptr q, double d, mpq_srcptr r) - { eval(q, r, d); } - - static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h) - { mpf_mul(f, g, h); } - - static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l) - { mpf_mul_ui(f, g, l); } - static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g) - { mpf_mul_ui(f, g, l); } - static void eval(mpf_ptr f, mpf_srcptr g, signed long int l) - { - if (l >= 0) - mpf_mul_ui(f, g, l); - else - { - mpf_mul_ui(f, g, -static_cast(l)); - mpf_neg(f, f); - } - } - static void eval(mpf_ptr f, signed long int l, mpf_srcptr g) - { eval(f, g, l); } - static void eval(mpf_ptr f, mpf_srcptr g, double d) - { - mpf_t temp; - mpf_init2(temp, 8*sizeof(double)); - mpf_set_d(temp, d); - mpf_mul(f, g, temp); - mpf_clear(temp); - } - static void eval(mpf_ptr f, double d, mpf_srcptr g) - { eval(f, g, d); } -}; - -struct __gmp_binary_divides -{ - static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) - { mpz_tdiv_q(z, w, v); } - - static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) - { -#if __GMP_GNUC_PREREQ(3, 4) - // Don't optimize division by 0... - if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0) - { - if (l == 1) - { - if (z != w) mpz_set(z, w); - } - else - mpz_tdiv_q_2exp(z, w, __builtin_ctzl(l)); - // warning: do not use rshift (fdiv) - } - else -#endif - mpz_tdiv_q_ui(z, w, l); - } - static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) - { - if (mpz_sgn(w) >= 0) - { - if (mpz_fits_ulong_p(w)) - mpz_set_ui(z, l / mpz_get_ui(w)); - else - mpz_set_ui(z, 0); - } - else - { - mpz_neg(z, w); - if (mpz_fits_ulong_p(z)) - { - mpz_set_ui(z, l / mpz_get_ui(z)); - mpz_neg(z, z); - } - else - mpz_set_ui(z, 0); - } - } - static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) - { - if (l >= 0) - eval(z, w, static_cast(l)); - else - { - eval(z, w, -static_cast(l)); - mpz_neg(z, z); - } - } - static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) - { - if (mpz_fits_slong_p(w)) - mpz_set_si(z, l / mpz_get_si(w)); - else - { - /* if w is bigger than a long then the quotient must be zero, unless - l==LONG_MIN and w==-LONG_MIN in which case the quotient is -1 */ - mpz_set_si (z, (mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? -1 : 0)); - } - } - static void eval(mpz_ptr z, mpz_srcptr w, double d) - { __GMPXX_TMPZ_D; mpz_tdiv_q (z, w, temp); } - static void eval(mpz_ptr z, double d, mpz_srcptr w) - { __GMPXX_TMPZ_D; mpz_tdiv_q (z, temp, w); } - - static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s) - { mpq_div(q, r, s); } - - static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l) - { -#if __GMP_GNUC_PREREQ(3, 4) - if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0) - __gmp_binary_rshift::eval(q, r, __builtin_ctzl(l)); - else -#endif - { - __GMPXX_TMPQ_UI; - mpq_div (q, r, temp); - } - } - static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r) - { - if (__GMPXX_CONSTANT_TRUE(l == 0)) - mpq_set_ui(q, 0, 1); - else if (__GMPXX_CONSTANT_TRUE(l == 1)) - mpq_inv(q, r); - else - { - __GMPXX_TMPQ_UI; - mpq_div (q, temp, r); - } - } - static void eval(mpq_ptr q, mpq_srcptr r, signed long int l) - { - if (__GMPXX_CONSTANT_TRUE(l >= 0)) - eval(q, r, static_cast(l)); - else if (__GMPXX_CONSTANT_TRUE(l <= 0)) - { - eval(q, r, -static_cast(l)); - mpq_neg(q, q); - } - else - { - __GMPXX_TMPQ_SI; - mpq_div (q, r, temp); - } - } - static void eval(mpq_ptr q, signed long int l, mpq_srcptr r) - { - if (__GMPXX_CONSTANT_TRUE(l == 0)) - mpq_set_ui(q, 0, 1); - else if (__GMPXX_CONSTANT_TRUE(l == 1)) - mpq_inv(q, r); - else if (__GMPXX_CONSTANT_TRUE(l == -1)) - { - mpq_inv(q, r); - mpq_neg(q, q); - } - else - { - __GMPXX_TMPQ_SI; - mpq_div (q, temp, r); - } - } - static void eval(mpq_ptr q, mpq_srcptr r, double d) - { __GMPXX_TMPQ_D; mpq_div (q, r, temp); } - static void eval(mpq_ptr q, double d, mpq_srcptr r) - { __GMPXX_TMPQ_D; mpq_div (q, temp, r); } - - static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h) - { mpf_div(f, g, h); } - - static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l) - { mpf_div_ui(f, g, l); } - static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g) - { mpf_ui_div(f, l, g); } - static void eval(mpf_ptr f, mpf_srcptr g, signed long int l) - { - if (l >= 0) - mpf_div_ui(f, g, l); - else - { - mpf_div_ui(f, g, -static_cast(l)); - mpf_neg(f, f); - } - } - static void eval(mpf_ptr f, signed long int l, mpf_srcptr g) - { - if (l >= 0) - mpf_ui_div(f, l, g); - else - { - mpf_ui_div(f, -static_cast(l), g); - mpf_neg(f, f); - } - } - static void eval(mpf_ptr f, mpf_srcptr g, double d) - { - mpf_t temp; - mpf_init2(temp, 8*sizeof(double)); - mpf_set_d(temp, d); - mpf_div(f, g, temp); - mpf_clear(temp); - } - static void eval(mpf_ptr f, double d, mpf_srcptr g) - { - mpf_t temp; - mpf_init2(temp, 8*sizeof(double)); - mpf_set_d(temp, d); - mpf_div(f, temp, g); - mpf_clear(temp); - } -}; - -struct __gmp_binary_modulus -{ - static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) - { mpz_tdiv_r(z, w, v); } - - static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) - { mpz_tdiv_r_ui(z, w, l); } - static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) - { - if (mpz_sgn(w) >= 0) - { - if (mpz_fits_ulong_p(w)) - mpz_set_ui(z, l % mpz_get_ui(w)); - else - mpz_set_ui(z, l); - } - else - { - mpz_neg(z, w); - if (mpz_fits_ulong_p(z)) - mpz_set_ui(z, l % mpz_get_ui(z)); - else - mpz_set_ui(z, l); - } - } - static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) - { - mpz_tdiv_r_ui (z, w, __gmpxx_abs_ui(l)); - } - static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) - { - if (mpz_fits_slong_p(w)) - mpz_set_si(z, l % mpz_get_si(w)); - else - { - /* if w is bigger than a long then the remainder is l unchanged, - unless l==LONG_MIN and w==-LONG_MIN in which case it's 0 */ - mpz_set_si (z, mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? 0 : l); - } - } - static void eval(mpz_ptr z, mpz_srcptr w, double d) - { __GMPXX_TMPZ_D; mpz_tdiv_r (z, w, temp); } - static void eval(mpz_ptr z, double d, mpz_srcptr w) - { __GMPXX_TMPZ_D; mpz_tdiv_r (z, temp, w); } -}; - -struct __gmp_binary_and -{ - static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) - { mpz_and(z, w, v); } - - static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) - { __GMPXX_TMPZ_UI; mpz_and (z, w, temp); } - static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) - { __GMPXX_TMPZ_SI; mpz_and (z, w, temp); } - static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, double d) - { __GMPXX_TMPZ_D; mpz_and (z, w, temp); } - static void eval(mpz_ptr z, double d, mpz_srcptr w) - { eval(z, w, d); } -}; - -struct __gmp_binary_ior -{ - static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) - { mpz_ior(z, w, v); } - static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) - { __GMPXX_TMPZ_UI; mpz_ior (z, w, temp); } - static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) - { __GMPXX_TMPZ_SI; mpz_ior (z, w, temp); } - static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, double d) - { __GMPXX_TMPZ_D; mpz_ior (z, w, temp); } - static void eval(mpz_ptr z, double d, mpz_srcptr w) - { eval(z, w, d); } -}; - -struct __gmp_binary_xor -{ - static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) - { mpz_xor(z, w, v); } - static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) - { __GMPXX_TMPZ_UI; mpz_xor (z, w, temp); } - static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) - { __GMPXX_TMPZ_SI; mpz_xor (z, w, temp); } - static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, double d) - { __GMPXX_TMPZ_D; mpz_xor (z, w, temp); } - static void eval(mpz_ptr z, double d, mpz_srcptr w) - { eval(z, w, d); } -}; - -struct __gmp_cmp_function -{ - static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); } - - static int eval(mpz_srcptr z, unsigned long int l) - { return mpz_cmp_ui(z, l); } - static int eval(unsigned long int l, mpz_srcptr z) - { return -mpz_cmp_ui(z, l); } - static int eval(mpz_srcptr z, signed long int l) - { return mpz_cmp_si(z, l); } - static int eval(signed long int l, mpz_srcptr z) - { return -mpz_cmp_si(z, l); } - static int eval(mpz_srcptr z, double d) - { return mpz_cmp_d(z, d); } - static int eval(double d, mpz_srcptr z) - { return -mpz_cmp_d(z, d); } - - static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); } - - static int eval(mpq_srcptr q, unsigned long int l) - { return mpq_cmp_ui(q, l, 1); } - static int eval(unsigned long int l, mpq_srcptr q) - { return -mpq_cmp_ui(q, l, 1); } - static int eval(mpq_srcptr q, signed long int l) - { return mpq_cmp_si(q, l, 1); } - static int eval(signed long int l, mpq_srcptr q) - { return -mpq_cmp_si(q, l, 1); } - static int eval(mpq_srcptr q, double d) - { __GMPXX_TMPQ_D; return mpq_cmp (q, temp); } - static int eval(double d, mpq_srcptr q) - { __GMPXX_TMPQ_D; return mpq_cmp (temp, q); } - static int eval(mpq_srcptr q, mpz_srcptr z) - { return mpq_cmp_z(q, z); } - static int eval(mpz_srcptr z, mpq_srcptr q) - { return -mpq_cmp_z(q, z); } - - static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); } - - static int eval(mpf_srcptr f, unsigned long int l) - { return mpf_cmp_ui(f, l); } - static int eval(unsigned long int l, mpf_srcptr f) - { return -mpf_cmp_ui(f, l); } - static int eval(mpf_srcptr f, signed long int l) - { return mpf_cmp_si(f, l); } - static int eval(signed long int l, mpf_srcptr f) - { return -mpf_cmp_si(f, l); } - static int eval(mpf_srcptr f, double d) - { return mpf_cmp_d(f, d); } - static int eval(double d, mpf_srcptr f) - { return -mpf_cmp_d(f, d); } - static int eval(mpf_srcptr f, mpz_srcptr z) - { return mpf_cmp_z(f, z); } - static int eval(mpz_srcptr z, mpf_srcptr f) - { return -mpf_cmp_z(f, z); } - static int eval(mpf_srcptr f, mpq_srcptr q) - { - mpf_t qf; - mpf_init(qf); /* Should we use the precision of f? */ - mpf_set_q(qf, q); - int ret = eval(f, qf); - mpf_clear(qf); - return ret; - } - static int eval(mpq_srcptr q, mpf_srcptr f) - { return -eval(f, q); } -}; - -struct __gmp_binary_equal -{ - static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; } - - static bool eval(mpz_srcptr z, unsigned long int l) - { return mpz_cmp_ui(z, l) == 0; } - static bool eval(unsigned long int l, mpz_srcptr z) - { return eval(z, l); } - static bool eval(mpz_srcptr z, signed long int l) - { return mpz_cmp_si(z, l) == 0; } - static bool eval(signed long int l, mpz_srcptr z) - { return eval(z, l); } - static bool eval(mpz_srcptr z, double d) - { return mpz_cmp_d(z, d) == 0; } - static bool eval(double d, mpz_srcptr z) - { return eval(z, d); } - - static bool eval(mpq_srcptr q, mpq_srcptr r) - { return mpq_equal(q, r) != 0; } - - static bool eval(mpq_srcptr q, unsigned long int l) - { return ((__GMPXX_CONSTANT(l) && l == 0) || - mpz_cmp_ui(mpq_denref(q), 1) == 0) && - mpz_cmp_ui(mpq_numref(q), l) == 0; } - static bool eval(unsigned long int l, mpq_srcptr q) - { return eval(q, l); } - static bool eval(mpq_srcptr q, signed long int l) - { return ((__GMPXX_CONSTANT(l) && l == 0) || - mpz_cmp_ui(mpq_denref(q), 1) == 0) && - mpz_cmp_si(mpq_numref(q), l) == 0; } - static bool eval(signed long int l, mpq_srcptr q) - { return eval(q, l); } - static bool eval(mpq_srcptr q, double d) - { __GMPXX_TMPQ_D; return mpq_equal (q, temp) != 0; } - static bool eval(double d, mpq_srcptr q) - { return eval(q, d); } - static bool eval(mpq_srcptr q, mpz_srcptr z) - { return mpz_cmp_ui(mpq_denref(q), 1) == 0 && mpz_cmp(mpq_numref(q), z) == 0; } - static bool eval(mpz_srcptr z, mpq_srcptr q) - { return eval(q, z); } - - static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; } - - static bool eval(mpf_srcptr f, unsigned long int l) - { return mpf_cmp_ui(f, l) == 0; } - static bool eval(unsigned long int l, mpf_srcptr f) - { return eval(f, l); } - static bool eval(mpf_srcptr f, signed long int l) - { return mpf_cmp_si(f, l) == 0; } - static bool eval(signed long int l, mpf_srcptr f) - { return eval(f, l); } - static bool eval(mpf_srcptr f, double d) - { return mpf_cmp_d(f, d) == 0; } - static bool eval(double d, mpf_srcptr f) - { return eval(f, d); } - static bool eval(mpf_srcptr f, mpz_srcptr z) - { return mpf_cmp_z(f, z) == 0; } - static bool eval(mpz_srcptr z, mpf_srcptr f) - { return eval(f, z); } - static bool eval(mpf_srcptr f, mpq_srcptr q) - { return __gmp_cmp_function::eval(f, q) == 0; } - static bool eval(mpq_srcptr q, mpf_srcptr f) - { return eval(f, q); } -}; - -struct __gmp_binary_less -{ - static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; } - - static bool eval(mpz_srcptr z, unsigned long int l) - { return mpz_cmp_ui(z, l) < 0; } - static bool eval(unsigned long int l, mpz_srcptr z) - { return mpz_cmp_ui(z, l) > 0; } - static bool eval(mpz_srcptr z, signed long int l) - { return mpz_cmp_si(z, l) < 0; } - static bool eval(signed long int l, mpz_srcptr z) - { return mpz_cmp_si(z, l) > 0; } - static bool eval(mpz_srcptr z, double d) - { return mpz_cmp_d(z, d) < 0; } - static bool eval(double d, mpz_srcptr z) - { return mpz_cmp_d(z, d) > 0; } - - static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; } - - static bool eval(mpq_srcptr q, unsigned long int l) - { return mpq_cmp_ui(q, l, 1) < 0; } - static bool eval(unsigned long int l, mpq_srcptr q) - { return mpq_cmp_ui(q, l, 1) > 0; } - static bool eval(mpq_srcptr q, signed long int l) - { return mpq_cmp_si(q, l, 1) < 0; } - static bool eval(signed long int l, mpq_srcptr q) - { return mpq_cmp_si(q, l, 1) > 0; } - static bool eval(mpq_srcptr q, double d) - { __GMPXX_TMPQ_D; return mpq_cmp (q, temp) < 0; } - static bool eval(double d, mpq_srcptr q) - { __GMPXX_TMPQ_D; return mpq_cmp (temp, q) < 0; } - static bool eval(mpq_srcptr q, mpz_srcptr z) - { return mpq_cmp_z(q, z) < 0; } - static bool eval(mpz_srcptr z, mpq_srcptr q) - { return mpq_cmp_z(q, z) > 0; } - - static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; } - - static bool eval(mpf_srcptr f, unsigned long int l) - { return mpf_cmp_ui(f, l) < 0; } - static bool eval(unsigned long int l, mpf_srcptr f) - { return mpf_cmp_ui(f, l) > 0; } - static bool eval(mpf_srcptr f, signed long int l) - { return mpf_cmp_si(f, l) < 0; } - static bool eval(signed long int l, mpf_srcptr f) - { return mpf_cmp_si(f, l) > 0; } - static bool eval(mpf_srcptr f, double d) - { return mpf_cmp_d(f, d) < 0; } - static bool eval(double d, mpf_srcptr f) - { return mpf_cmp_d(f, d) > 0; } - static bool eval(mpf_srcptr f, mpz_srcptr z) - { return mpf_cmp_z(f, z) < 0; } - static bool eval(mpz_srcptr z, mpf_srcptr f) - { return mpf_cmp_z(f, z) > 0; } - static bool eval(mpf_srcptr f, mpq_srcptr q) - { return __gmp_cmp_function::eval(f, q) < 0; } - static bool eval(mpq_srcptr q, mpf_srcptr f) - { return __gmp_cmp_function::eval(q, f) < 0; } -}; - -struct __gmp_binary_greater -{ - template - static inline bool eval(T t, U u) { return __gmp_binary_less::eval(u, t); } -}; - -struct __gmp_unary_increment -{ - static void eval(mpz_ptr z) { mpz_add_ui(z, z, 1); } - static void eval(mpq_ptr q) - { mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q)); } - static void eval(mpf_ptr f) { mpf_add_ui(f, f, 1); } -}; - -struct __gmp_unary_decrement -{ - static void eval(mpz_ptr z) { mpz_sub_ui(z, z, 1); } - static void eval(mpq_ptr q) - { mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q)); } - static void eval(mpf_ptr f) { mpf_sub_ui(f, f, 1); } -}; - -struct __gmp_abs_function -{ - static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); } - static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); } - static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); } -}; - -struct __gmp_trunc_function -{ - static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); } -}; - -struct __gmp_floor_function -{ - static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); } -}; - -struct __gmp_ceil_function -{ - static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); } -}; - -struct __gmp_sqrt_function -{ - static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); } - static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); } -}; - -struct __gmp_hypot_function -{ - static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h) - { - mpf_t temp; - mpf_init2(temp, mpf_get_prec(f)); - mpf_mul(temp, g, g); - mpf_mul(f, h, h); - mpf_add(f, f, temp); - mpf_sqrt(f, f); - mpf_clear(temp); - } - - static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l) - { - mpf_t temp; - mpf_init2(temp, mpf_get_prec(f)); - mpf_mul(temp, g, g); - mpf_set_ui(f, l); - mpf_mul_ui(f, f, l); - mpf_add(f, f, temp); - mpf_clear(temp); - mpf_sqrt(f, f); - } - static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g) - { eval(f, g, l); } - static void eval(mpf_ptr f, mpf_srcptr g, signed long int l) - { eval(f, g, __gmpxx_abs_ui(l)); } - static void eval(mpf_ptr f, signed long int l, mpf_srcptr g) - { eval(f, g, l); } - static void eval(mpf_ptr f, mpf_srcptr g, double d) - { - mpf_t temp; - mpf_init2(temp, mpf_get_prec(f)); - mpf_mul(temp, g, g); - mpf_set_d(f, d); - mpf_mul(f, f, f); - mpf_add(f, f, temp); - mpf_sqrt(f, f); - mpf_clear(temp); - } - static void eval(mpf_ptr f, double d, mpf_srcptr g) - { eval(f, g, d); } -}; - -struct __gmp_sgn_function -{ - static int eval(mpz_srcptr z) { return mpz_sgn(z); } - static int eval(mpq_srcptr q) { return mpq_sgn(q); } - static int eval(mpf_srcptr f) { return mpf_sgn(f); } -}; - -struct __gmp_gcd_function -{ - static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) - { mpz_gcd(z, w, v); } - static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) - { mpz_gcd_ui(z, w, l); } - static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) - { eval(z, w, __gmpxx_abs_ui(l)); } - static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, double d) - { __GMPXX_TMPZ_D; mpz_gcd (z, w, temp); } - static void eval(mpz_ptr z, double d, mpz_srcptr w) - { eval(z, w, d); } -}; - -struct __gmp_lcm_function -{ - static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) - { mpz_lcm(z, w, v); } - static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) - { mpz_lcm_ui(z, w, l); } - static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) - { eval(z, w, __gmpxx_abs_ui(l)); } - static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) - { eval(z, w, l); } - static void eval(mpz_ptr z, mpz_srcptr w, double d) - { __GMPXX_TMPZ_D; mpz_lcm (z, w, temp); } - static void eval(mpz_ptr z, double d, mpz_srcptr w) - { eval(z, w, d); } -}; - -struct __gmp_rand_function -{ - static void eval(mpz_ptr z, gmp_randstate_t s, mp_bitcnt_t l) - { mpz_urandomb(z, s, l); } - static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w) - { mpz_urandomm(z, s, w); } - static void eval(mpf_ptr f, gmp_randstate_t s, mp_bitcnt_t prec) - { mpf_urandomb(f, s, prec); } -}; - -struct __gmp_fac_function -{ - static void eval(mpz_ptr z, unsigned long l) { mpz_fac_ui(z, l); } - static void eval(mpz_ptr z, signed long l) - { - if (l < 0) - throw std::domain_error ("factorial(negative)"); - eval(z, static_cast(l)); - } - static void eval(mpz_ptr z, mpz_srcptr w) - { - if (!mpz_fits_ulong_p(w)) - { - if (mpz_sgn(w) < 0) - throw std::domain_error ("factorial(negative)"); - else - throw std::bad_alloc(); // or std::overflow_error ("factorial")? - } - eval(z, mpz_get_ui(w)); - } - static void eval(mpz_ptr z, double d) - { __GMPXX_TMPZ_D; eval (z, temp); } -}; - -struct __gmp_primorial_function -{ - static void eval(mpz_ptr z, unsigned long l) { mpz_primorial_ui(z, l); } - static void eval(mpz_ptr z, signed long l) - { - if (l < 0) - throw std::domain_error ("primorial(negative)"); - eval(z, static_cast(l)); - } - static void eval(mpz_ptr z, mpz_srcptr w) - { - if (!mpz_fits_ulong_p(w)) - { - if (mpz_sgn(w) < 0) - throw std::domain_error ("primorial(negative)"); - else - throw std::bad_alloc(); // or std::overflow_error ("primorial")? - } - eval(z, mpz_get_ui(w)); - } - static void eval(mpz_ptr z, double d) - { __GMPXX_TMPZ_D; eval (z, temp); } -}; - -struct __gmp_fib_function -{ - static void eval(mpz_ptr z, unsigned long l) { mpz_fib_ui(z, l); } - static void eval(mpz_ptr z, signed long l) - { - if (l < 0) - { - eval(z, -static_cast(l)); - if ((l & 1) == 0) - mpz_neg(z, z); - } - else - eval(z, static_cast(l)); - } - static void eval(mpz_ptr z, mpz_srcptr w) - { - if (!mpz_fits_slong_p(w)) - throw std::bad_alloc(); // or std::overflow_error ("fibonacci")? - eval(z, mpz_get_si(w)); - } - static void eval(mpz_ptr z, double d) - { __GMPXX_TMPZ_D; eval (z, temp); } -}; - - -/**************** Auxiliary classes ****************/ - -/* this is much the same as gmp_allocated_string in gmp-impl.h - since gmp-impl.h is not publicly available, I redefine it here - I use a different name to avoid possible clashes */ - -extern "C" { - typedef void (*__gmp_freefunc_t) (void *, size_t); -} -struct __gmp_alloc_cstring -{ - char *str; - __gmp_alloc_cstring(char *s) { str = s; } - ~__gmp_alloc_cstring() - { - __gmp_freefunc_t freefunc; - mp_get_memory_functions (NULL, NULL, &freefunc); - (*freefunc) (str, std::strlen(str)+1); - } -}; - - -// general expression template class -template -class __gmp_expr; - - -// templates for resolving expression types -template -struct __gmp_resolve_ref -{ - typedef T ref_type; -}; - -template -struct __gmp_resolve_ref<__gmp_expr > -{ - typedef const __gmp_expr & ref_type; -}; - - -template -struct __gmp_resolve_expr; - -template <> -struct __gmp_resolve_expr -{ - typedef mpz_t value_type; - typedef mpz_ptr ptr_type; - typedef mpz_srcptr srcptr_type; -}; - -template <> -struct __gmp_resolve_expr -{ - typedef mpq_t value_type; - typedef mpq_ptr ptr_type; - typedef mpq_srcptr srcptr_type; -}; - -template <> -struct __gmp_resolve_expr -{ - typedef mpf_t value_type; - typedef mpf_ptr ptr_type; - typedef mpf_srcptr srcptr_type; -}; - -template <> -struct __gmp_resolve_expr -{ - typedef mpq_t value_type; -}; - -template <> -struct __gmp_resolve_expr -{ - typedef mpq_t value_type; -}; - -template <> -struct __gmp_resolve_expr -{ - typedef mpf_t value_type; -}; - -template <> -struct __gmp_resolve_expr -{ - typedef mpf_t value_type; -}; - -template <> -struct __gmp_resolve_expr -{ - typedef mpf_t value_type; -}; - -template <> -struct __gmp_resolve_expr -{ - typedef mpf_t value_type; -}; - -#if __GMPXX_USE_CXX11 -namespace std { - template - struct common_type <__gmp_expr, __gmp_expr > - { - private: - typedef typename __gmp_resolve_expr::value_type X; - public: - typedef __gmp_expr type; - }; - - template - struct common_type <__gmp_expr > - { - typedef __gmp_expr type; - }; - -#define __GMPXX_DECLARE_COMMON_TYPE(typ) \ - template \ - struct common_type <__gmp_expr, typ > \ - { \ - typedef __gmp_expr type; \ - }; \ - \ - template \ - struct common_type > \ - { \ - typedef __gmp_expr type; \ - } - - __GMPXX_DECLARE_COMMON_TYPE(signed char); - __GMPXX_DECLARE_COMMON_TYPE(unsigned char); - __GMPXX_DECLARE_COMMON_TYPE(signed int); - __GMPXX_DECLARE_COMMON_TYPE(unsigned int); - __GMPXX_DECLARE_COMMON_TYPE(signed short int); - __GMPXX_DECLARE_COMMON_TYPE(unsigned short int); - __GMPXX_DECLARE_COMMON_TYPE(signed long int); - __GMPXX_DECLARE_COMMON_TYPE(unsigned long int); - __GMPXX_DECLARE_COMMON_TYPE(float); - __GMPXX_DECLARE_COMMON_TYPE(double); -#undef __GMPXX_DECLARE_COMMON_TYPE -} -#endif - -// classes for evaluating unary and binary expressions -template -struct __gmp_unary_expr -{ - typename __gmp_resolve_ref::ref_type val; - - __gmp_unary_expr(const T &v) : val(v) { } -private: - __gmp_unary_expr(); -}; - -template -struct __gmp_binary_expr -{ - typename __gmp_resolve_ref::ref_type val1; - typename __gmp_resolve_ref::ref_type val2; - - __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { } -private: - __gmp_binary_expr(); -}; - - - -/**************** Macros for in-class declarations ****************/ -/* This is just repetitive code that is easier to maintain if it's written - only once */ - -#define __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \ - template \ - __gmp_expr & fun(const __gmp_expr &); - -#define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \ - __gmp_expr & fun(signed char); \ - __gmp_expr & fun(unsigned char); \ - __gmp_expr & fun(signed int); \ - __gmp_expr & fun(unsigned int); \ - __gmp_expr & fun(signed short int); \ - __gmp_expr & fun(unsigned short int); \ - __gmp_expr & fun(signed long int); \ - __gmp_expr & fun(unsigned long int); \ - __gmp_expr & fun(float); \ - __gmp_expr & fun(double); \ - /* __gmp_expr & fun(long double); */ - -#define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \ -__GMPP_DECLARE_COMPOUND_OPERATOR(fun) \ -__GMPN_DECLARE_COMPOUND_OPERATOR(fun) - -#define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \ - __gmp_expr & fun(mp_bitcnt_t); - -#define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \ - inline __gmp_expr & fun(); \ - inline __gmp_expr fun(int); - -#define __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS \ - __gmp_expr(signed char c) { init_si(c); } \ - __gmp_expr(unsigned char c) { init_ui(c); } \ - __gmp_expr(signed int i) { init_si(i); } \ - __gmp_expr(unsigned int i) { init_ui(i); } \ - __gmp_expr(signed short int s) { init_si(s); } \ - __gmp_expr(unsigned short int s) { init_ui(s); } \ - __gmp_expr(signed long int l) { init_si(l); } \ - __gmp_expr(unsigned long int l) { init_ui(l); } \ - __gmp_expr(float f) { init_d(f); } \ - __gmp_expr(double d) { init_d(d); } - -#define __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS \ - __gmp_expr & operator=(signed char c) { assign_si(c); return *this; } \ - __gmp_expr & operator=(unsigned char c) { assign_ui(c); return *this; } \ - __gmp_expr & operator=(signed int i) { assign_si(i); return *this; } \ - __gmp_expr & operator=(unsigned int i) { assign_ui(i); return *this; } \ - __gmp_expr & operator=(signed short int s) { assign_si(s); return *this; } \ - __gmp_expr & operator=(unsigned short int s) { assign_ui(s); return *this; } \ - __gmp_expr & operator=(signed long int l) { assign_si(l); return *this; } \ - __gmp_expr & operator=(unsigned long int l) { assign_ui(l); return *this; } \ - __gmp_expr & operator=(float f) { assign_d(f); return *this; } \ - __gmp_expr & operator=(double d) { assign_d(d); return *this; } - -#define __GMPP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \ -template \ -static __gmp_expr, eval_fun> > \ -fun(const __gmp_expr &expr); - -#define __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, bigtype) \ -static inline __gmp_expr > \ -fun(type expr); - -#define __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ -__GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long) -#define __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ -__GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long) -#define __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ -__GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double) - -#define __GMPN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \ -__GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char) \ -__GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char) \ -__GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int) \ -__GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int) \ -__GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int) \ -__GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int) \ -__GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int) \ -__GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int) \ -__GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float) \ -__GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double) - -#define __GMP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \ -__GMPP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \ -__GMPN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) - -/**************** mpz_class -- wrapper for mpz_t ****************/ - -template <> -class __gmp_expr -{ -private: - typedef mpz_t value_type; - value_type mp; - - // Helper functions used for all arithmetic types - void assign_ui(unsigned long l) - { - if (__GMPXX_CONSTANT_TRUE(l == 0)) - mp->_mp_size = 0; - else - mpz_set_ui(mp, l); - } - void assign_si(signed long l) - { - if (__GMPXX_CONSTANT_TRUE(l >= 0)) - assign_ui(l); - else if (__GMPXX_CONSTANT_TRUE(l <= 0)) - { - assign_ui(-static_cast(l)); - mpz_neg(mp, mp); - } - else - mpz_set_si(mp, l); - } - void assign_d (double d) - { - mpz_set_d (mp, d); - } - - void init_ui(unsigned long l) - { - if (__GMPXX_CONSTANT_TRUE(l == 0)) - mpz_init(mp); - else - mpz_init_set_ui(mp, l); - } - void init_si(signed long l) - { - if (__GMPXX_CONSTANT_TRUE(l >= 0)) - init_ui(l); - else if (__GMPXX_CONSTANT_TRUE(l <= 0)) - { - init_ui(-static_cast(l)); - mpz_neg(mp, mp); - } - else - mpz_init_set_si(mp, l); - } - void init_d (double d) - { - mpz_init_set_d (mp, d); - } - -public: - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } - - // constructors and destructor - __gmp_expr() __GMPXX_NOEXCEPT { mpz_init(mp); } - - __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); } -#if __GMPXX_USE_CXX11 - __gmp_expr(__gmp_expr &&z) noexcept - { *mp = *z.mp; mpz_init(z.mp); } -#endif - template - __gmp_expr(const __gmp_expr &expr) - { mpz_init(mp); __gmp_set_expr(mp, expr); } - template - explicit __gmp_expr(const __gmp_expr &expr) - { mpz_init(mp); __gmp_set_expr(mp, expr); } - - __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS - - explicit __gmp_expr(const char *s, int base = 0) - { - if (mpz_init_set_str (mp, s, base) != 0) - { - mpz_clear (mp); - throw std::invalid_argument ("mpz_set_str"); - } - } - explicit __gmp_expr(const std::string &s, int base = 0) - { - if (mpz_init_set_str(mp, s.c_str(), base) != 0) - { - mpz_clear (mp); - throw std::invalid_argument ("mpz_set_str"); - } - } - - explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); } - - ~__gmp_expr() { mpz_clear(mp); } - - void swap(__gmp_expr& z) __GMPXX_NOEXCEPT { std::swap(*mp, *z.mp); } - - // assignment operators - __gmp_expr & operator=(const __gmp_expr &z) - { mpz_set(mp, z.mp); return *this; } -#if __GMPXX_USE_CXX11 - __gmp_expr & operator=(__gmp_expr &&z) noexcept - { swap(z); return *this; } -#endif - template - __gmp_expr & operator=(const __gmp_expr &expr) - { __gmp_set_expr(mp, expr); return *this; } - - __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS - - __gmp_expr & operator=(const char *s) - { - if (mpz_set_str (mp, s, 0) != 0) - throw std::invalid_argument ("mpz_set_str"); - return *this; - } - __gmp_expr & operator=(const std::string &s) - { - if (mpz_set_str(mp, s.c_str(), 0) != 0) - throw std::invalid_argument ("mpz_set_str"); - return *this; - } - - // string input/output functions - int set_str(const char *s, int base) - { return mpz_set_str(mp, s, base); } - int set_str(const std::string &s, int base) - { return mpz_set_str(mp, s.c_str(), base); } - std::string get_str(int base = 10) const - { - __gmp_alloc_cstring temp(mpz_get_str(0, base, mp)); - return std::string(temp.str); - } - - // conversion functions - mpz_srcptr __get_mp() const { return mp; } - mpz_ptr __get_mp() { return mp; } - mpz_srcptr get_mpz_t() const { return mp; } - mpz_ptr get_mpz_t() { return mp; } - - signed long int get_si() const { return mpz_get_si(mp); } - unsigned long int get_ui() const { return mpz_get_ui(mp); } - double get_d() const { return mpz_get_d(mp); } - - // bool fits_schar_p() const { return mpz_fits_schar_p(mp); } - // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); } - bool fits_sint_p() const { return mpz_fits_sint_p(mp); } - bool fits_uint_p() const { return mpz_fits_uint_p(mp); } - bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); } - bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); } - bool fits_slong_p() const { return mpz_fits_slong_p(mp); } - bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); } - // bool fits_float_p() const { return mpz_fits_float_p(mp); } - // bool fits_double_p() const { return mpz_fits_double_p(mp); } - // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); } - -#if __GMPXX_USE_CXX11 - explicit operator bool() const { return mp->_mp_size != 0; } -#endif - - // member operators - __GMP_DECLARE_COMPOUND_OPERATOR(operator+=) - __GMP_DECLARE_COMPOUND_OPERATOR(operator-=) - __GMP_DECLARE_COMPOUND_OPERATOR(operator*=) - __GMP_DECLARE_COMPOUND_OPERATOR(operator/=) - __GMP_DECLARE_COMPOUND_OPERATOR(operator%=) - - __GMP_DECLARE_COMPOUND_OPERATOR(operator&=) - __GMP_DECLARE_COMPOUND_OPERATOR(operator|=) - __GMP_DECLARE_COMPOUND_OPERATOR(operator^=) - - __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=) - __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=) - - __GMP_DECLARE_INCREMENT_OPERATOR(operator++) - __GMP_DECLARE_INCREMENT_OPERATOR(operator--) - - __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, factorial, __gmp_fac_function) - __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, primorial, __gmp_primorial_function) - __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, fibonacci, __gmp_fib_function) -}; - -typedef __gmp_expr mpz_class; - - -/**************** mpq_class -- wrapper for mpq_t ****************/ - -template <> -class __gmp_expr -{ -private: - typedef mpq_t value_type; - value_type mp; - - // Helper functions used for all arithmetic types - void assign_ui(unsigned long l) { mpq_set_ui(mp, l, 1); } - void assign_si(signed long l) - { - if (__GMPXX_CONSTANT_TRUE(l >= 0)) - assign_ui(l); - else - mpq_set_si(mp, l, 1); - } - void assign_d (double d) { mpq_set_d (mp, d); } - - void init_ui(unsigned long l) { mpq_init(mp); get_num() = l; } - void init_si(signed long l) { mpq_init(mp); get_num() = l; } - void init_d (double d) { mpq_init(mp); assign_d (d); } - -public: - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } - void canonicalize() { mpq_canonicalize(mp); } - - // constructors and destructor - __gmp_expr() { mpq_init(mp); } - - __gmp_expr(const __gmp_expr &q) - { - mpz_init_set(mpq_numref(mp), mpq_numref(q.mp)); - mpz_init_set(mpq_denref(mp), mpq_denref(q.mp)); - } -#if __GMPXX_USE_CXX11 - __gmp_expr(__gmp_expr &&q) - { *mp = *q.mp; mpq_init(q.mp); } -#endif - template - __gmp_expr(const __gmp_expr &expr) - { mpq_init(mp); __gmp_set_expr(mp, expr); } - template - __gmp_expr(const __gmp_expr &expr) - { mpq_init(mp); __gmp_set_expr(mp, expr); } - template - explicit __gmp_expr(const __gmp_expr &expr) - { mpq_init(mp); __gmp_set_expr(mp, expr); } - - __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS - - explicit __gmp_expr(const char *s, int base = 0) - { - mpq_init (mp); - // If s is the literal 0, we meant to call another constructor. - // If s just happens to evaluate to 0, we would crash, so whatever. - if (s == 0) - { - // Don't turn mpq_class(0,0) into 0 - mpz_set_si(mpq_denref(mp), base); - } - else if (mpq_set_str(mp, s, base) != 0) - { - mpq_clear (mp); - throw std::invalid_argument ("mpq_set_str"); - } - } - explicit __gmp_expr(const std::string &s, int base = 0) - { - mpq_init(mp); - if (mpq_set_str (mp, s.c_str(), base) != 0) - { - mpq_clear (mp); - throw std::invalid_argument ("mpq_set_str"); - } - } - explicit __gmp_expr(mpq_srcptr q) - { - mpz_init_set(mpq_numref(mp), mpq_numref(q)); - mpz_init_set(mpq_denref(mp), mpq_denref(q)); - } - - __gmp_expr(const mpz_class &num, const mpz_class &den) - { - mpz_init_set(mpq_numref(mp), num.get_mpz_t()); - mpz_init_set(mpq_denref(mp), den.get_mpz_t()); - } - - ~__gmp_expr() { mpq_clear(mp); } - - void swap(__gmp_expr& q) __GMPXX_NOEXCEPT { std::swap(*mp, *q.mp); } - - // assignment operators - __gmp_expr & operator=(const __gmp_expr &q) - { mpq_set(mp, q.mp); return *this; } -#if __GMPXX_USE_CXX11 - __gmp_expr & operator=(__gmp_expr &&q) noexcept - { swap(q); return *this; } - __gmp_expr & operator=(mpz_class &&z) noexcept - { get_num() = std::move(z); get_den() = 1u; return *this; } -#endif - template - __gmp_expr & operator=(const __gmp_expr &expr) - { __gmp_set_expr(mp, expr); return *this; } - - __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS - - __gmp_expr & operator=(const char *s) - { - if (mpq_set_str (mp, s, 0) != 0) - throw std::invalid_argument ("mpq_set_str"); - return *this; - } - __gmp_expr & operator=(const std::string &s) - { - if (mpq_set_str(mp, s.c_str(), 0) != 0) - throw std::invalid_argument ("mpq_set_str"); - return *this; - } - - // string input/output functions - int set_str(const char *s, int base) - { return mpq_set_str(mp, s, base); } - int set_str(const std::string &s, int base) - { return mpq_set_str(mp, s.c_str(), base); } - std::string get_str(int base = 10) const - { - __gmp_alloc_cstring temp(mpq_get_str(0, base, mp)); - return std::string(temp.str); - } - - // conversion functions - - // casting a reference to an mpz_t to mpz_class & is a dirty hack, - // but works because the internal representation of mpz_class is - // exactly an mpz_t - const mpz_class & get_num() const - { return reinterpret_cast(*mpq_numref(mp)); } - mpz_class & get_num() - { return reinterpret_cast(*mpq_numref(mp)); } - const mpz_class & get_den() const - { return reinterpret_cast(*mpq_denref(mp)); } - mpz_class & get_den() - { return reinterpret_cast(*mpq_denref(mp)); } - - mpq_srcptr __get_mp() const { return mp; } - mpq_ptr __get_mp() { return mp; } - mpq_srcptr get_mpq_t() const { return mp; } - mpq_ptr get_mpq_t() { return mp; } - - mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); } - mpz_ptr get_num_mpz_t() { return mpq_numref(mp); } - mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); } - mpz_ptr get_den_mpz_t() { return mpq_denref(mp); } - - double get_d() const { return mpq_get_d(mp); } - -#if __GMPXX_USE_CXX11 - explicit operator bool() const { return mpq_numref(mp)->_mp_size != 0; } -#endif - - // compound assignments - __GMP_DECLARE_COMPOUND_OPERATOR(operator+=) - __GMP_DECLARE_COMPOUND_OPERATOR(operator-=) - __GMP_DECLARE_COMPOUND_OPERATOR(operator*=) - __GMP_DECLARE_COMPOUND_OPERATOR(operator/=) - - __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=) - __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=) - - __GMP_DECLARE_INCREMENT_OPERATOR(operator++) - __GMP_DECLARE_INCREMENT_OPERATOR(operator--) -}; - -typedef __gmp_expr mpq_class; - - -/**************** mpf_class -- wrapper for mpf_t ****************/ - -template <> -class __gmp_expr -{ -private: - typedef mpf_t value_type; - value_type mp; - - // Helper functions used for all arithmetic types - void assign_ui(unsigned long l) { mpf_set_ui(mp, l); } - void assign_si(signed long l) - { - if (__GMPXX_CONSTANT_TRUE(l >= 0)) - assign_ui(l); - else - mpf_set_si(mp, l); - } - void assign_d (double d) { mpf_set_d (mp, d); } - - void init_ui(unsigned long l) - { - if (__GMPXX_CONSTANT_TRUE(l == 0)) - mpf_init(mp); - else - mpf_init_set_ui(mp, l); - } - void init_si(signed long l) - { - if (__GMPXX_CONSTANT_TRUE(l >= 0)) - init_ui(l); - else - mpf_init_set_si(mp, l); - } - void init_d (double d) { mpf_init_set_d (mp, d); } - -public: - mp_bitcnt_t get_prec() const { return mpf_get_prec(mp); } - - void set_prec(mp_bitcnt_t prec) { mpf_set_prec(mp, prec); } - void set_prec_raw(mp_bitcnt_t prec) { mpf_set_prec_raw(mp, prec); } - - // constructors and destructor - __gmp_expr() { mpf_init(mp); } - - __gmp_expr(const __gmp_expr &f) - { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); } -#if __GMPXX_USE_CXX11 - __gmp_expr(__gmp_expr &&f) - { *mp = *f.mp; mpf_init2(f.mp, get_prec()); } -#endif - __gmp_expr(const __gmp_expr &f, mp_bitcnt_t prec) - { mpf_init2(mp, prec); mpf_set(mp, f.mp); } - template - __gmp_expr(const __gmp_expr &expr) - { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); } - template - __gmp_expr(const __gmp_expr &expr, mp_bitcnt_t prec) - { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); } - - __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS - - __gmp_expr(signed char c, mp_bitcnt_t prec) - { mpf_init2(mp, prec); mpf_set_si(mp, c); } - __gmp_expr(unsigned char c, mp_bitcnt_t prec) - { mpf_init2(mp, prec); mpf_set_ui(mp, c); } - - __gmp_expr(signed int i, mp_bitcnt_t prec) - { mpf_init2(mp, prec); mpf_set_si(mp, i); } - __gmp_expr(unsigned int i, mp_bitcnt_t prec) - { mpf_init2(mp, prec); mpf_set_ui(mp, i); } - - __gmp_expr(signed short int s, mp_bitcnt_t prec) - { mpf_init2(mp, prec); mpf_set_si(mp, s); } - __gmp_expr(unsigned short int s, mp_bitcnt_t prec) - { mpf_init2(mp, prec); mpf_set_ui(mp, s); } - - __gmp_expr(signed long int l, mp_bitcnt_t prec) - { mpf_init2(mp, prec); mpf_set_si(mp, l); } - __gmp_expr(unsigned long int l, mp_bitcnt_t prec) - { mpf_init2(mp, prec); mpf_set_ui(mp, l); } - - __gmp_expr(float f, mp_bitcnt_t prec) - { mpf_init2(mp, prec); mpf_set_d(mp, f); } - __gmp_expr(double d, mp_bitcnt_t prec) - { mpf_init2(mp, prec); mpf_set_d(mp, d); } - // __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); } - // __gmp_expr(long double ld, mp_bitcnt_t prec) - // { mpf_init2(mp, prec); mpf_set_d(mp, ld); } - - explicit __gmp_expr(const char *s) - { - if (mpf_init_set_str (mp, s, 0) != 0) - { - mpf_clear (mp); - throw std::invalid_argument ("mpf_set_str"); - } - } - __gmp_expr(const char *s, mp_bitcnt_t prec, int base = 0) - { - mpf_init2(mp, prec); - if (mpf_set_str(mp, s, base) != 0) - { - mpf_clear (mp); - throw std::invalid_argument ("mpf_set_str"); - } - } - explicit __gmp_expr(const std::string &s) - { - if (mpf_init_set_str(mp, s.c_str(), 0) != 0) - { - mpf_clear (mp); - throw std::invalid_argument ("mpf_set_str"); - } - } - __gmp_expr(const std::string &s, mp_bitcnt_t prec, int base = 0) - { - mpf_init2(mp, prec); - if (mpf_set_str(mp, s.c_str(), base) != 0) - { - mpf_clear (mp); - throw std::invalid_argument ("mpf_set_str"); - } - } - - explicit __gmp_expr(mpf_srcptr f) - { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); } - __gmp_expr(mpf_srcptr f, mp_bitcnt_t prec) - { mpf_init2(mp, prec); mpf_set(mp, f); } - - ~__gmp_expr() { mpf_clear(mp); } - - void swap(__gmp_expr& f) __GMPXX_NOEXCEPT { std::swap(*mp, *f.mp); } - - // assignment operators - __gmp_expr & operator=(const __gmp_expr &f) - { mpf_set(mp, f.mp); return *this; } -#if __GMPXX_USE_CXX11 - __gmp_expr & operator=(__gmp_expr &&f) noexcept - { swap(f); return *this; } -#endif - template - __gmp_expr & operator=(const __gmp_expr &expr) - { __gmp_set_expr(mp, expr); return *this; } - - __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS - - __gmp_expr & operator=(const char *s) - { - if (mpf_set_str (mp, s, 0) != 0) - throw std::invalid_argument ("mpf_set_str"); - return *this; - } - __gmp_expr & operator=(const std::string &s) - { - if (mpf_set_str(mp, s.c_str(), 0) != 0) - throw std::invalid_argument ("mpf_set_str"); - return *this; - } - - // string input/output functions - int set_str(const char *s, int base) - { return mpf_set_str(mp, s, base); } - int set_str(const std::string &s, int base) - { return mpf_set_str(mp, s.c_str(), base); } - std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const - { - __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp)); - return std::string(temp.str); - } - - // conversion functions - mpf_srcptr __get_mp() const { return mp; } - mpf_ptr __get_mp() { return mp; } - mpf_srcptr get_mpf_t() const { return mp; } - mpf_ptr get_mpf_t() { return mp; } - - signed long int get_si() const { return mpf_get_si(mp); } - unsigned long int get_ui() const { return mpf_get_ui(mp); } - double get_d() const { return mpf_get_d(mp); } - - // bool fits_schar_p() const { return mpf_fits_schar_p(mp); } - // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); } - bool fits_sint_p() const { return mpf_fits_sint_p(mp); } - bool fits_uint_p() const { return mpf_fits_uint_p(mp); } - bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); } - bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); } - bool fits_slong_p() const { return mpf_fits_slong_p(mp); } - bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); } - // bool fits_float_p() const { return mpf_fits_float_p(mp); } - // bool fits_double_p() const { return mpf_fits_double_p(mp); } - // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); } - -#if __GMPXX_USE_CXX11 - explicit operator bool() const { return mpf_sgn(mp) != 0; } -#endif - - // compound assignments - __GMP_DECLARE_COMPOUND_OPERATOR(operator+=) - __GMP_DECLARE_COMPOUND_OPERATOR(operator-=) - __GMP_DECLARE_COMPOUND_OPERATOR(operator*=) - __GMP_DECLARE_COMPOUND_OPERATOR(operator/=) - - __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=) - __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=) - - __GMP_DECLARE_INCREMENT_OPERATOR(operator++) - __GMP_DECLARE_INCREMENT_OPERATOR(operator--) -}; - -typedef __gmp_expr mpf_class; - - - -/**************** User-defined literals ****************/ - -#if __GMPXX_USE_CXX11 -inline mpz_class operator"" _mpz(const char* s) -{ - return mpz_class(s); -} - -inline mpq_class operator"" _mpq(const char* s) -{ - mpq_class q; - q.get_num() = s; - return q; -} - -inline mpf_class operator"" _mpf(const char* s) -{ - return mpf_class(s); -} -#endif - -/**************** I/O operators ****************/ - -// these should (and will) be provided separately - -template -inline std::ostream & operator<< -(std::ostream &o, const __gmp_expr &expr) -{ - __gmp_expr const& temp(expr); - return o << temp.__get_mp(); -} - -template -inline std::istream & operator>>(std::istream &i, __gmp_expr &expr) -{ - return i >> expr.__get_mp(); -} - -/* -// you might want to uncomment this -inline std::istream & operator>>(std::istream &i, mpq_class &q) -{ - i >> q.get_mpq_t(); - q.canonicalize(); - return i; -} -*/ - - -/**************** Functions for type conversion ****************/ - -inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w) -{ - mpz_set(z, w.get_mpz_t()); -} - -template -inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr &expr) -{ - expr.eval(z); -} - -template -inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr &expr) -{ - mpq_class const& temp(expr); - mpz_set_q(z, temp.get_mpq_t()); -} - -template -inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr &expr) -{ - mpf_class const& temp(expr); - mpz_set_f(z, temp.get_mpf_t()); -} - -inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z) -{ - mpq_set_z(q, z.get_mpz_t()); -} - -template -inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr &expr) -{ - __gmp_set_expr(mpq_numref(q), expr); - mpz_set_ui(mpq_denref(q), 1); -} - -inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r) -{ - mpq_set(q, r.get_mpq_t()); -} - -template -inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr &expr) -{ - expr.eval(q); -} - -template -inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr &expr) -{ - mpf_class const& temp(expr); - mpq_set_f(q, temp.get_mpf_t()); -} - -template -inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr &expr) -{ - mpz_class const& temp(expr); - mpf_set_z(f, temp.get_mpz_t()); -} - -template -inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr &expr) -{ - mpq_class const& temp(expr); - mpf_set_q(f, temp.get_mpq_t()); -} - -inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g) -{ - mpf_set(f, g.get_mpf_t()); -} - -template -inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr &expr) -{ - expr.eval(f); -} - - -/* Temporary objects */ - -template -class __gmp_temp -{ - __gmp_expr val; - public: - template - __gmp_temp(U const& u, V) : val (u) {} - typename __gmp_resolve_expr::srcptr_type - __get_mp() const { return val.__get_mp(); } -}; - -template <> -class __gmp_temp -{ - mpf_class val; - public: - template - __gmp_temp(U const& u, mpf_ptr res) : val (u, mpf_get_prec(res)) {} - mpf_srcptr __get_mp() const { return val.__get_mp(); } -}; - -/**************** Specializations of __gmp_expr ****************/ -/* The eval() method of __gmp_expr evaluates the corresponding - expression and assigns the result to its argument, which is either an - mpz_t, mpq_t, or mpf_t as specified by the T argument. - Compound expressions are evaluated recursively (temporaries are created - to hold intermediate values), while for simple expressions the eval() - method of the appropriate function object (available as the Op argument - of either __gmp_unary_expr or __gmp_binary_expr) is - called. */ - - -/**************** Unary expressions ****************/ -/* cases: - - simple: argument is mp*_class, that is, __gmp_expr - - compound: argument is __gmp_expr (with U not equal to T) */ - - -// simple expressions - -template -class __gmp_expr, Op> > -{ -private: - typedef __gmp_expr val_type; - - __gmp_unary_expr expr; -public: - explicit __gmp_expr(const val_type &val) : expr(val) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { Op::eval(p, expr.val.__get_mp()); } - const val_type & get_val() const { return expr.val; } - mp_bitcnt_t get_prec() const { return expr.val.get_prec(); } -}; - - -// simple expressions, U is a built-in numerical type - -template -class __gmp_expr > -{ -private: - typedef U val_type; - - __gmp_unary_expr expr; -public: - explicit __gmp_expr(const val_type &val) : expr(val) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { Op::eval(p, expr.val); } - const val_type & get_val() const { return expr.val; } - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } -}; - - -// compound expressions - -template -class __gmp_expr, Op> > -{ -private: - typedef __gmp_expr val_type; - - __gmp_unary_expr expr; -public: - explicit __gmp_expr(const val_type &val) : expr(val) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { expr.val.eval(p); Op::eval(p, p); } - const val_type & get_val() const { return expr.val; } - mp_bitcnt_t get_prec() const { return expr.val.get_prec(); } -}; - - -/**************** Binary expressions ****************/ -/* simple: - - arguments are both mp*_class - - one argument is mp*_class, one is a built-in type - compound: - - one is mp*_class, one is __gmp_expr - - one is __gmp_expr, one is built-in - - both arguments are __gmp_expr<...> */ - - -// simple expressions - -template -class __gmp_expr -, __gmp_expr, Op> > -{ -private: - typedef __gmp_expr val1_type; - typedef __gmp_expr val2_type; - - __gmp_binary_expr expr; -public: - __gmp_expr(const val1_type &val1, const val2_type &val2) - : expr(val1, val2) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); } - const val1_type & get_val1() const { return expr.val1; } - const val2_type & get_val2() const { return expr.val2; } - mp_bitcnt_t get_prec() const - { - mp_bitcnt_t prec1 = expr.val1.get_prec(), - prec2 = expr.val2.get_prec(); - return (prec1 > prec2) ? prec1 : prec2; - } -}; - - -// simple expressions, U is a built-in numerical type - -template -class __gmp_expr, U, Op> > -{ -private: - typedef __gmp_expr val1_type; - typedef U val2_type; - - __gmp_binary_expr expr; -public: - __gmp_expr(const val1_type &val1, const val2_type &val2) - : expr(val1, val2) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { Op::eval(p, expr.val1.__get_mp(), expr.val2); } - const val1_type & get_val1() const { return expr.val1; } - const val2_type & get_val2() const { return expr.val2; } - mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); } -}; - -template -class __gmp_expr, Op> > -{ -private: - typedef U val1_type; - typedef __gmp_expr val2_type; - - __gmp_binary_expr expr; -public: - __gmp_expr(const val1_type &val1, const val2_type &val2) - : expr(val1, val2) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { Op::eval(p, expr.val1, expr.val2.__get_mp()); } - const val1_type & get_val1() const { return expr.val1; } - const val2_type & get_val2() const { return expr.val2; } - mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); } -}; - - -// compound expressions, one argument is a subexpression - -template -class __gmp_expr -, __gmp_expr, Op> > -{ -private: - typedef __gmp_expr val1_type; - typedef __gmp_expr val2_type; - - __gmp_binary_expr expr; -public: - __gmp_expr(const val1_type &val1, const val2_type &val2) - : expr(val1, val2) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { - if(p != expr.val1.__get_mp()) - { - __gmp_set_expr(p, expr.val2); - Op::eval(p, expr.val1.__get_mp(), p); - } - else - { - __gmp_temp temp(expr.val2, p); - Op::eval(p, expr.val1.__get_mp(), temp.__get_mp()); - } - } - const val1_type & get_val1() const { return expr.val1; } - const val2_type & get_val2() const { return expr.val2; } - mp_bitcnt_t get_prec() const - { - mp_bitcnt_t prec1 = expr.val1.get_prec(), - prec2 = expr.val2.get_prec(); - return (prec1 > prec2) ? prec1 : prec2; - } -}; - -template -class __gmp_expr -, __gmp_expr, Op> > -{ -private: - typedef __gmp_expr val1_type; - typedef __gmp_expr val2_type; - - __gmp_binary_expr expr; -public: - __gmp_expr(const val1_type &val1, const val2_type &val2) - : expr(val1, val2) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { - if(p != expr.val2.__get_mp()) - { - __gmp_set_expr(p, expr.val1); - Op::eval(p, p, expr.val2.__get_mp()); - } - else - { - __gmp_temp temp(expr.val1, p); - Op::eval(p, temp.__get_mp(), expr.val2.__get_mp()); - } - } - const val1_type & get_val1() const { return expr.val1; } - const val2_type & get_val2() const { return expr.val2; } - mp_bitcnt_t get_prec() const - { - mp_bitcnt_t prec1 = expr.val1.get_prec(), - prec2 = expr.val2.get_prec(); - return (prec1 > prec2) ? prec1 : prec2; - } -}; - -template -class __gmp_expr -, __gmp_expr, Op> > -{ -private: - typedef __gmp_expr val1_type; - typedef __gmp_expr val2_type; - - __gmp_binary_expr expr; -public: - __gmp_expr(const val1_type &val1, const val2_type &val2) - : expr(val1, val2) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { - if(p != expr.val1.__get_mp()) - { - __gmp_set_expr(p, expr.val2); - Op::eval(p, expr.val1.__get_mp(), p); - } - else - { - __gmp_temp temp(expr.val2, p); - Op::eval(p, expr.val1.__get_mp(), temp.__get_mp()); - } - } - const val1_type & get_val1() const { return expr.val1; } - const val2_type & get_val2() const { return expr.val2; } - mp_bitcnt_t get_prec() const - { - mp_bitcnt_t prec1 = expr.val1.get_prec(), - prec2 = expr.val2.get_prec(); - return (prec1 > prec2) ? prec1 : prec2; - } -}; - -template -class __gmp_expr -, __gmp_expr, Op> > -{ -private: - typedef __gmp_expr val1_type; - typedef __gmp_expr val2_type; - - __gmp_binary_expr expr; -public: - __gmp_expr(const val1_type &val1, const val2_type &val2) - : expr(val1, val2) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { - if(p != expr.val2.__get_mp()) - { - __gmp_set_expr(p, expr.val1); - Op::eval(p, p, expr.val2.__get_mp()); - } - else - { - __gmp_temp temp(expr.val1, p); - Op::eval(p, temp.__get_mp(), expr.val2.__get_mp()); - } - } - const val1_type & get_val1() const { return expr.val1; } - const val2_type & get_val2() const { return expr.val2; } - mp_bitcnt_t get_prec() const - { - mp_bitcnt_t prec1 = expr.val1.get_prec(), - prec2 = expr.val2.get_prec(); - return (prec1 > prec2) ? prec1 : prec2; - } -}; - - -// one argument is a subexpression, one is a built-in - -template -class __gmp_expr, V, Op> > -{ -private: - typedef __gmp_expr val1_type; - typedef V val2_type; - - __gmp_binary_expr expr; -public: - __gmp_expr(const val1_type &val1, const val2_type &val2) - : expr(val1, val2) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { - expr.val1.eval(p); - Op::eval(p, p, expr.val2); - } - const val1_type & get_val1() const { return expr.val1; } - const val2_type & get_val2() const { return expr.val2; } - mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); } -}; - -template -class __gmp_expr, Op> > -{ -private: - typedef U val1_type; - typedef __gmp_expr val2_type; - - __gmp_binary_expr expr; -public: - __gmp_expr(const val1_type &val1, const val2_type &val2) - : expr(val1, val2) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { - expr.val2.eval(p); - Op::eval(p, expr.val1, p); - } - const val1_type & get_val1() const { return expr.val1; } - const val2_type & get_val2() const { return expr.val2; } - mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); } -}; - - -// both arguments are subexpressions - -template -class __gmp_expr -, __gmp_expr, Op> > -{ -private: - typedef __gmp_expr val1_type; - typedef __gmp_expr val2_type; - - __gmp_binary_expr expr; -public: - __gmp_expr(const val1_type &val1, const val2_type &val2) - : expr(val1, val2) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { - __gmp_temp temp2(expr.val2, p); - expr.val1.eval(p); - Op::eval(p, p, temp2.__get_mp()); - } - const val1_type & get_val1() const { return expr.val1; } - const val2_type & get_val2() const { return expr.val2; } - mp_bitcnt_t get_prec() const - { - mp_bitcnt_t prec1 = expr.val1.get_prec(), - prec2 = expr.val2.get_prec(); - return (prec1 > prec2) ? prec1 : prec2; - } -}; - -template -class __gmp_expr -, __gmp_expr, Op> > -{ -private: - typedef __gmp_expr val1_type; - typedef __gmp_expr val2_type; - - __gmp_binary_expr expr; -public: - __gmp_expr(const val1_type &val1, const val2_type &val2) - : expr(val1, val2) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { - __gmp_temp temp1(expr.val1, p); - expr.val2.eval(p); - Op::eval(p, temp1.__get_mp(), p); - } - const val1_type & get_val1() const { return expr.val1; } - const val2_type & get_val2() const { return expr.val2; } - mp_bitcnt_t get_prec() const - { - mp_bitcnt_t prec1 = expr.val1.get_prec(), - prec2 = expr.val2.get_prec(); - return (prec1 > prec2) ? prec1 : prec2; - } -}; - -template -class __gmp_expr -, __gmp_expr, Op> > -{ -private: - typedef __gmp_expr val1_type; - typedef __gmp_expr val2_type; - - __gmp_binary_expr expr; -public: - __gmp_expr(const val1_type &val1, const val2_type &val2) - : expr(val1, val2) { } - void eval(typename __gmp_resolve_expr::ptr_type p) const - { - __gmp_temp temp2(expr.val2, p); - expr.val1.eval(p); - Op::eval(p, p, temp2.__get_mp()); - } - const val1_type & get_val1() const { return expr.val1; } - const val2_type & get_val2() const { return expr.val2; } - mp_bitcnt_t get_prec() const - { - mp_bitcnt_t prec1 = expr.val1.get_prec(), - prec2 = expr.val2.get_prec(); - return (prec1 > prec2) ? prec1 : prec2; - } -}; - - -/**************** Special cases ****************/ - -/* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments - can be done directly without first converting the mpz to mpq. - Appropriate specializations of __gmp_expr are required. */ - - -#define __GMPZQ_DEFINE_EXPR(eval_fun) \ - \ -template <> \ -class __gmp_expr > \ -{ \ -private: \ - typedef mpz_class val1_type; \ - typedef mpq_class val2_type; \ - \ - __gmp_binary_expr expr; \ -public: \ - __gmp_expr(const val1_type &val1, const val2_type &val2) \ - : expr(val1, val2) { } \ - void eval(mpq_ptr q) const \ - { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \ - const val1_type & get_val1() const { return expr.val1; } \ - const val2_type & get_val2() const { return expr.val2; } \ - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \ -}; \ - \ -template <> \ -class __gmp_expr > \ -{ \ -private: \ - typedef mpq_class val1_type; \ - typedef mpz_class val2_type; \ - \ - __gmp_binary_expr expr; \ -public: \ - __gmp_expr(const val1_type &val1, const val2_type &val2) \ - : expr(val1, val2) { } \ - void eval(mpq_ptr q) const \ - { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \ - const val1_type & get_val1() const { return expr.val1; } \ - const val2_type & get_val2() const { return expr.val2; } \ - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \ -}; \ - \ -template \ -class __gmp_expr \ -, eval_fun> > \ -{ \ -private: \ - typedef mpz_class val1_type; \ - typedef __gmp_expr val2_type; \ - \ - __gmp_binary_expr expr; \ -public: \ - __gmp_expr(const val1_type &val1, const val2_type &val2) \ - : expr(val1, val2) { } \ - void eval(mpq_ptr q) const \ - { \ - mpq_class temp(expr.val2); \ - eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \ - } \ - const val1_type & get_val1() const { return expr.val1; } \ - const val2_type & get_val2() const { return expr.val2; } \ - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \ -}; \ - \ -template \ -class __gmp_expr \ -, eval_fun> > \ -{ \ -private: \ - typedef mpq_class val1_type; \ - typedef __gmp_expr val2_type; \ - \ - __gmp_binary_expr expr; \ -public: \ - __gmp_expr(const val1_type &val1, const val2_type &val2) \ - : expr(val1, val2) { } \ - void eval(mpq_ptr q) const \ - { \ - mpz_class temp(expr.val2); \ - eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \ - } \ - const val1_type & get_val1() const { return expr.val1; } \ - const val2_type & get_val2() const { return expr.val2; } \ - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \ -}; \ - \ -template \ -class __gmp_expr \ -, mpq_class, eval_fun> > \ -{ \ -private: \ - typedef __gmp_expr val1_type; \ - typedef mpq_class val2_type; \ - \ - __gmp_binary_expr expr; \ -public: \ - __gmp_expr(const val1_type &val1, const val2_type &val2) \ - : expr(val1, val2) { } \ - void eval(mpq_ptr q) const \ - { \ - mpz_class temp(expr.val1); \ - eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \ - } \ - const val1_type & get_val1() const { return expr.val1; } \ - const val2_type & get_val2() const { return expr.val2; } \ - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \ -}; \ - \ -template \ -class __gmp_expr \ -, mpz_class, eval_fun> > \ -{ \ -private: \ - typedef __gmp_expr val1_type; \ - typedef mpz_class val2_type; \ - \ - __gmp_binary_expr expr; \ -public: \ - __gmp_expr(const val1_type &val1, const val2_type &val2) \ - : expr(val1, val2) { } \ - void eval(mpq_ptr q) const \ - { \ - mpq_class temp(expr.val1); \ - eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \ - } \ - const val1_type & get_val1() const { return expr.val1; } \ - const val2_type & get_val2() const { return expr.val2; } \ - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \ -}; \ - \ -template \ -class __gmp_expr, __gmp_expr, eval_fun> > \ -{ \ -private: \ - typedef __gmp_expr val1_type; \ - typedef __gmp_expr val2_type; \ - \ - __gmp_binary_expr expr; \ -public: \ - __gmp_expr(const val1_type &val1, const val2_type &val2) \ - : expr(val1, val2) { } \ - void eval(mpq_ptr q) const \ - { \ - mpz_class temp1(expr.val1); \ - expr.val2.eval(q); \ - eval_fun::eval(q, temp1.get_mpz_t(), q); \ - } \ - const val1_type & get_val1() const { return expr.val1; } \ - const val2_type & get_val2() const { return expr.val2; } \ - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \ -}; \ - \ -template \ -class __gmp_expr, __gmp_expr, eval_fun> > \ -{ \ -private: \ - typedef __gmp_expr val1_type; \ - typedef __gmp_expr val2_type; \ - \ - __gmp_binary_expr expr; \ -public: \ - __gmp_expr(const val1_type &val1, const val2_type &val2) \ - : expr(val1, val2) { } \ - void eval(mpq_ptr q) const \ - { \ - mpz_class temp2(expr.val2); \ - expr.val1.eval(q); \ - eval_fun::eval(q, q, temp2.get_mpz_t()); \ - } \ - const val1_type & get_val1() const { return expr.val1; } \ - const val2_type & get_val2() const { return expr.val2; } \ - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \ -}; - - -__GMPZQ_DEFINE_EXPR(__gmp_binary_plus) -__GMPZQ_DEFINE_EXPR(__gmp_binary_minus) - - - -/**************** Macros for defining functions ****************/ -/* Results of operators and functions are instances of __gmp_expr. - T determines the numerical type of the expression: it can be either - mpz_t, mpq_t, or mpf_t. When the arguments of a binary - expression have different numerical types, __gmp_resolve_expr is used - to determine the "larger" type. - U is either __gmp_unary_expr or __gmp_binary_expr, - where V and W are the arguments' types -- they can in turn be - expressions, thus allowing to build compound expressions to any - degree of complexity. - Op is a function object that must have an eval() method accepting - appropriate arguments. - Actual evaluation of a __gmp_expr object is done when it gets - assigned to an mp*_class ("lazy" evaluation): this is done by calling - its eval() method. */ - - -// non-member unary operators and functions - -#define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun) \ - \ -template \ -inline __gmp_expr, eval_fun> > \ -fun(const __gmp_expr &expr) \ -{ \ - return __gmp_expr, eval_fun> >(expr); \ -} - -// variant that only works for one of { mpz, mpq, mpf } - -#define __GMP_DEFINE_UNARY_FUNCTION_1(T, fun, eval_fun) \ - \ -template \ -inline __gmp_expr, eval_fun> > \ -fun(const __gmp_expr &expr) \ -{ \ - return __gmp_expr, eval_fun> >(expr); \ -} - -#define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \ - \ -template \ -inline type fun(const __gmp_expr &expr) \ -{ \ - __gmp_expr const& temp(expr); \ - return eval_fun::eval(temp.__get_mp()); \ -} - - -// non-member binary operators and functions - -#define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \ - \ -template \ -inline __gmp_expr::value_type, \ -__gmp_binary_expr<__gmp_expr, __gmp_expr, eval_fun> > \ -fun(const __gmp_expr &expr1, const __gmp_expr &expr2) \ -{ \ - return __gmp_expr::value_type, \ - __gmp_binary_expr<__gmp_expr, __gmp_expr, eval_fun> > \ - (expr1, expr2); \ -} - -#define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype) \ - \ -template \ -inline __gmp_expr \ -, bigtype, eval_fun> > \ -fun(const __gmp_expr &expr, type t) \ -{ \ - return __gmp_expr \ - , bigtype, eval_fun> >(expr, t); \ -} \ - \ -template \ -inline __gmp_expr \ -, eval_fun> > \ -fun(type t, const __gmp_expr &expr) \ -{ \ - return __gmp_expr \ - , eval_fun> >(t, expr); \ -} - -#define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \ -__GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int) - -#define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \ -__GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int) - -#define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \ -__GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double) - -#define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \ -__GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double) - -#define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \ -__GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \ -__GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \ -__GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \ -__GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \ -__GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \ -__GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \ -__GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \ -__GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \ -__GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \ -__GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \ -/* __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double) */ - -#define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \ -__GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \ -__GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) - -// variant that only works for one of { mpz, mpq, mpf } - -#define __GMPP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \ - \ -template \ -inline __gmp_expr, __gmp_expr, eval_fun> > \ -fun(const __gmp_expr &expr1, const __gmp_expr &expr2) \ -{ \ - return __gmp_expr, __gmp_expr, eval_fun> > \ - (expr1, expr2); \ -} - -#define __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, bigtype) \ - \ -template \ -inline __gmp_expr \ -, bigtype, eval_fun> > \ -fun(const __gmp_expr &expr, type t) \ -{ \ - return __gmp_expr \ - , bigtype, eval_fun> >(expr, t); \ -} \ - \ -template \ -inline __gmp_expr \ -, eval_fun> > \ -fun(type t, const __gmp_expr &expr) \ -{ \ - return __gmp_expr \ - , eval_fun> >(t, expr); \ -} - -#define __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \ -__GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, signed long int) - -#define __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \ -__GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, unsigned long int) - -#define __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \ -__GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, double) - -#define __GMPNLD_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \ -__GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, long double) - -#define __GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \ -__GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed char) \ -__GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned char) \ -__GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed int) \ -__GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned int) \ -__GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed short int) \ -__GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned short int) \ -__GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed long int) \ -__GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned long int) \ -__GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, float) \ -__GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, double) \ -/* __GMPNLD_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, long double) */ - -#define __GMP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \ -__GMPP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \ -__GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) - - -#define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun) \ - \ -template \ -inline __gmp_expr \ -, mp_bitcnt_t, eval_fun> > \ -fun(const __gmp_expr &expr, mp_bitcnt_t l) \ -{ \ - return __gmp_expr, mp_bitcnt_t, eval_fun> >(expr, l); \ -} - - -#define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \ - \ -template \ -inline type fun(const __gmp_expr &expr1, \ - const __gmp_expr &expr2) \ -{ \ - __gmp_expr const& temp1(expr1); \ - __gmp_expr const& temp2(expr2); \ - return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \ -} - -#define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \ - type2, bigtype) \ - \ -template \ -inline type fun(const __gmp_expr &expr, type2 t) \ -{ \ - __gmp_expr const& temp(expr); \ - return eval_fun::eval(temp.__get_mp(), static_cast(t)); \ -} \ - \ -template \ -inline type fun(type2 t, const __gmp_expr &expr) \ -{ \ - __gmp_expr const& temp(expr); \ - return eval_fun::eval(static_cast(t), temp.__get_mp()); \ -} - -#define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \ -__GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \ - type2, signed long int) - -#define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \ -__GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \ - type2, unsigned long int) - -#define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \ -__GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double) - -#define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \ -__GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double) - -#define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \ -__GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \ -__GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \ -__GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \ -__GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \ -__GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \ -__GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \ -__GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \ -__GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \ -__GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \ -__GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \ -/* __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double) */ - -#define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \ -__GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \ -__GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) - - -// member operators - -#define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \ - \ -template \ -inline type##_class & type##_class::fun(const __gmp_expr &expr) \ -{ \ - __gmp_set_expr(mp, __gmp_expr, eval_fun> >(*this, expr)); \ - return *this; \ -} - -#define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \ - type2, bigtype) \ - \ -inline type##_class & type##_class::fun(type2 t) \ -{ \ - __gmp_set_expr(mp, __gmp_expr >(*this, t)); \ - return *this; \ -} - -#define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \ -__GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \ - type2, signed long int) - -#define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \ -__GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \ - type2, unsigned long int) - -#define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \ -__GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double) - -#define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \ -__GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double) - -#define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \ -__GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \ -__GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \ -__GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \ -__GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \ -__GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \ -__GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \ -__GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \ -__GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \ -__GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \ -__GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \ -/* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */ - -#define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \ -__GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \ -__GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) - -#define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \ -__GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun) - -#define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \ -__GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun) - -#define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \ -__GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun) - - - -#define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun) \ - \ -inline type##_class & type##_class::fun(mp_bitcnt_t l) \ -{ \ - __gmp_set_expr(mp, __gmp_expr >(*this, l)); \ - return *this; \ -} - -#define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \ -__GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun) - -#define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \ -__GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun) - -#define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \ -__GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun) - - - -#define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \ - \ -inline type##_class & type##_class::fun() \ -{ \ - eval_fun::eval(mp); \ - return *this; \ -} \ - \ -inline type##_class type##_class::fun(int) \ -{ \ - type##_class temp(*this); \ - eval_fun::eval(mp); \ - return temp; \ -} - -#define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \ -__GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun) - -#define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \ -__GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun) - -#define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \ -__GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun) - - -#define __GMPP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \ -template \ -__gmp_expr, eval_fun> > \ -fun(const __gmp_expr &expr) \ -{ \ - return __gmp_expr, eval_fun> >(expr); \ -} - -#define __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, bigtype) \ -inline __gmp_expr > \ -fun(type expr) \ -{ \ - return __gmp_expr >(expr); \ -} - -#define __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ -__GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long) -#define __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ -__GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long) -#define __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ -__GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double) - -#define __GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \ -__GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char) \ -__GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char) \ -__GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int) \ -__GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int) \ -__GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int) \ -__GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int) \ -__GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int) \ -__GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int) \ -__GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float) \ -__GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double) \ - -#define __GMP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \ -__GMPP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \ -__GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \ - - -/**************** Arithmetic operators and functions ****************/ - -// non-member operators and functions - -__GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus) -__GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus) -__GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, operator~, __gmp_unary_com) - -__GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus) -__GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus) -__GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies) -__GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides) -__GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator%, __gmp_binary_modulus) -__GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator&, __gmp_binary_and) -__GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator|, __gmp_binary_ior) -__GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator^, __gmp_binary_xor) - -__GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift) -__GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift) - -__GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal) -__GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, ! __gmp_binary_equal) -__GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less) -__GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, ! __gmp_binary_greater) -__GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater) -__GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, ! __gmp_binary_less) - -__GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function) -__GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, trunc, __gmp_trunc_function) -__GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, floor, __gmp_floor_function) -__GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, ceil, __gmp_ceil_function) -__GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, sqrt, __gmp_sqrt_function) -__GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, sqrt, __gmp_sqrt_function) -__GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, factorial, __gmp_fac_function) -__GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, primorial, __gmp_primorial_function) -__GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, fibonacci, __gmp_fib_function) -__GMP_DEFINE_BINARY_FUNCTION_1(mpf_t, hypot, __gmp_hypot_function) -__GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, gcd, __gmp_gcd_function) -__GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, lcm, __gmp_lcm_function) - -__GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function) -__GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function) - -template -void swap(__gmp_expr& x, __gmp_expr& y) __GMPXX_NOEXCEPT -{ x.swap(y); } - -// member operators for mpz_class - -__GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus) -__GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus) -__GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies) -__GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides) -__GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus) - -__GMPZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and) -__GMPZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior) -__GMPZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor) - -__GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift) -__GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift) - -__GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment) -__GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement) - -__GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::factorial, __gmp_fac_function) -__GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::primorial, __gmp_primorial_function) -__GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::fibonacci, __gmp_fib_function) - -// member operators for mpq_class - -__GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus) -__GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus) -__GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies) -__GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides) - -__GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift) -__GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift) - -__GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment) -__GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement) - -// member operators for mpf_class - -__GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus) -__GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus) -__GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies) -__GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides) - -__GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift) -__GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift) - -__GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment) -__GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement) - - - -/**************** Class wrapper for gmp_randstate_t ****************/ - -class __gmp_urandomb_value { }; -class __gmp_urandomm_value { }; - -template <> -class __gmp_expr -{ -private: - __gmp_randstate_struct *state; - mp_bitcnt_t bits; -public: - __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { } - void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); } - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } -}; - -template <> -class __gmp_expr -{ -private: - __gmp_randstate_struct *state; - mpz_class range; -public: - __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { } - void eval(mpz_ptr z) const - { __gmp_rand_function::eval(z, state, range.get_mpz_t()); } - mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } -}; - -template <> -class __gmp_expr -{ -private: - __gmp_randstate_struct *state; - mp_bitcnt_t bits; -public: - __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { } - void eval(mpf_ptr f) const - { - __gmp_rand_function::eval(f, state, - (bits>0) ? bits : mpf_get_prec(f)); - } - mp_bitcnt_t get_prec() const - { - if (bits == 0) - return mpf_get_default_prec(); - else - return bits; - } -}; - -extern "C" { - typedef void __gmp_randinit_default_t (gmp_randstate_t); - typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, mp_bitcnt_t); - typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, mp_bitcnt_t); -} - -class gmp_randclass -{ -private: - gmp_randstate_t state; - - // copy construction and assignment not allowed - gmp_randclass(const gmp_randclass &); - void operator=(const gmp_randclass &); -public: - // constructors and destructor - gmp_randclass(gmp_randalg_t alg, unsigned long int size) - { - switch (alg) - { - case GMP_RAND_ALG_LC: // no other cases for now - default: - gmp_randinit(state, alg, size); - break; - } - } - - // gmp_randinit_default - gmp_randclass(__gmp_randinit_default_t* f) { f(state); } - - // gmp_randinit_lc_2exp - gmp_randclass(__gmp_randinit_lc_2exp_t* f, - mpz_class z, unsigned long int l1, mp_bitcnt_t l2) - { f(state, z.get_mpz_t(), l1, l2); } - - // gmp_randinit_lc_2exp_size - gmp_randclass(__gmp_randinit_lc_2exp_size_t* f, - mp_bitcnt_t size) - { - if (f (state, size) == 0) - throw std::length_error ("gmp_randinit_lc_2exp_size"); - } - - ~gmp_randclass() { gmp_randclear(state); } - - // initialize - void seed(); // choose a random seed some way (?) - void seed(unsigned long int s) { gmp_randseed_ui(state, s); } - void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); } - - // get random number - __gmp_expr get_z_bits(mp_bitcnt_t l) - { return __gmp_expr(state, l); } - __gmp_expr get_z_bits(const mpz_class &z) - { return get_z_bits(z.get_ui()); } - // FIXME: z.get_bitcnt_t() ? - - __gmp_expr get_z_range(const mpz_class &z) - { return __gmp_expr(state, z); } - - __gmp_expr get_f(mp_bitcnt_t prec = 0) - { return __gmp_expr(state, prec); } -}; - - -/**************** Specialize std::numeric_limits ****************/ - -namespace std { - template <> class numeric_limits - { - public: - static const bool is_specialized = true; - static mpz_class min() { return mpz_class(); } - static mpz_class max() { return mpz_class(); } - static mpz_class lowest() { return mpz_class(); } - static const int digits = 0; - static const int digits10 = 0; - static const int max_digits10 = 0; - static const bool is_signed = true; - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - static mpz_class epsilon() { return mpz_class(); } - static mpz_class round_error() { return mpz_class(); } - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - static mpz_class infinity() { return mpz_class(); } - static mpz_class quiet_NaN() { return mpz_class(); } - static mpz_class signaling_NaN() { return mpz_class(); } - static mpz_class denorm_min() { return mpz_class(); } - static const bool is_iec559 = false; - static const bool is_bounded = false; - static const bool is_modulo = false; - static const bool traps = false; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; - }; - - template <> class numeric_limits - { - public: - static const bool is_specialized = true; - static mpq_class min() { return mpq_class(); } - static mpq_class max() { return mpq_class(); } - static mpq_class lowest() { return mpq_class(); } - static const int digits = 0; - static const int digits10 = 0; - static const int max_digits10 = 0; - static const bool is_signed = true; - static const bool is_integer = false; - static const bool is_exact = true; - static const int radix = 2; - static mpq_class epsilon() { return mpq_class(); } - static mpq_class round_error() { return mpq_class(); } - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - static mpq_class infinity() { return mpq_class(); } - static mpq_class quiet_NaN() { return mpq_class(); } - static mpq_class signaling_NaN() { return mpq_class(); } - static mpq_class denorm_min() { return mpq_class(); } - static const bool is_iec559 = false; - static const bool is_bounded = false; - static const bool is_modulo = false; - static const bool traps = false; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; - }; - - template <> class numeric_limits - { - public: - static const bool is_specialized = true; - static mpf_class min() { return mpf_class(); } - static mpf_class max() { return mpf_class(); } - static mpf_class lowest() { return mpf_class(); } - static const int digits = 0; - static const int digits10 = 0; - static const int max_digits10 = 0; - static const bool is_signed = true; - static const bool is_integer = false; - static const bool is_exact = false; - static const int radix = 2; - static mpf_class epsilon() { return mpf_class(); } - static mpf_class round_error() { return mpf_class(); } - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - static mpf_class infinity() { return mpf_class(); } - static mpf_class quiet_NaN() { return mpf_class(); } - static mpf_class signaling_NaN() { return mpf_class(); } - static mpf_class denorm_min() { return mpf_class(); } - static const bool is_iec559 = false; - static const bool is_bounded = false; - static const bool is_modulo = false; - static const bool traps = false; - static const bool tinyness_before = false; - static const float_round_style round_style = round_indeterminate; - }; -} - - -/**************** #undef all private macros ****************/ - -#undef __GMPP_DECLARE_COMPOUND_OPERATOR -#undef __GMPN_DECLARE_COMPOUND_OPERATOR -#undef __GMP_DECLARE_COMPOUND_OPERATOR -#undef __GMP_DECLARE_COMPOUND_OPERATOR_UI -#undef __GMP_DECLARE_INCREMENT_OPERATOR -#undef __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS -#undef __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS - -#undef __GMPZQ_DEFINE_EXPR - -#undef __GMP_DEFINE_UNARY_FUNCTION_1 -#undef __GMP_DEFINE_UNARY_FUNCTION -#undef __GMP_DEFINE_UNARY_TYPE_FUNCTION - -#undef __GMPP_DEFINE_BINARY_FUNCTION -#undef __GMPNN_DEFINE_BINARY_FUNCTION -#undef __GMPNS_DEFINE_BINARY_FUNCTION -#undef __GMPNU_DEFINE_BINARY_FUNCTION -#undef __GMPND_DEFINE_BINARY_FUNCTION -#undef __GMPNLD_DEFINE_BINARY_FUNCTION -#undef __GMPN_DEFINE_BINARY_FUNCTION -#undef __GMP_DEFINE_BINARY_FUNCTION - -#undef __GMP_DEFINE_BINARY_FUNCTION_UI - -#undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION -#undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION -#undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION -#undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION -#undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION -#undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION -#undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION -#undef __GMP_DEFINE_BINARY_TYPE_FUNCTION - -#undef __GMPZ_DEFINE_COMPOUND_OPERATOR - -#undef __GMPP_DEFINE_COMPOUND_OPERATOR -#undef __GMPNN_DEFINE_COMPOUND_OPERATOR -#undef __GMPNS_DEFINE_COMPOUND_OPERATOR -#undef __GMPNU_DEFINE_COMPOUND_OPERATOR -#undef __GMPND_DEFINE_COMPOUND_OPERATOR -#undef __GMPNLD_DEFINE_COMPOUND_OPERATOR -#undef __GMPN_DEFINE_COMPOUND_OPERATOR -#undef __GMP_DEFINE_COMPOUND_OPERATOR - -#undef __GMPQ_DEFINE_COMPOUND_OPERATOR -#undef __GMPF_DEFINE_COMPOUND_OPERATOR - -#undef __GMP_DEFINE_COMPOUND_OPERATOR_UI -#undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI -#undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI -#undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI - -#undef __GMP_DEFINE_INCREMENT_OPERATOR -#undef __GMPZ_DEFINE_INCREMENT_OPERATOR -#undef __GMPQ_DEFINE_INCREMENT_OPERATOR -#undef __GMPF_DEFINE_INCREMENT_OPERATOR - -#undef __GMPXX_CONSTANT_TRUE -#undef __GMPXX_CONSTANT - -#endif /* __GMP_PLUSPLUS__ */ diff --git a/include/gvAbcCmd.h b/include/gvAbcCmd.h deleted file mode 120000 index 87c7f0f9..00000000 --- a/include/gvAbcCmd.h +++ /dev/null @@ -1 +0,0 @@ -../src/abc/gvAbcCmd.h \ No newline at end of file diff --git a/include/gvAbcMgr.h b/include/gvAbcMgr.h deleted file mode 120000 index b8c82217..00000000 --- a/include/gvAbcMgr.h +++ /dev/null @@ -1 +0,0 @@ -../src/abc/gvAbcMgr.h \ No newline at end of file diff --git a/include/gvAbcNtk.h b/include/gvAbcNtk.h deleted file mode 120000 index bf41baed..00000000 --- a/include/gvAbcNtk.h +++ /dev/null @@ -1 +0,0 @@ -../src/abc/gvAbcNtk.h \ No newline at end of file diff --git a/include/gvCmdComm.h b/include/gvCmdComm.h deleted file mode 120000 index 27bbe1c2..00000000 --- a/include/gvCmdComm.h +++ /dev/null @@ -1 +0,0 @@ -../src/cmd/gvCmdComm.h \ No newline at end of file diff --git a/include/gvCmdMgr.h b/include/gvCmdMgr.h deleted file mode 120000 index 1bc8799e..00000000 --- a/include/gvCmdMgr.h +++ /dev/null @@ -1 +0,0 @@ -../src/cmd/gvCmdMgr.h \ No newline at end of file diff --git a/include/gvIntType.h b/include/gvIntType.h deleted file mode 120000 index a6c983c3..00000000 --- a/include/gvIntType.h +++ /dev/null @@ -1 +0,0 @@ -../src/util/gvIntType.h \ No newline at end of file diff --git a/include/gvModCmd.h b/include/gvModCmd.h deleted file mode 120000 index 763cbb22..00000000 --- a/include/gvModCmd.h +++ /dev/null @@ -1 +0,0 @@ -../src/mod/gvModCmd.h \ No newline at end of file diff --git a/include/gvModMgr.h b/include/gvModMgr.h deleted file mode 120000 index f5d7be90..00000000 --- a/include/gvModMgr.h +++ /dev/null @@ -1 +0,0 @@ -../src/mod/gvModMgr.h \ No newline at end of file diff --git a/include/gvMsg.h b/include/gvMsg.h deleted file mode 120000 index 26b49245..00000000 --- a/include/gvMsg.h +++ /dev/null @@ -1 +0,0 @@ -../src/util/gvMsg.h \ No newline at end of file diff --git a/include/gvNtkCmd.h b/include/gvNtkCmd.h deleted file mode 120000 index 4bf9dfae..00000000 --- a/include/gvNtkCmd.h +++ /dev/null @@ -1 +0,0 @@ -../src/ntk/gvNtkCmd.h \ No newline at end of file diff --git a/include/gvSimCmd.h b/include/gvSimCmd.h deleted file mode 120000 index 09fef443..00000000 --- a/include/gvSimCmd.h +++ /dev/null @@ -1 +0,0 @@ -../src/sim/gvSimCmd.h \ No newline at end of file diff --git a/include/gvUsage.h b/include/gvUsage.h deleted file mode 120000 index 2da66c94..00000000 --- a/include/gvUsage.h +++ /dev/null @@ -1 +0,0 @@ -../src/util/gvUsage.h \ No newline at end of file diff --git a/include/gvVrfCmd.h b/include/gvVrfCmd.h deleted file mode 120000 index f9cdd810..00000000 --- a/include/gvVrfCmd.h +++ /dev/null @@ -1 +0,0 @@ -../src/vrf/gvVrfCmd.h \ No newline at end of file diff --git a/include/hashlib.h b/include/hashlib.h deleted file mode 120000 index 93fa5e2c..00000000 --- a/include/hashlib.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/hashlib.h \ No newline at end of file diff --git a/include/libyosys.so b/include/libyosys.so deleted file mode 120000 index ce621502..00000000 --- a/include/libyosys.so +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/libyosys.so \ No newline at end of file diff --git a/include/log.h b/include/log.h deleted file mode 120000 index f2ee7d04..00000000 --- a/include/log.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/log.h \ No newline at end of file diff --git a/include/macc.h b/include/macc.h deleted file mode 120000 index 82204ecb..00000000 --- a/include/macc.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/macc.h \ No newline at end of file diff --git a/include/mem.h b/include/mem.h deleted file mode 120000 index 7312d859..00000000 --- a/include/mem.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/mem.h \ No newline at end of file diff --git a/include/modtools.h b/include/modtools.h deleted file mode 120000 index 8efaa977..00000000 --- a/include/modtools.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/modtools.h \ No newline at end of file diff --git a/include/myHashMap.h b/include/myHashMap.h deleted file mode 120000 index d4bcb81c..00000000 --- a/include/myHashMap.h +++ /dev/null @@ -1 +0,0 @@ -../src/util/myHashMap.h \ No newline at end of file diff --git a/include/myUsage.h b/include/myUsage.h deleted file mode 120000 index 20689518..00000000 --- a/include/myUsage.h +++ /dev/null @@ -1 +0,0 @@ -../src/util/myUsage.h \ No newline at end of file diff --git a/include/preproc.h b/include/preproc.h deleted file mode 120000 index ec99bf3b..00000000 --- a/include/preproc.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/preproc.h \ No newline at end of file diff --git a/include/qcsat.h b/include/qcsat.h deleted file mode 120000 index 0e8b6580..00000000 --- a/include/qcsat.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/qcsat.h \ No newline at end of file diff --git a/include/quteRTL.h b/include/quteRTL.h deleted file mode 120000 index 4121cb5d..00000000 --- a/include/quteRTL.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/quteRTL/quteRTL.h \ No newline at end of file diff --git a/include/register.h b/include/register.h deleted file mode 120000 index d7354657..00000000 --- a/include/register.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/register.h \ No newline at end of file diff --git a/include/rnGen.h b/include/rnGen.h deleted file mode 120000 index 95506035..00000000 --- a/include/rnGen.h +++ /dev/null @@ -1 +0,0 @@ -../src/util/rnGen.h \ No newline at end of file diff --git a/include/rtlil.h b/include/rtlil.h deleted file mode 120000 index cd916c96..00000000 --- a/include/rtlil.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/rtlil.h \ No newline at end of file diff --git a/include/sat.h b/include/sat.h deleted file mode 120000 index 16531751..00000000 --- a/include/sat.h +++ /dev/null @@ -1 +0,0 @@ -../src/sat/sat.h \ No newline at end of file diff --git a/include/satgen.h b/include/satgen.h deleted file mode 120000 index 96fac5b9..00000000 --- a/include/satgen.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/satgen.h \ No newline at end of file diff --git a/include/sigtools.h b/include/sigtools.h deleted file mode 120000 index 0b314726..00000000 --- a/include/sigtools.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/sigtools.h \ No newline at end of file diff --git a/include/timinginfo.h b/include/timinginfo.h deleted file mode 120000 index b2199177..00000000 --- a/include/timinginfo.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/timinginfo.h \ No newline at end of file diff --git a/include/util.h b/include/util.h deleted file mode 120000 index 7f2305cb..00000000 --- a/include/util.h +++ /dev/null @@ -1 +0,0 @@ -../src/util/util.h \ No newline at end of file diff --git a/include/utils.h b/include/utils.h deleted file mode 120000 index 8923cbe3..00000000 --- a/include/utils.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/utils.h \ No newline at end of file diff --git a/include/yosys.h b/include/yosys.h deleted file mode 120000 index b6126261..00000000 --- a/include/yosys.h +++ /dev/null @@ -1 +0,0 @@ -../src/eng/yosys/yosys.h \ No newline at end of file diff --git a/input.pattern b/input.pattern new file mode 100644 index 00000000..6d12a9a5 --- /dev/null +++ b/input.pattern @@ -0,0 +1,5 @@ +01010101 +01110111 +11011011 +10110111 +01010001 diff --git a/lib/lib.d b/lib/lib.d deleted file mode 100644 index e69de29b..00000000 diff --git a/patches/vcd_parser.patch b/patches/vcd_parser.patch new file mode 100644 index 00000000..8c6072cf --- /dev/null +++ b/patches/vcd_parser.patch @@ -0,0 +1,38 @@ +diff --git a/Makefile b/Makefile +index 3286f6d..9068c51 100644 +--- a/Makefile ++++ b/Makefile +@@ -24,7 +24,7 @@ VCD_OBJ_FILES = $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/%.o,$(VCD_SRC)) $(YAC + + TEST_APP ?= $(BUILD_DIR)/vcd-parse + +-all : vcd-parser docs $(BUILD_DIR)/libverilog-vcd-parser.a ++all : vcd-parser $(BUILD_DIR)/libverilog-vcd-parser.a + + vcd-parser: $(TEST_APP) + +diff --git a/src/VCDParser.ypp b/src/VCDParser.ypp +index 6b3f0d4..0d8c321 100644 +--- a/src/VCDParser.ypp ++++ b/src/VCDParser.ypp +@@ -152,7 +152,7 @@ declaration_command : + if (new_signal->size == 1) { + assert((new_signal->lindex == -1) || (new_signal->rindex == -1)); + } else { +- assert((new_signal->lindex > 0) && (new_signal->lindex - new_signal->rindex + 1 == new_signal->size)); ++ // assert((new_signal->lindex > 0) && (new_signal->lindex - new_signal->rindex + 1 == new_signal->size)); + } + VCDScope * scope = driver.scopes.top(); + scope -> signals.push_back(new_signal); +diff --git a/src/VCDScanner.l b/src/VCDScanner.l +index 5bd1206..5a6c42d 100644 +--- a/src/VCDScanner.l ++++ b/src/VCDScanner.l +@@ -394,6 +394,7 @@ void VCDFileParser::scan_begin() { + error("Cannot open "+filepath+": "+strerror(errno)); + exit(EXIT_FAILURE); + } ++ yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); + } + + void VCDFileParser::scan_end() { diff --git a/patches/vcd_parser_patch.cmake b/patches/vcd_parser_patch.cmake new file mode 100644 index 00000000..8d64ecdb --- /dev/null +++ b/patches/vcd_parser_patch.cmake @@ -0,0 +1,27 @@ +# Path to the VCD parser patch +set(VCD_PARSER_PATCH_FILE vcd_parser.patch) +set(OUTPUT_REDIRECT "/dev/null") + +# Command for checking the patch is applied or not +set(VCD_PARSER_PATCH_CHECK git apply --check ${CMAKE_CURRENT_LIST_DIR}/${VCD_PARSER_PATCH_FILE}) +# Command for applying the patch +set(VCD_PARSER_PATCH git apply ${CMAKE_CURRENT_LIST_DIR}/${VCD_PARSER_PATCH_FILE}) + +# * Get the exit status of "git apply --check" +# * Output the log message to the /dev/null +execute_process( + COMMAND ${VCD_PARSER_PATCH_CHECK} + RESULT_VARIABLE STATUS + OUTPUT_VARIABLE OUTPUT + OUTPUT_FILE ${OUTPUT_REDIRECT} + ERROR_FILE ${OUTPUT_REDIRECT}) + +# Patch has not been applied +if(STATUS EQUAL "0") + # Apply the patch to the Yosys Makefile + message(STATUS "Applying the VCD parser patch") + execute_process(COMMAND ${VCD_PARSER_PATCH}) + # Patch has been applied +else() + message(STATUS "Skip the patch step\nPatch has been applied") +endif() diff --git a/patches/yosys_linux.patch b/patches/yosys_linux.patch new file mode 100644 index 00000000..63098956 --- /dev/null +++ b/patches/yosys_linux.patch @@ -0,0 +1,54 @@ +diff --git a/Makefile b/Makefile +index 0de05b622..4f682768c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + +-CONFIG := clang +-# CONFIG := gcc ++# CONFIG := clang ++CONFIG := gcc + # CONFIG := afl-gcc + # CONFIG := emcc + # CONFIG := wasi +@@ -9,8 +9,8 @@ CONFIG := clang + # CONFIG := msys2-64 + + # features (the more the better) +-ENABLE_TCL := 1 +-ENABLE_ABC := 1 ++ENABLE_ABC := 0 ++ENABLE_TCL:= 0 + ENABLE_GLOB := 1 + ENABLE_PLUGINS := 1 + ENABLE_READLINE := 1 +@@ -22,7 +22,7 @@ ENABLE_VERIFIC_LIBERTY := 0 + DISABLE_VERIFIC_EXTENSIONS := 0 + DISABLE_VERIFIC_VHDL := 0 + ENABLE_COVER := 1 +-ENABLE_LIBYOSYS := 0 ++ENABLE_LIBYOSYS := 1 + ENABLE_ZLIB := 1 + + # python wrappers +@@ -752,9 +752,9 @@ $(PROGRAM_PREFIX)yosys$(EXE): $(OBJS) + + libyosys.so: $(filter-out kernel/driver.o,$(OBJS)) + ifeq ($(OS), Darwin) +- $(P) $(LD) -o libyosys.so -shared -Wl,-install_name,$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS) $(LDLIBS_VERIFIC) ++ $(P) $(LD) -o libyosys.so -shared -Wl,-install_name,@rpath/libyosyss.so $(LDFLAGS) $^ $(LDLIBS) $(LDLIBS_VERIFIC) + else +- $(P) $(LD) -o libyosys.so -shared -Wl,-soname,$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS) $(LDLIBS_VERIFIC) ++ $(P) $(LD) -o libyosys.so -shared $(LDFLAGS) $^ $(LDLIBS) $(LDLIBS_VERIFIC) + endif + + %.o: %.cc +@@ -1048,7 +1048,7 @@ config-clean: clean + rm -f Makefile.conf + + config-clang: clean +- echo 'CONFIG := clang' > Makefile.conf ++ echo '# CONFIG := clang' > Makefile.conf + + config-gcc: clean + echo 'CONFIG := gcc' > Makefile.conf diff --git a/patches/yosys_mac.patch b/patches/yosys_mac.patch new file mode 100644 index 00000000..34e1cdbd --- /dev/null +++ b/patches/yosys_mac.patch @@ -0,0 +1,34 @@ +diff --git a/Makefile b/Makefile +index 0de05b622..3b061c5a2 100644 +--- a/Makefile ++++ b/Makefile +@@ -10,7 +10,7 @@ CONFIG := clang + + # features (the more the better) + ENABLE_TCL := 1 +-ENABLE_ABC := 1 ++ENABLE_ABC := 0 + ENABLE_GLOB := 1 + ENABLE_PLUGINS := 1 + ENABLE_READLINE := 1 +@@ -22,7 +22,7 @@ ENABLE_VERIFIC_LIBERTY := 0 + DISABLE_VERIFIC_EXTENSIONS := 0 + DISABLE_VERIFIC_VHDL := 0 + ENABLE_COVER := 1 +-ENABLE_LIBYOSYS := 0 ++ENABLE_LIBYOSYS := 1 + ENABLE_ZLIB := 1 + + # python wrappers +@@ -752,9 +752,9 @@ $(PROGRAM_PREFIX)yosys$(EXE): $(OBJS) + + libyosys.so: $(filter-out kernel/driver.o,$(OBJS)) + ifeq ($(OS), Darwin) +- $(P) $(LD) -o libyosys.so -shared -Wl,-install_name,$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS) $(LDLIBS_VERIFIC) ++ $(P) $(LD) -o libyosys.so -shared -Wl,-install_name,@rpath/libyosys.so $(LDFLAGS) $^ $(LDLIBS) $(LDLIBS_VERIFIC) + else +- $(P) $(LD) -o libyosys.so -shared -Wl,-soname,$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS) $(LDLIBS_VERIFIC) ++ $(P) $(LD) -o libyosys.so -shared $(LDFLAGS) $^ $(LDLIBS) $(LDLIBS_VERIFIC) + endif + + %.o: %.cc diff --git a/patches/yosys_patch.cmake b/patches/yosys_patch.cmake new file mode 100644 index 00000000..603883cd --- /dev/null +++ b/patches/yosys_patch.cmake @@ -0,0 +1,34 @@ +# Path to the yosys patch +if(APPLE) + message(STATUS "Using Mac Patch") + set(YOSYS_PATCH_FILE yosys_mac.patch) +else() + message(STATUS "Using Linux Patch") + set(YOSYS_PATCH_FILE yosys_linux.patch) +endif() + +set(OUTPUT_REDIRECT "/dev/null") + +# Command for checking the patch is applied or not +set(YOSYS_PATCH_CHECK git apply --check ${CMAKE_CURRENT_LIST_DIR}/${YOSYS_PATCH_FILE}) +# Command for applying the patch +set(YOSYS_PATCH git apply ${CMAKE_CURRENT_LIST_DIR}/${YOSYS_PATCH_FILE}) + +# * Get the exit status of "git apply --check" +# * Output the log message to the /dev/null +execute_process( + COMMAND ${YOSYS_PATCH_CHECK} + RESULT_VARIABLE STATUS + OUTPUT_VARIABLE OUTPUT + OUTPUT_FILE ${OUTPUT_REDIRECT} + ERROR_FILE ${OUTPUT_REDIRECT}) + +# Patch has not been applied +if(STATUS EQUAL "0") + # Apply the patch to the Yosys Makefile + message(STATUS "Applying the yosys patch") + execute_process(COMMAND ${YOSYS_PATCH}) + # Patch has been applied +else() + message(STATUS "Skip the patch step\nPatch has been applied") +endif() diff --git a/src/itp/FileV.cpp b/satsolvers/minisat/File.cpp similarity index 99% rename from src/itp/FileV.cpp rename to satsolvers/minisat/File.cpp index ea6a65ab..c59cf9e8 100644 --- a/src/itp/FileV.cpp +++ b/satsolvers/minisat/File.cpp @@ -1,4 +1,4 @@ -#include "FileV.h" +#include "minisat/File.h" void File::open(int file_descr, FileMode m, bool own) diff --git a/src/itp/FileV.h b/satsolvers/minisat/File.h similarity index 99% rename from src/itp/FileV.h rename to satsolvers/minisat/File.h index 2a4fb7e6..c36939f4 100644 --- a/src/itp/FileV.h +++ b/satsolvers/minisat/File.h @@ -2,7 +2,7 @@ #define File_h #ifndef Global_h -#include "GlobalV.h" +#include "minisat/Global.h" #endif #include diff --git a/src/itp/GlobalV.h b/satsolvers/minisat/Global.h similarity index 100% rename from src/itp/GlobalV.h rename to satsolvers/minisat/Global.h diff --git a/src/sat/Heap.h b/satsolvers/minisat/Heap.h similarity index 100% rename from src/sat/Heap.h rename to satsolvers/minisat/Heap.h diff --git a/src/itp/ProofV.cpp b/satsolvers/minisat/Proof.cpp similarity index 99% rename from src/itp/ProofV.cpp rename to satsolvers/minisat/Proof.cpp index e0610bce..7afd812c 100644 --- a/src/itp/ProofV.cpp +++ b/satsolvers/minisat/Proof.cpp @@ -17,8 +17,8 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#include "ProofV.h" -#include "SortV.h" +#include "minisat/Proof.h" +#include "minisat/Sort.h" #include #include #include diff --git a/src/itp/ProofV.h b/satsolvers/minisat/Proof.h similarity index 98% rename from src/itp/ProofV.h rename to satsolvers/minisat/Proof.h index 5f1d5e28..a92492c0 100644 --- a/src/itp/ProofV.h +++ b/satsolvers/minisat/Proof.h @@ -20,8 +20,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef Proof_h #define Proof_h -#include "SolverTypesV.h" -#include "FileV.h" +#include "minisat/SolverTypes.h" +#include "minisat/File.h" //================================================================================================= diff --git a/src/itp/SolverV.cpp b/satsolvers/minisat/Solver.cpp similarity index 99% rename from src/itp/SolverV.cpp rename to satsolvers/minisat/Solver.cpp index 7f5f33ca..1e978198 100644 --- a/src/itp/SolverV.cpp +++ b/satsolvers/minisat/Solver.cpp @@ -17,8 +17,8 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#include "SolverV.h" -#include "SortV.h" +#include "minisat/Solver.h" +#include "minisat/Sort.h" #include #include diff --git a/src/itp/SolverV.h b/satsolvers/minisat/Solver.h similarity index 99% rename from src/itp/SolverV.h rename to satsolvers/minisat/Solver.h index e93eb1cd..3fee7006 100644 --- a/src/itp/SolverV.h +++ b/satsolvers/minisat/Solver.h @@ -20,9 +20,9 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef Solver_h #define Solver_h -#include "ProofV.h" -#include "SolverTypesV.h" -#include "VarOrderV.h" +#include "minisat/Proof.h" +#include "minisat/SolverTypes.h" +#include "minisat/VarOrder.h" // Redfine if you want output to go somewhere else: #define reportf(format, args...) (printf(format, ##args), fflush(stdout)) diff --git a/src/itp/SolverTypesV.h b/satsolvers/minisat/SolverTypes.h similarity index 99% rename from src/itp/SolverTypesV.h rename to satsolvers/minisat/SolverTypes.h index 2233efaf..b9f22ab0 100644 --- a/src/itp/SolverTypesV.h +++ b/satsolvers/minisat/SolverTypes.h @@ -21,7 +21,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #define SolverTypes_h #ifndef Global_h -#include "GlobalV.h" +#include "minisat/Global.h" #endif //================================================================================================= diff --git a/src/sat/Sort.h b/satsolvers/minisat/Sort.h similarity index 100% rename from src/sat/Sort.h rename to satsolvers/minisat/Sort.h diff --git a/src/itp/VarOrderV.h b/satsolvers/minisat/VarOrder.h similarity index 98% rename from src/itp/VarOrderV.h rename to satsolvers/minisat/VarOrder.h index 0893d8a7..e3eb9080 100644 --- a/src/itp/VarOrderV.h +++ b/satsolvers/minisat/VarOrder.h @@ -20,8 +20,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef VarOrder_h #define VarOrder_h -#include "HeapV.h" -#include "SolverTypesV.h" +#include "minisat/Heap.h" +#include "minisat/SolverTypes.h" //================================================================================================= diff --git a/src/itp/gvBitVec.cpp b/satsolvers/minisat/gvBitVec.cpp similarity index 100% rename from src/itp/gvBitVec.cpp rename to satsolvers/minisat/gvBitVec.cpp diff --git a/src/itp/gvBitVec.h b/satsolvers/minisat/gvBitVec.h similarity index 100% rename from src/itp/gvBitVec.h rename to satsolvers/minisat/gvBitVec.h diff --git a/satsolvers/minisat/reader.cpp b/satsolvers/minisat/reader.cpp new file mode 100644 index 00000000..3f7ee479 --- /dev/null +++ b/satsolvers/minisat/reader.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** + FileName [ reader.cpp ] + PackageName [ sat ] + Synopsis [ Proof reader for Minisat1.14_p ] + Author [ Jiunru Yang ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] +****************************************************************************/ + +#include "reader.h" + +#include + +void Reader::open(const char* file_name) { + fd = ::open(file_name, O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + buf = new unsigned char[BUF_SIZE]; + pos = 0; + overall_pos = 0; + size = read(fd, buf, BUF_SIZE); +} + +void Reader::open(int filedesc) { + fd = filedesc; + buf = new unsigned char[BUF_SIZE]; + pos = 0; + overall_pos = 0; + size = read(fd, buf, BUF_SIZE); +} + +void Reader::seek(const unsigned int to) { + lseek(fd, to, SEEK_SET); + size = read(fd, buf, BUF_SIZE); + pos = 0; + overall_pos = to; +} + +unsigned int Reader::getChar() { + if (pos < size) { + overall_pos++; + return static_cast(buf[pos++]); + } + if (size < BUF_SIZE) return RDR_EOF; + pos = 1; + overall_pos++; + size = read(fd, buf, BUF_SIZE); + if (size == 0) return RDR_EOF; + return static_cast(buf[0]); +} + +unsigned long long Reader::get64() { + unsigned int byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7; + byte0 = getChar(); + if (byte0 == RDR_EOF) return RDR_EOF; + if (!(byte0 & 0x80)) + return byte0; + else { + switch ((byte0 & 0x60) >> 5) { + case 0: + byte1 = getChar(); + return ((byte0 & 0x1F) << 8) | byte1; + case 1: + byte1 = getChar(); + byte2 = getChar(); + return ((byte0 & 0x1F) << 16) | (byte1 << 8) | byte2; + case 2: + byte1 = getChar(); + byte2 = getChar(); + byte3 = getChar(); + return ((byte0 & 0x1F) << 24) | (byte1 << 16) | (byte2 << 8) | byte3; + default: + byte0 = getChar(); + byte1 = getChar(); + byte2 = getChar(); + byte3 = getChar(); + byte4 = getChar(); + byte5 = getChar(); + byte6 = getChar(); + byte7 = getChar(); + return ((unsigned long long)((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3) << 32) | (unsigned long long)((byte4 << 24) | (byte5 << 16) | (byte6 << 8) | byte7); + } + } +} + +void Reader::close() { + if (fd == -1) return; + ::close(fd); + fd = -1; + delete[] buf; +} + +Reader::~Reader() { + close(); +} + +bool Reader::eof() { + if (pos < size) return false; + if (size < BUF_SIZE) return true; + pos = 0; + size = read(fd, buf, BUF_SIZE); + return size == 0; +} diff --git a/satsolvers/minisat/reader.h b/satsolvers/minisat/reader.h new file mode 100644 index 00000000..9c59df82 --- /dev/null +++ b/satsolvers/minisat/reader.h @@ -0,0 +1,42 @@ +/**************************************************************************** + FileName [ reader.h ] + PackageName [ sat ] + Synopsis [ Proof reader for Minisat1.14_p ] + Author [ Jiunru Yang ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] +****************************************************************************/ + +#ifndef _READER_H_ +#define _READER_H_ + +#include +#include +#include +#include + +#define BUF_SIZE 1024 +#define RDR_EOF ((unsigned)~0) + +class Reader { + int fd; + unsigned char* buf; + unsigned int size; + unsigned int pos; + unsigned int getChar(); + unsigned int overall_pos; + +public: + Reader() : fd(-1){}; + void open(const char* file_name); + void open(int file_descriptor); + void close(); + void seek(const unsigned int to); + unsigned long long get64(); + ~Reader(); + bool null() { return fd == -1; } + unsigned int Current_Pos() { return overall_pos; } + // unsigned int Current_Pos() { return lseek(fd, 0, SEEK_CUR) - (size - pos); } + bool eof(); +}; + +#endif // _READER_H_ diff --git a/scripts/LINT b/scripts/LINT new file mode 100755 index 00000000..761f9dd4 --- /dev/null +++ b/scripts/LINT @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +if [ ! -x "$(command -v parallel)" ]; then + echo "Error: GNU parallel is not installed!!" + exit 1 +fi + +format_one() { + clang-format -i "$1" +} +export -f format_one + +lint_one() { + clang-tidy -p build "$1" --quiet 2>&1 | grep -v -E "warnings? generated" +} +export -f lint_one + +FILES=$(find ./src -regex '.*\.[ch]pp' -type f) +CPPS=$(find ./src -regex '.*\.cpp' -type f) + +# Format all files first to avoid linting errors +echo "Formatting files..." +parallel -j"$(nproc)" format_one ::: "$FILES" +echo "Generating compile commands..." +cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=1 > /dev/null +echo "Linting files..." +parallel -j"$(nproc)" lint_one ::: "$CPPS" +echo "Done" diff --git a/scripts/RUN_TEST b/scripts/RUN_TEST new file mode 100755 index 00000000..ea4d4d28 --- /dev/null +++ b/scripts/RUN_TEST @@ -0,0 +1,277 @@ +#!/bin/bash + +if [ ! -x "$(command -v parallel)" ]; then + echo "Error: GNU parallel is not installed!!" + exit 1 +fi + +# test if colordiff is installed; if not use diff +if [ -x "$(command -v colordiff)" ]; then + DIFF="colordiff" +else + DIFF="diff" +fi + +# return text in green, bold +pass-style() { + if [ $# -ne 1 ]; then + echo "Usage: pass-style " + else + echo -e "\033[1;32m$1\033[0m" + fi +} +export -f pass-style + +# return text in red, bold +fail-style() { + if [ $# -ne 1 ]; then + echo "Usage: fail-style " + else + echo -e "\033[1;31m$1\033[0m" + fi +} +export -f fail-style + +# return text in cyan, bold +unknown-style() { + if [ $# -ne 1 ]; then + echo "Usage: unknown-style " + else + echo -e "\033[1;36m$1\033[0m" + fi +} +export -f unknown-style + +# print usage message +usage() { + echo "Usage: $0 [-d|--diff] [-u|--update] [-g|--gv ]" + echo " -d, --diff diff the output of gv with the expected output" + echo " -u, --update update the expected output with the output of gv" + echo " -g, --gv path to gv executable" + echo " -v, --verbose also report tests that pass" + echo " -s, --silent do not report difference between execution result and reference" + echo " -f, --full execute the dofiles within the \"full\" folder (takes longer time)" +} +export -f usage + +# parse arguments + +cd "$(git rev-parse --show-toplevel)" || exit 1 +GV=./gv +ACTION="" +SILENT=0 +VERBOSE=0 +FULL=0 +POSITIONAL=() +FULL_DIR=(full) + +while [[ $# -gt 0 ]]; do + case $1 in + -d | --diff) + if [ -n "$ACTION" ]; then + echo "Error: cannot specify multiple actions!!" + usage + exit 1 + fi + ACTION="diff" + shift # argument + ;; + -u | --update) + if [ -n "$ACTION" ]; then + echo "Error: cannot specify multiple actions!!" + usage + exit 1 + fi + ACTION="update" + shift # argument + ;; + -g | --gv) + GV=$2 + shift # argument + shift # variable + ;; + -v | --verbose) + VERBOSE=1 + shift # argument + ;; + -s | --silent) + SILENT=1 + shift # argument + ;; + -h | --help) + usage + exit 0 + ;; + -f | --full) + FULL=1 + shift + ;; + -* | --*) + echo "Error: unknown option $1!!" + usage + exit 1 + ;; + *) + POSITIONAL+=("$1") + shift # argument + ;; + esac +done + +# the default action is to diff +if [ ! -n "$ACTION" ]; then + ACTION="diff" +fi + +# if no positional argument is given, run all tests from the tests directory +if [ ${#POSITIONAL[@]} -eq 0 ]; then + POSITIONAL=(tests) +fi + +SYSTEM="linux" +# detect the OS type +if [[ "$OSTYPE" == "darwin"* ]]; then + SYSTEM="macos" +fi +echo "Your system: $SYSTEM" + +TESTS=() +# for each positional argument, if it is a file, run the test on that file +# if it is a directory, run the test on all files in that directory +for arg in "${POSITIONAL[@]}"; do + if [ -f "$arg" ]; then + TESTS+=("$arg") + elif [ -d "$arg" ]; then + if [[ $FULL -eq 0 ]]; then + EXCLUDE_COMMAND="-type d -name $FULL_DIR -prune -o" + fi + + for file in $(find $arg ${EXCLUDE_COMMAND} -regex ".*\.dofile" -type f); do + if [ -f "$file" ]; then + TESTS+=("$file") + fi + done + else + echo "Error: $arg is not a file or directory!!" + usage + exit 1 + fi +done + +# run dofile with gv and diff the output with the expected output +ref-path() { + local TEST=$1 + local DIR=$(dirname "${TEST}") + local BASE=$(basename "${TEST%.*}") + local REF_DIR="${DIR}/../ref_${SYSTEM}" + local REF_PATH="${REF_DIR}/${BASE}.log" + echo $(perl -MFile::Spec -e 'print File::Spec->abs2rel($ARGV[0], $ARGV[1])' "${REF_PATH}" "$(pwd)") +} +export -f ref-path + +# diff the output of gv with the reference output +dofile-result-same-with-ref() { + local TEST=$1 + local VERBOSE=$2 + local SILENT=$3 + local GV=$4 + local DIFF=$5 + local REF=$(ref-path $TEST) + + # DIFF_OUTPUT=$(OMP_WAIT_POLICY=passive $GV -file $TEST 2>&1 | $DIFF - $REF 2>&1) + DIFF_OUTPUT=$($GV -file $TEST 2>&1 | $DIFF - $REF 2>&1) + + # if [ $? -eq 0 ]; then + if [ -z "$DIFF_OUTPUT" ]; then + if [[ $VERBOSE -eq 1 ]]; then + echo " $(pass-style '✓') $TEST" + return 0 + fi + else + if [ ! -f $REF ]; then + echo " $(unknown-style '?') $REF" + else + echo " $(fail-style '✗') $TEST" + fi + if [[ $SILENT -eq 0 ]]; then + # indent diff output + DIFF_OUTPUT=$(echo "$DIFF_OUTPUT" | sed 's/^/ /') + echo "$DIFF_OUTPUT" + fi + return 1 + fi +} +export -f dofile-result-same-with-ref + +update-dofile-ref() { + local TEST=$1 + local VERBOSE=$2 + local SILENT=$3 + local GV=$4 + local REF=$(ref-path $TEST) + + # if the reference file does not exist, create it + if [[ ! -f $REF ]]; then + mkdir -p $(dirname $REF) + touch $REF + fi + + # DIFF_OUTPUT=$(OMP_WAIT_POLICY=passive $GV -file $TEST 2>&1 | diff $REF -) + DIFF_OUTPUT=$($GV -file $TEST 2>&1 | diff $REF -) + + # update reference file if the output of gv is different from the reference + # if [[ $? -eq 0 ]]; then + if [ -z "$DIFF_OUTPUT" ]; then + if [[ $VERBOSE -eq 1 ]]; then + echo " - $TEST" + return 0 + fi + else + printf "%s\n" "$DIFF_OUTPUT" | patch -f $REF + if [[ $? -eq 1 ]]; then + echo " $(fail-style !) $TEST" + return 0 + else + echo " $(pass-style ↑) $TEST" + return 1 + fi + fi +} +export -f update-dofile-ref + +# diff dofiles and report result +if [[ "$ACTION" == 'diff' ]]; then + echo "> Testing dofiles..." + echo "> Current Path: $(pwd)" + + # run in parallel and count failures + # parallel -j"$(nproc)" "dofile-result-same-with-ref {} $VERBOSE $SILENT $GV $DIFF" ::: "${TESTS[@]}" + # parallel -j"1" "dofile-result-same-with-ref {} $VERBOSE $SILENT $GV $DIFF" ::: "${TESTS[@]}" + FAIL_COUNT=0 + for test in "${TESTS[@]}"; do + dofile-result-same-with-ref $test $VERBOSE $SILENT $GV $DIFF + FAIL_COUNT=$((FAIL_COUNT+$?)) + done + + # FAIL_COUNT=$? + TESTS_COUNT=${#TESTS[@]} + if [ $FAIL_COUNT -eq 0 ]; then + echo "$(pass-style "Passed all $TESTS_COUNT tests.")" + else + echo "$(fail-style "$FAIL_COUNT out of $TESTS_COUNT tests failed.")" + fi +elif [[ "$ACTION" == 'update' ]]; then + echo "> Updating reference files..." + + # run in parallel and count updates + # parallel -j"1" "update-dofile-ref {} $VERBOSE $SILENT $GV" ::: "${TESTS[@]}" + for test in "${TESTS[@]}"; do + update-dofile-ref $test $VERBOSE $SILENT $GV + UPDATE_COUNT=$((UPDATE_COUNT+$?)) + done + + # UPDATE_COUNT=$? + + TESTS_COUNT=${#TESTS[@]} + echo "$(pass-style "Updated $UPDATE_COUNT out of $TESTS_COUNT reference files.")" +fi diff --git a/simulators/cxxrtl/Makefile b/simulators/cxxrtl/Makefile new file mode 100644 index 00000000..96794e60 --- /dev/null +++ b/simulators/cxxrtl/Makefile @@ -0,0 +1,33 @@ +# Executable name +EXE_FILE := cxxrtl_tb +# Directories and sources +SRC_DIR := src +SRCS := $(SRC_DIR)/testbench.cpp +# Include directories +INCLUDE := ../../build/engines/src/engine-yosys/ +# Compiler and flags +CXX := g++ +CXXFLAGS := -g -std=c++14 +CXXFLAGS += -I$(INCLUDE) -I$(SRC_DIR) +CXXFLAGS += -DPATTERN_FILE=$(GV_PATH)/$(PATTERN_FILE) +CXXFLAGS += -DCYCLE=$(CYCLE) +CXXFLAGS += -DVCD_FILE=$(VCD_FILE) +CXXFLAGS += -DMODE=$(MODE) +# Headers +HEADERS := $(SRC_DIR)/simulator.hpp \ + $(SRC_DIR)/interface.hpp \ + $(SRC_DIR)/utility.hpp + +# Targets +all: $(EXE_FILE) + +$(EXE_FILE): $(SRCS) $(HEADERS) + $(CXX) $(CXXFLAGS) $(SRCS) -o $(EXE_FILE) + +run: $(EXE_FILE) + ./$(EXE_FILE) + +clean: + rm -f $(EXE_FILE) + +.PHONY: all run clean diff --git a/simulators/cxxrtl/src/interface.hpp b/simulators/cxxrtl/src/interface.hpp new file mode 100644 index 00000000..2bdac87d --- /dev/null +++ b/simulators/cxxrtl/src/interface.hpp @@ -0,0 +1,106 @@ +#ifndef interface_hpp +#define interface_hpp + +#include + +#include +#include +#include +#include + +#include ".sim.cpp" + +// Define Macro +#define CONCATENATE(in0, in1, in2) in0##in1##in2 + +#define SET_VALUE_FUNC(bitwidth, type) \ + void CONCATENATE(set, bitwidth, BitsVal)(const unsigned& val) { \ + item->set(val); \ + }; + +#define SET_WIDTH_CONDITION(signal_width) \ + if (width == signal_width) \ + CONCATENATE(set, signal_width, BitsVal) \ + (value); + +#define SET_CXX_SIGNAL(signal_type, signal_name) \ + signal_type.emplace_back(SignalInfo(const_cast(&items->at(signal_name)), signal_name)); + +#define SET_CXX_TOP(top_module) \ + cxxrtl_design::p_##top_module top; + +struct SignalInfo { +public: + SignalInfo(const cxxrtl::debug_item* it, std::string n) : item(it), name(n) { + } + void setBoolVal(const bool& val) { + item->set<1, bool>(val); + } + // Set signal value functions + SET_VALUE_FUNC(4,unsigned); + // End (Code is generated by GV) + + unsigned getUpper() { return std::pow(2, item->width); } + unsigned getValue() { return *(item->curr); } + unsigned getWidth() { return item->width; } + std::string getName() { return name; } + + void setValue(size_t value) { + size_t width = item->width; + if (width == 1) setBoolVal(value); + // Set N bits value condition + SET_WIDTH_CONDITION(4); + // End (Code is generated by GV) + } + +private: + const cxxrtl::debug_item* item; + std::string name; +}; + +class Interface { +public: + Interface(cxxrtl::debug_items* items) { + top.debug_info(*items); + + // CLK Init + SET_CXX_SIGNAL(clk, "clk"); + // End (Code is generated by GV) + + // RST Init + SET_CXX_SIGNAL(rst, "rst"); + // End (Code is generated by GV) + + // PI Init List + SET_CXX_SIGNAL(pi, "b"); + SET_CXX_SIGNAL(pi, "a"); + // End (Code is generated by GV) + + // PO Init List + SET_CXX_SIGNAL(po, "sum"); + // End (Code is generated by GV) + + // REG Init List + // End (Code is generated by GV) + + // MEM Init List + // End (Code is generated by GV) + } + + + void step() { top.step(); } + + // Set top design object + SET_CXX_TOP(adder); + // End (Code is generated by GV) + + std::vector clk; + std::vector rst; + std::vector po; + std::vector pi; + std::vector reg; + std::vector mem; +}; + +#endif /* interface_hpp */ + diff --git a/simulators/cxxrtl/src/simulator.hpp b/simulators/cxxrtl/src/simulator.hpp new file mode 100644 index 00000000..09d31003 --- /dev/null +++ b/simulators/cxxrtl/src/simulator.hpp @@ -0,0 +1,219 @@ +// +// simulator.hpp +// crv_01 +// dhgir.abien@gmail.com +// + +#ifndef simulator_h +#define simulator_h + +#include +#include +#include + +#include "backends/cxxrtl/cxxrtl.h" +#include "backends/cxxrtl/cxxrtl_vcd.h" +#include "interface.hpp" +#include "utility.hpp" + +#define GREEN_TEXT "\033[32m" // ANSI escape code for green color +#define RESET_COLOR "\033[0m" // ANSI escape code to reset color + +#define STR(s) STR2(s) +#define STR2(s) #s + +class Simulator { + typedef std::vector> Pattern; // Input pattern + +public: + Simulator() : cycle(0), sampleCount(0), isVCD(true) { init(); } + + bool init() { + itf = new Interface(&all_debug_items); + + vcd.timescale(1, "ps"); + vcd.add_without_memories(all_debug_items); + vcd.add(all_debug_items); + + patternFile = STR(PATTERN_FILE); + vcdFile = STR(VCD_FILE); + return true; + } + + bool enableVCD() { + waves.open(vcdFile); + if (!waves.is_open()) { + return false; + std::cout << " Open the CXXRTL file failed !!\n"; + } + return true; + } + + bool finish() { + waves.close(); + return true; + } + + void resetNeg() { + vcd.sample(sampleCount++); + itf->step(); + + // __ __ + // clk: __| |__| |__ + // __ + // rst: ___________| | + + // RESET + setCLK(false); + setRST(false); + eval(); + + setCLK(true); + setRST(false); + eval(); + + setCLK(false); + setRST(false); + eval(); + + setCLK(true); + setRST(false); + eval(); + + setCLK(false); + setRST(true); + eval(); + } + + //! setter functions + void setCLK(const bool &value) { itf->clk[0].setValue(value); } + void setRST(const bool &value) { itf->rst[0].setValue(value); } + void setCycle(const size_t &c) { cycle = c; } + void setPiPattern(std::vector &piPattern) { + for (unsigned i = 0; i < piPattern.size(); i++) { + itf->pi[i].setValue(piPattern[i]); + }; + } + + //! getter functions + unsigned getPiNum() { return itf->pi.size(); } + unsigned getPoNum() { return itf->po.size(); } + unsigned getPiUpper(const unsigned &idx) { return itf->pi[idx].getUpper(); } + + void eval() { + itf->step(); + if (isVCD) { + vcd.sample(sampleCount++); + outVCD(); + } + } + + void evalOneClock(void) { + // __ + // clk : | |___ + setCLK(1); + eval(); + setCLK(0); + eval(); + } + + void outVCD() { + waves << vcd.buffer; + vcd.buffer.clear(); + } + + void printValue() { + uint32_t sum = itf->po[0].getValue(); + std::cout << "==========================================\n"; + std::cout << "= cycle " << cycle + 1 << "\n"; + std::cout << "==========================================\n"; + std::cout << "sum= " << sum << "\n"; + std::cout << "clk = " << itf->clk[0].getValue() << "\n"; + std::cout << "rst= " << itf->rst[0].getValue() << "\n"; + std::cout << itf->pi[0].getName() << "= " << itf->pi[0].getValue() << "\n"; + std::cout << itf->pi[1].getName() << "= " << itf->pi[1].getValue() << "\n"; + std::cout << std::endl; + } + + std::vector genPiRandomPattern() { + std::vector pattern; + pattern.clear(); + for (unsigned i = 0; i < getPiNum(); i++) { + pattern.emplace(pattern.end(), + rGen.getRandNum(0, getPiUpper(i))); + } + return pattern; + } + + std::string replaceXValue(const std::string &pattern) { + std::string newPattern = pattern; + size_t xPos = newPattern.find('X'); + while (xPos != std::string::npos) { + newPattern[xPos] = '0'; + xPos = newPattern.find('X'); + } + return newPattern; + } + + bool loadRandomPattern() { + for (int i = 0; i < cycle; ++i) { + std::vector onePattern = genPiRandomPattern(); + patternVec.emplace_back(onePattern); + } + return true; + } + + bool loadInputPattern() { + std::ifstream infile(patternFile); + std::string buffer = "", inputStr = ""; + unsigned width = 0, inputVal = 0; + + if (!infile) { + std::cout << "ERROR: Cannot open file " << patternFile << " !!\n"; + return false; + } + + while (infile >> buffer) { + std::vector onePattern; + for (int i = 0, n = getPiNum(); i < n; ++i) { + width = itf->pi[i].getWidth(); + inputStr = replaceXValue(buffer.substr(0, width)); + if (inputStr.size() < width) { + std::cout << "ERROR: Illegal input pattern file !!\n"; + return false; + } + inputVal = stoi(inputStr, nullptr, 2); + onePattern.emplace_back(inputVal); + buffer = buffer.substr(width); + } + if (buffer.size() != 0) { + std::cout << "ERROR: Illegal input pattern file !!\n"; + return false; + } + patternVec.push_back(onePattern); + } + infile.close(); + return true; + } + + void startSim(const bool &verbose) { + if (itf->rst.size() > 0) resetNeg(); + for (int i = 0, n = patternVec.size(); i < n; ++i) { + setPiPattern(patternVec[i]); + evalOneClock(); + } + } + + bool isVCD; + size_t cycle; + size_t sampleCount; + cxxrtl::debug_items all_debug_items; + cxxrtl::vcd_writer vcd; + std::string patternFile; + std::string vcdFile; + std::ofstream waves; + Pattern patternVec; + Interface *itf; +}; + +#endif /* simulator_h */ diff --git a/simulators/cxxrtl/src/testbench.cpp b/simulators/cxxrtl/src/testbench.cpp new file mode 100644 index 00000000..409474a2 --- /dev/null +++ b/simulators/cxxrtl/src/testbench.cpp @@ -0,0 +1,19 @@ +#include "simulator.hpp" +#include "utility.hpp" + +int main() { + Simulator* simulator = new Simulator(); + simulator->enableVCD(); + simulator->setCycle(CYCLE); + + switch (MODE) { + case PURE_RANDOM: + simulator->loadRandomPattern(); + break; + case STIMULUS: + simulator->loadInputPattern(); + break; + } + simulator->startSim(true); + simulator->finish(); +} diff --git a/simulators/cxxrtl/src/utility.hpp b/simulators/cxxrtl/src/utility.hpp new file mode 100644 index 00000000..70e4d688 --- /dev/null +++ b/simulators/cxxrtl/src/utility.hpp @@ -0,0 +1,53 @@ +#ifndef utility_h +#define utility_h + +#define STR(s) STR2(s) +#define STR2(s) #s + +#define PURE_RANDOM 0 +#define STIMULUS 1 + +#include + +class RandomGen { +public: + RandomGen(bool isDebug) { + unsigned seed; + + if (isDebug) { + seed = 84133409; + } else { + seed = rd(); + } + + // std::cout << "Random Seed = " << seed << std::endl; + ranEngine = std::default_random_engine(seed); + } + + unsigned getRandNum(unsigned lower, unsigned upper) { + std::uniform_int_distribution _uni64(lower, upper); + return _uni64(ranEngine); + } + + std::random_device rd; + std::default_random_engine ranEngine; +}; +RandomGen rGen(false); + +class Timer { +public: + Timer() {} + + void start(void) { + start_timestamp = clock(); + } + + double getTime(void) { + return (clock() - start_timestamp) / (double)(CLOCKS_PER_SEC); + } + + clock_t start_timestamp; +}; +Timer timer; + +#endif /* utility_h */ diff --git a/simulators/cxxrtl/template/interface.hpp b/simulators/cxxrtl/template/interface.hpp new file mode 100644 index 00000000..17846627 --- /dev/null +++ b/simulators/cxxrtl/template/interface.hpp @@ -0,0 +1,97 @@ +#ifndef interface_hpp +#define interface_hpp + +#include + +#include +#include +#include +#include + +#include ".sim.cpp" + +// Define Macro +#define CONCATENATE(in0, in1, in2) in0##in1##in2 + +#define SET_VALUE_FUNC(bitwidth, type) \ + void CONCATENATE(set, bitwidth, BitsVal)(const unsigned& val) { \ + item->set(val); \ + }; + +#define SET_WIDTH_CONDITION(signal_width) \ + if (width == signal_width) \ + CONCATENATE(set, signal_width, BitsVal) \ + (value); + +#define SET_CXX_SIGNAL(signal_type, signal_name) \ + signal_type.emplace_back(SignalInfo(const_cast(&items->at(signal_name)), signal_name)); + +#define SET_CXX_TOP(top_module) \ + cxxrtl_design::p_##top_module top; + +struct SignalInfo { +public: + SignalInfo(const cxxrtl::debug_item* it, std::string n) : item(it), name(n) { + } + void setBoolVal(const bool& val) { + item->set<1, bool>(val); + } + // Set signal value functions + // End (Code is generated by GV) + + unsigned getUpper() { return std::pow(2, item->width); } + unsigned getValue() { return *(item->curr); } + unsigned getWidth() { return item->width; } + std::string getName() { return name; } + + void setValue(size_t value) { + size_t width = item->width; + if (width == 1) setBoolVal(value); + // Set N bits value condition + // End (Code is generated by GV) + } + +private: + const cxxrtl::debug_item* item; + std::string name; +}; + +class Interface { +public: + Interface(cxxrtl::debug_items* items) { + top.debug_info(*items); + + // CLK Init + // End (Code is generated by GV) + + // RST Init + // End (Code is generated by GV) + + // PI Init List + // End (Code is generated by GV) + + // PO Init List + // End (Code is generated by GV) + + // REG Init List + // End (Code is generated by GV) + + // MEM Init List + // End (Code is generated by GV) + } + + + void step() { top.step(); } + + // Set top design object + // End (Code is generated by GV) + + std::vector clk; + std::vector rst; + std::vector po; + std::vector pi; + std::vector reg; + std::vector mem; +}; + +#endif /* interface_hpp */ diff --git a/simulators/verilator/Makefile b/simulators/verilator/Makefile new file mode 100644 index 00000000..722dab89 --- /dev/null +++ b/simulators/verilator/Makefile @@ -0,0 +1,54 @@ +VERILATOR := verilator +VRLT_PATH=$(GV_PATH)/simulators/verilator/ + +DESIGN_PATH := $(GV_PATH)/$(DESIGN) +DESIGN_NAME :=$(notdir $(basename $(DESIGN_PATH))) +SRC_DIR := $(VRLT_PATH) + +VFLAGS += --cc --public --trace --assert -O3 + +VFLAGS += -CFLAGS -O3 +VFLAGS += -CFLAGS -DCYCLE=$(CYCLE) +VFLAGS += -CFLAGS -DVCD_FILE=$(GV_PATH)/$(VCD_FILE) +VFLAGS += -CFLAGS -DMODE=$(MODE) +VFLAGS += -CFLAGS -DPATTERN_FILE=$(GV_PATH)/$(PATTERN_FILE) +VFLAGS += -CFLAGS -I$(VRLT_PATH)include + + +VFLAGS += -y build +VFLAGS += --Mdir build/obj_dir +VFLAGS += -Wno-WIDTHEXPAND -Wno-WIDTHTRUNC -Wno-LATCH +VFLAGS += --exe $(SRC_DIR)testbench.cpp + +VERILATE=$(VERILATOR) $(VFLAGS) +SUBMAKE := $(MAKE) --no-print-directory --directory=build/obj_dir -f +VRLT_MK := Vdesign_under_test.mk + +all: symbolic_link_design run_vrlt_sim + +run_vrlt_sim: compile_vrlt_mk + +compile_vrlt_mk: gen_vrlt_mk + @echo Make the Verilator Makefile ... +# @echo $(SUBMAKE) $(VRLT_MK) + $(SUBMAKE) $(VRLT_MK) + +gen_vrlt_mk: + @echo Generating the Verilator Makefile ... +# @echo $(VERILATE) $(VRLT_PATH)design_under_test.v + $(VERILATE) $(VRLT_PATH)design_under_test.v + +symbolic_link_design: + @echo Symbolic linking the design ... +# @echo ln -fs $(DESIGN_PATH) $(VRLT_PATH)design_under_test.v + ln -fs $(DESIGN_PATH) $(VRLT_PATH)design_under_test.v + +run: + ./build/obj_dir/Vdesign_under_test + @echo $(DESIGN_NAME) + +create_build_dir: clean + mkdir build + +clean: + rm -rf build/ diff --git a/simulators/verilator/control_signal.hpp b/simulators/verilator/control_signal.hpp new file mode 100644 index 00000000..918987a7 --- /dev/null +++ b/simulators/verilator/control_signal.hpp @@ -0,0 +1,15 @@ +#ifndef control_signal_hpp +#define control_signal_hpp + +#include "crpg.hpp" + +class ControlSignal { +public: + ControlSignal() { + // State Inst + } + + std::vector fsm_list; +}; + +#endif /* control_signal_hpp */ diff --git a/simulators/verilator/include/crpg.hpp b/simulators/verilator/include/crpg.hpp new file mode 100644 index 00000000..c0c07d19 --- /dev/null +++ b/simulators/verilator/include/crpg.hpp @@ -0,0 +1,236 @@ +// +// crpg.hpp +// Constrained Random Pattern Generation +// + +#ifndef crpg_h +#define crpg_h + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Vdesign_under_test.h" +#include "Vdesign_under_test___024root.h" +#include "svdpi.h" +#include "verilated_vcd_c.h" +// #include "Vdesign_under_test__Dpi.h" + +// #include "NumCpp.hpp" + +// Time Factor +#define UCB_C 0.0001 +#define EXPANSION_FACTOR 10 +#define VALID_SAMPLE_FACTOR 10 +#define ATTENUATION_COEFFICIENT 0.9 +#define STATE_TRANSFER_MAX_TRY 10 +#define SAMPLE_TIMEOUT 0.5 +#define CART_DEPTH 3 +#define CART_TIMEOUT 5 + +// Space Factor +#define MAXV 100 +#define HASH_TABLE_SIZE 10000 + +// Other +#define INV_MATRIX_DELTA 0.00001 +#define VALUE_NORMALIZATION_FACTOR 10000 +#define FINAL_STATE_INDEX 4294967295 + +// Global Count +unsigned transitionNum = 0; +unsigned hashNum = 0; +unsigned hashCollisionNum = 0; +unsigned hashHitNum = 0; +unsigned mctsNodeNum = 0; +unsigned mctsBranchNum = 0; + +vluint64_t main_time = 1000; +double sc_time_stamp() { + return main_time; +} + +class Signal { +public: + Signal( + std::string newName, + void* newValue, + unsigned newWidth) : name(newName), + value(newValue), + width(newWidth) {} + + virtual const char getType() = 0; + + std::string name; + void* value; + unsigned width; +}; + +class SignalI : public Signal { +public: + SignalI( + std::string newName, + void* newValue, + unsigned newWidth) : Signal(newName, newValue, newWidth) {} + + virtual const char getType() override { return 'I'; } +}; + +class SignalC : public Signal { +public: + SignalC( + std::string newName, + void* newValue, + unsigned newWidth) : Signal(newName, newValue, newWidth) {} + + virtual const char getType() override { return 'C'; } +}; + +class SignalS : public Signal { +public: + SignalS( + std::string newName, + void* newValue, + unsigned newWidth) : Signal(newName, newValue, newWidth) {} + + virtual const char getType() override { return 'S'; } +}; + +class SignalQ : public Signal { +public: + SignalQ( + std::string newName, + void* newValue, + unsigned newWidth) : Signal(newName, newValue, newWidth) {} + + virtual const char getType() override { return 'Q'; } +}; + +class Property { +public: + Property( + std::string newFileName, + unsigned newIndex, + unsigned newLineNumber, + std::string newStatement) : fileName(newFileName), + index(newIndex), + lineNumber(newLineNumber), + statement(newStatement) {} + + std::string fileName; + unsigned index; + unsigned lineNumber; + std::string statement; +}; + +class FsmState { +public: + FsmState( + unsigned newIndex, + unsigned newEncoding, + std::vector newTransitionTable) : index(newIndex), + encoding(newEncoding), + transitionTable(newTransitionTable) {} + + unsigned index; + unsigned encoding; + std::vector transitionTable; +}; + +class FSM { +public: + FSM( + unsigned newIndex, + std::string newVarName, + unsigned newVarIndex) : index(newIndex), + varName(newVarName), + varIndex(newVarIndex) {} + + unsigned index; + std::string varName; + unsigned varIndex; + std::vector states; +}; + +class DPI { +public: + static bool assertion_flag; + static unsigned assertion_index; + static bool constraint_flag; + static unsigned constraint_index; + static unsigned constraint_count; + static unsigned constraint_count_n; + static bool stable_flag; + static unsigned stable_index; + static unsigned assertion_active_index; + + static void rst_asset_flag(void) { + assertion_flag = false; + } + + static bool get_asset_flag(void) { + return assertion_flag; + } + + static void rst_constraint_flag(void) { + constraint_flag = false; + } + + static bool get_constraint_flag(void) { + return constraint_flag; + } + + static void rst_stable_flag(void) { + stable_flag = false; + } + + static bool get_stable_flag(void) { + return stable_flag; + } +}; + +bool DPI::assertion_flag = false; +unsigned DPI::assertion_index = 0; +bool DPI::constraint_flag = false; +unsigned DPI::constraint_index = 0; +unsigned DPI::constraint_count = 0; +unsigned DPI::constraint_count_n = 0; +bool DPI::stable_flag = false; +unsigned DPI::stable_index = 0; +unsigned DPI::assertion_active_index = -1; + +void set_assert_flag(int index) { + if (index == DPI::assertion_active_index) { + DPI::assertion_flag = true; + DPI::assertion_index = index; + } else { + return; + // std::cout << "###INFO set_asset_flag: " << index << std::endl; + } +} + +void set_constraint_flag(int index) { + DPI::constraint_flag = true; + DPI::constraint_index = index; + DPI::constraint_count_n++; + // std::cout << "###INFO set_constraint_flag: " << index << std::endl; +} + +void set_stable_flag(int index) { + DPI::stable_flag = true; + DPI::stable_index = index; + // std::cout << "###INFO set_stable_flag: " << index << std::endl; +} + +#endif /* crpg_h */ diff --git a/simulators/verilator/include/template/assertion.hpp b/simulators/verilator/include/template/assertion.hpp new file mode 100644 index 00000000..2fee9548 --- /dev/null +++ b/simulators/verilator/include/template/assertion.hpp @@ -0,0 +1,23 @@ +// +// assertion.hpp +// Constrained-Random-Pattern-Generation +// dhgir.abien@gmail.com +// + +#ifndef assertion_hpp +#define assertion_hpp + +#include "crpg.hpp" + +class Assertion{ +public: + Assertion(){ + + // Assert Init + + } + + std::vector assertion; +}; + +#endif /* assertion_hpp */ diff --git a/simulators/verilator/include/template/control_signal.hpp b/simulators/verilator/include/template/control_signal.hpp new file mode 100644 index 00000000..2fae4e0b --- /dev/null +++ b/simulators/verilator/include/template/control_signal.hpp @@ -0,0 +1,23 @@ +// +// control_signal.hpp +// Constrained-Random-Pattern-Generation +// dhgir.abien@gmail.com +// + +#ifndef control_signal_hpp +#define control_signal_hpp + +#include "crpg.hpp" + +class ControlSignal{ +public: + ControlSignal(){ + + // State Inst + + } + + std::vector fsm_list; +}; + +#endif /* control_signal_hpp */ diff --git a/simulators/verilator/include/template/interface.hpp b/simulators/verilator/include/template/interface.hpp new file mode 100644 index 00000000..5e7007d7 --- /dev/null +++ b/simulators/verilator/include/template/interface.hpp @@ -0,0 +1,37 @@ +// +// interface.hpp +// Constrained-Random-Pattern-Generation +// dhgir.abien@gmail.com +// + +#ifndef interface_hpp +#define interface_hpp + +#include "crpg.hpp" + +class Interface { +public: + Interface(Vdesign_under_test___024root *rootp) { + + // CLK Init + + // RST Init + + // PI Init List + + // PO Init List + + // REG Init List + + // MEM Init List + } + + std::vector clk; + std::vector rst; + std::vector pi; + std::vector po; + std::vector reg; + std::vector mem; +}; + +#endif /* interface_hpp */ diff --git a/simulators/verilator/interface.hpp b/simulators/verilator/interface.hpp new file mode 100644 index 00000000..9539dcb8 --- /dev/null +++ b/simulators/verilator/interface.hpp @@ -0,0 +1,36 @@ +#ifndef interface_hpp +#define interface_hpp + +#include "crpg.hpp" + +class Interface { +public: + Interface(Vdesign_under_test___024root *rootp) { + // CLK Init + clk.push_back(new SignalC("clk", &rootp->clk, 1)); + + // RST Init + rst.push_back(new SignalC("rst", &rootp->rst, 1)); + + // PI Init List + pi.push_back(new SignalC("b", &rootp->b, 4)); + pi.push_back(new SignalC("a", &rootp->a, 4)); + + // PO Init List + po.push_back(new SignalC("sum", &rootp->sum, 5)); + + // REG Init List + + // MEM Init List + } + + std::vector clk; + std::vector rst; + std::vector pi; + std::vector po; + std::vector reg; + std::vector mem; +}; + +#endif /* interface_hpp */ + diff --git a/simulators/verilator/simulator.hpp b/simulators/verilator/simulator.hpp new file mode 100644 index 00000000..ba004155 --- /dev/null +++ b/simulators/verilator/simulator.hpp @@ -0,0 +1,400 @@ +#ifndef simulator_h +#define simulator_h + +#include +#include +#include + +#include "crpg.hpp" +#include "fstream" +#include "interface.hpp" +#include "utility.hpp" + +#define GREEN_TEXT "\033[32m" // ANSI escape code for green color +#define RESET_COLOR "\033[0m" // ANSI escape code to reset color + +class Simulator { + typedef std::vector> Pattern; // Input pattern +public: + Simulator() + : contextp(std::make_unique()), + duv(std::make_unique()), count(0), cycle(0) { + Verilated::traceEverOn(true); + contextp->debug(0); + contextp->randReset(2); + contextp->traceEverOn(true); + + signalMap = new Interface(duv->rootp); + patternFile = STR(PATTERN_FILE); + vcdFileName = STR(VCD_FILE); + } + ~Simulator() { + duv->final(); + closeVcdFile(); + } + + std::unique_ptr contextp; + std::unique_ptr duv; + VerilatedVcdC *tfp; + Interface *signalMap; + std::string patternFile; + std::string vcdFileName; + Pattern patternVec; + long long unsigned count; + unsigned cycle; + + void resetDUV() { + setCLK(0); + setRST(1); + duv->eval(); + setCLK(1); + setRST(1); + duv->eval(); + setCLK(0); + setRST(1); + duv->eval(); + setCLK(1); + setRST(1); + duv->eval(); + setCLK(0); + setRST(0); + duv->eval(); + } + + void resetNegDUV() { + setCLK(0); + setRST(0); + eval(); + + setCLK(1); + // setRST(0); + eval(); + + setCLK(0); + // setRST(0); + eval(); + + setCLK(1); + // setRST(0); + eval(); + + setCLK(0); + setRST(1); + eval(); + } + + unsigned getPiNum(void) { return signalMap->pi.size(); } + unsigned getPoNum(void) { return signalMap->po.size(); } + unsigned getRegNum(void) { return signalMap->reg.size(); } + unsigned getRstNum(void) { return signalMap->rst.size(); } + + unsigned getPiWidth(int index) { return signalMap->pi[index]->width; } + unsigned getPoWidth(int index) { return signalMap->po[index]->width; } + + Signal *getPiSignal(unsigned index) { return signalMap->pi[index]; } + Signal *getPoSignal(unsigned index) { return signalMap->po[index]; } + Signal *getRegSignal(unsigned index) { return signalMap->reg[index]; } + + unsigned getPiWidth(unsigned index) { return signalMap->pi[index]->width; } + unsigned getPoWidth(unsigned index) { return signalMap->po[index]->width; } + unsigned getRegWidth(unsigned index) { return signalMap->reg[index]->width; } + + unsigned getPiUpper(unsigned index) { + return (unsigned)pow(2, getPiWidth(index)) - 1; + } + unsigned getPoUpper(unsigned index) { + return (unsigned)pow(2, getPoWidth(index)) - 1; + } + unsigned getRegUpper(unsigned index) { + return (unsigned)pow(2, getRegWidth(index)) - 1; + } + + unsigned getPI(unsigned index) { + if (signalMap->pi[index]->getType() == 'C') + return *(CData *)(signalMap->pi[index]->value); + else if (signalMap->pi[index]->getType() == 'I') + return *(IData *)(signalMap->pi[index]->value); + else if (signalMap->pi[index]->getType() == 'Q') + return *(QData *)(signalMap->pi[index]->value); + return *(SData *)(signalMap->pi[index]->value); + } + unsigned getPO(unsigned index) { + if (signalMap->po[index]->getType() == 'C') + return *(CData *)(signalMap->po[index]->value); + else if (signalMap->po[index]->getType() == 'I') + return *(IData *)(signalMap->po[index]->value); + else if (signalMap->po[index]->getType() == 'Q') + return *(QData *)(signalMap->po[index]->value); + return *(SData *)(signalMap->po[index]->value); + } + unsigned getREG(unsigned index) { + if (signalMap->reg[index]->getType() == 'C') + return *(CData *)(signalMap->reg[index]->value); + else if (signalMap->reg[index]->getType() == 'I') + return *(IData *)(signalMap->reg[index]->value); + else if (signalMap->reg[index]->getType() == 'Q') + return *(QData *)(signalMap->reg[index]->value); + return *(SData *)(signalMap->reg[index]->value); + } + void getRegPattern(std::vector ®Pattern) { + for (unsigned i = 0; i < signalMap->reg.size(); i++) { + if (signalMap->reg[i]->getType() == 'C') + regPattern.push_back(*(CData *)(signalMap->reg[i]->value)); + else if (signalMap->reg[i]->getType() == 'I') + regPattern.push_back(*(IData *)(signalMap->reg[i]->value)); + else if (signalMap->reg[i]->getType() == 'Q') + regPattern.push_back(*(QData *)(signalMap->reg[i]->value)); + else + regPattern.push_back(*(SData *)(signalMap->reg[i]->value)); + } + }; + void getRegPattern(std::vector ®Pattern) { + for (unsigned i = 0; i < signalMap->reg.size(); i++) { + if (signalMap->reg[i]->getType() == 'C') + regPattern.push_back(*(CData *)(signalMap->reg[i]->value)); + else if (signalMap->reg[i]->getType() == 'I') + regPattern.push_back(*(IData *)(signalMap->reg[i]->value)); + else if (signalMap->reg[i]->getType() == 'Q') + regPattern.push_back(*(QData *)(signalMap->reg[i]->value)); + else + regPattern.push_back(*(SData *)(signalMap->reg[i]->value)); + } + }; + void getPiPattern(std::vector &piPattern) { + for (unsigned i = 0; i < signalMap->pi.size(); i++) { + if (signalMap->pi[i]->getType() == 'C') + piPattern.push_back(*(CData *)(signalMap->pi[i]->value)); + else if (signalMap->pi[i]->getType() == 'I') + piPattern.push_back(*(IData *)(signalMap->pi[i]->value)); + else if (signalMap->pi[i]->getType() == 'Q') + piPattern.push_back(*(QData *)(signalMap->pi[i]->value)); + else + piPattern.push_back(*(SData *)(signalMap->pi[i]->value)); + } + }; + void setCycle(unsigned newValue) { + cycle = newValue; + } + void setVcdFileName(const std::string &newValue) { + vcdFileName = newValue; + } + void setCLK(unsigned newValue) { + *(CData *)(signalMap->clk[0]->value) = newValue; + }; + void setRST(unsigned newValue) { + *(CData *)(signalMap->rst[0]->value) = newValue; + }; + void setPI(unsigned index, unsigned newValue) { + if (signalMap->pi[index]->getType() == 'C') + *(CData *)(signalMap->pi[index]->value) = newValue; + else if (signalMap->pi[index]->getType() == 'I') + *(IData *)(signalMap->pi[index]->value) = newValue; + else if (signalMap->pi[index]->getType() == 'Q') + *(QData *)(signalMap->pi[index]->value) = newValue; + else + *(SData *)(signalMap->pi[index]->value) = newValue; + }; + void setPO(unsigned index, unsigned newValue) { + if (signalMap->po[index]->getType() == 'C') + *(CData *)(signalMap->po[index]->value) = newValue; + else if (signalMap->po[index]->getType() == 'I') + *(IData *)(signalMap->po[index]->value) = newValue; + else if (signalMap->po[index]->getType() == 'Q') + *(QData *)(signalMap->po[index]->value) = newValue; + else + *(SData *)(signalMap->po[index]->value) = newValue; + }; + void setREG(unsigned index, unsigned newValue) { + if (signalMap->reg[index]->getType() == 'C') + *(CData *)(signalMap->reg[index]->value) = newValue; + else if (signalMap->reg[index]->getType() == 'I') + *(IData *)(signalMap->reg[index]->value) = newValue; + else if (signalMap->reg[index]->getType() == 'Q') + *(QData *)(signalMap->reg[index]->value) = newValue; + else + *(SData *)(signalMap->reg[index]->value) = newValue; + }; + + void setRegPattern(std::vector ®Pattern) { + for (unsigned i = 0; i < regPattern.size(); i++) { + if (signalMap->reg[i]->getType() == 'C') + *(CData *)(signalMap->reg[i]->value) = regPattern[i]; + else if (signalMap->reg[i]->getType() == 'I') + *(IData *)(signalMap->reg[i]->value) = regPattern[i]; + else if (signalMap->reg[i]->getType() == 'Q') + *(QData *)(signalMap->reg[i]->value) = regPattern[i]; + else + *(SData *)(signalMap->reg[i]->value) = regPattern[i]; + } + }; + + void setPiPattern(std::vector &piPattern) { + for (unsigned i = 0; i < piPattern.size(); i++) { + if (signalMap->pi[i]->getType() == 'C') + *(CData *)(signalMap->pi[i]->value) = piPattern[i]; + else if (signalMap->pi[i]->getType() == 'I') + *(IData *)(signalMap->pi[i]->value) = piPattern[i]; + else if (signalMap->pi[i]->getType() == 'Q') + *(QData *)(signalMap->pi[i]->value) = piPattern[i]; + else + *(SData *)(signalMap->pi[i]->value) = piPattern[i]; + // std::cout << " PI NAME: " << signalMap->pi[i]->name << " Value: " << piPattern[i] << "\n"; + }; + } + + void openVcdFile() { + tfp = new VerilatedVcdC(); + duv->trace(tfp, 99); + tfp->open(vcdFileName.c_str()); + } + + void closeVcdFile() { + tfp->close(); + } + + void dumpVcd(int timestamp) { + contextp->timeInc(1); + tfp->dump(contextp->time()); + tfp->flush(); + } + + void printInfo(unsigned cycle = 0) { + if (cycle != 0) + std::cout << GREEN_TEXT << " ########### Cycle " << cycle << " ###########\n" + << RESET_COLOR; + for (int i = 0; i < getPiNum(); ++i) + printPI(i); + for (int i = 0; i < getPoNum(); ++i) + printPO(i); + for (int i = 0; i < getRegNum(); ++i) + printREG(i); + } + + void printPI(unsigned i) { + unsigned value; + if (signalMap->pi[i]->getType() == 'C') + value = *(CData *)(signalMap->pi[i]->value); + else if (signalMap->pi[i]->getType() == 'I') + value = *(IData *)(signalMap->pi[i]->value); + else if (signalMap->pi[i]->getType() == 'Q') + value = *(QData *)(signalMap->pi[i]->value); + else + value = *(SData *)(signalMap->pi[i]->value); + + std::cout << " PI: " << signalMap->pi[i]->name << " " << signalMap->pi[i]->width << " " + << value << std::endl; + } + void printPO(unsigned i) { + unsigned value; + if (signalMap->po[i]->getType() == 'C') + value = *(CData *)(signalMap->po[i]->value); + else if (signalMap->po[i]->getType() == 'I') + value = *(IData *)(signalMap->po[i]->value); + else if (signalMap->po[i]->getType() == 'Q') + value = *(QData *)(signalMap->po[i]->value); + else + value = *(SData *)(signalMap->po[i]->value); + std::cout << " PO: " << signalMap->po[i]->name << " " << signalMap->po[i]->width << " " + << value << std::endl; + } + void printREG(unsigned i) { + unsigned value; + if (signalMap->reg[i]->getType() == 'C') + value = *(CData *)(signalMap->reg[i]->value); + else if (signalMap->reg[i]->getType() == 'I') + value = *(IData *)(signalMap->reg[i]->value); + else if (signalMap->reg[i]->getType() == 'Q') + value = *(QData *)(signalMap->reg[i]->value); + else + value = *(SData *)(signalMap->reg[i]->value); + std::cout << " REG: " << signalMap->reg[i]->name << " " << signalMap->reg[i]->width + << " " << value << std::endl; + } + + std::vector genPiRandomPattern() { + std::vector pattern; + pattern.clear(); + for (unsigned i = 0; i < getPiNum(); i++) { + pattern.emplace(pattern.end(), + rGen.getRandNum(0, getPiUpper(i))); + } + return pattern; + } + + void eval(void) { + duv->eval(); + tfp->flush(); + tfp->dump(uint64_t(count)); + tfp->flush(); + count++; + } + + void evalOneClock(void) { + setCLK(1); + eval(); + setCLK(0); + eval(); + // count += 2; + } + std::string replaceXValue(const std::string &pattern) { + std::string newPattern = pattern; + size_t xPos = newPattern.find('X'); + while (xPos != std::string::npos) { + newPattern[xPos] = '0'; + xPos = newPattern.find('X'); + } + return newPattern; + } + + bool loadInputPattern() { + std::ifstream infile(patternFile); + std::string buffer = "", inputStr = ""; + unsigned width = 0, inputVal = 0; + + if (!infile) { + std::cout << "ERROR: Cannot open file " << patternFile << " !!\n"; + return false; + } + while (infile >> buffer) { + std::vector onePattern; + for (int i = 0, n = getPiNum(); i < n; ++i) { + width = getPiWidth(i); + inputStr = replaceXValue(buffer.substr(0, width)); + if (inputStr.size() < width) { + std::cout << "ERROR: Illegal input pattern file !!\n"; + return false; + } + inputVal = stoi(inputStr, nullptr, 2); + onePattern.push_back(inputVal); + buffer = buffer.substr(width); + } + if (buffer.size() != 0) { + std::cout << "ERROR: Illegal input pattern file !!\n"; + return false; + } + patternVec.push_back(onePattern); + } + return true; + } + + bool loadRandomPattern() { + for (int i = 0; i < cycle; ++i) { + std::vector onePattern = genPiRandomPattern(); + patternVec.push_back(onePattern); + } + return true; + } + + void startSim(const bool &verbose) { + int simCycle = patternVec.size(); + if (getRstNum() > 0) + resetNegDUV(); + for (int i = 0; i < simCycle; ++i) { + setPiPattern(patternVec[i]); + evalOneClock(); + // if (verbose) printInfo(i + 1); + } + } +}; + +#endif /* simulator_h */ diff --git a/simulators/verilator/template/assertion.hpp b/simulators/verilator/template/assertion.hpp new file mode 100644 index 00000000..0c578f70 --- /dev/null +++ b/simulators/verilator/template/assertion.hpp @@ -0,0 +1,15 @@ +#ifndef assertion_hpp +#define assertion_hpp + +#include "crpg.hpp" + +class Assertion { +public: + Assertion() { + // Assert Init + } + + std::vector assertion; +}; + +#endif /* assertion_hpp */ diff --git a/simulators/verilator/template/control_signal.hpp b/simulators/verilator/template/control_signal.hpp new file mode 100644 index 00000000..ec2eb8a2 --- /dev/null +++ b/simulators/verilator/template/control_signal.hpp @@ -0,0 +1,17 @@ +#ifndef control_signal_hpp +#define control_signal_hpp + +#include "crpg.hpp" + +class ControlSignal{ +public: + ControlSignal(){ + + // State Inst + + } + + std::vector fsm_list; +}; + +#endif /* control_signal_hpp */ diff --git a/simulators/verilator/template/interface.hpp b/simulators/verilator/template/interface.hpp new file mode 100644 index 00000000..0bcf1cf7 --- /dev/null +++ b/simulators/verilator/template/interface.hpp @@ -0,0 +1,30 @@ +#ifndef interface_hpp +#define interface_hpp + +#include "crpg.hpp" + +class Interface { +public: + Interface(Vdesign_under_test___024root *rootp) { + // CLK Init + + // RST Init + + // PI Init List + + // PO Init List + + // REG Init List + + // MEM Init List + } + + std::vector clk; + std::vector rst; + std::vector pi; + std::vector po; + std::vector reg; + std::vector mem; +}; + +#endif /* interface_hpp */ diff --git a/simulators/verilator/testbench.cpp b/simulators/verilator/testbench.cpp new file mode 100644 index 00000000..41c9bc95 --- /dev/null +++ b/simulators/verilator/testbench.cpp @@ -0,0 +1,35 @@ +// +// main.cpp +// Constrained Random Pattern Generation +// dhgir.abien@gmail.com +// + +#include + +#include "fstream" +#include "simulator.hpp" +#include "string" +#include "utility.hpp" + +// #define CYCLE 10 + +using namespace std; + +int main(int argc, char **argv, char **env) { + // TODO: Assertion Handler + timer.start(); + Simulator *simulator = new Simulator(); + simulator->setCycle(CYCLE); + simulator->openVcdFile(); + simulator->contextp->commandArgs(argc, argv); + + // double random_time = timer.getTime(); + if (MODE == PURE_RANDOM) + simulator->loadRandomPattern(); + else if (MODE == STIMULUS) + if (!simulator->loadInputPattern()) return 1; + simulator->startSim(true); + simulator->closeVcdFile(); + + return 0; +} \ No newline at end of file diff --git a/simulators/verilator/utility.hpp b/simulators/verilator/utility.hpp new file mode 100644 index 00000000..b96df974 --- /dev/null +++ b/simulators/verilator/utility.hpp @@ -0,0 +1,53 @@ +#ifndef utility_h +#define utility_h + +#include "crpg.hpp" + +#define STR(s) STR2(s) +#define STR2(s) #s + +#define PURE_RANDOM 0 +#define STIMULUS 1 + +class RandomGen { +public: + RandomGen(bool isDebug) { + unsigned seed; + + if (isDebug) { + seed = 84133409; + } else { + seed = rd(); + } + + // std::cout << "Random Seed = " << seed << std::endl; + ranEngine = std::default_random_engine(seed); + } + + unsigned getRandNum(unsigned lower, unsigned upper) { + std::uniform_int_distribution _uni64(lower, upper); + return _uni64(ranEngine); + } + + std::random_device rd; + std::default_random_engine ranEngine; +}; +RandomGen rGen(false); + +class Timer { +public: + Timer() {} + + void start(void) { + start_timestamp = clock(); + } + + double getTime(void) { + return (clock() - start_timestamp) / (double)(CLOCKS_PER_SEC); + } + + clock_t start_timestamp; +}; +Timer timer; + +#endif /* utility_h */ diff --git a/src/Makefile.in b/src/Makefile.in deleted file mode 100644 index 14b6b07e..00000000 --- a/src/Makefile.in +++ /dev/null @@ -1,75 +0,0 @@ -CSRCS = $(wildcard *.cpp) -CHDRS = $(wildcard *.h) -COBJS = $(addsuffix .o, $(basename $(CSRCS))) -CDEPS = $(addsuffix .d, $(basename $(CSRCS))) - - -INCDIR = ../../include -DEPDIR = -I. -I$(INCDIR) -LIBDIR = ../../lib -LIBDEP = $(LIBDIR)/lib.d -EXTLINK = $(PKGNAME).d - -CC = g++ -YOSYSCONF = yosys-config --exec --cxx --cxxflags -AR = ar cr - - -ENGFLGS = -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -YOSYSFLGS = -D_YOSYS_ -DYOSYS_ENABLE_PLUGINS -DYOSYS_ENABLE_GLOB -DYOSYS_ENABLE_ZLIB -I/usr/include/tcl8.6 -DYOSYS_ENABLE_TCL -DYOSYS_ENABLE_ABC -DYOSYS_ENABLE_COVER -ABCFLGS = -DABC_USE_STDINT_H - -CFLAGS = $(ENGFLGS) $(PKGFLAG) -O3 -DNDEBUG -Wall -Wno-parentheses -Wno-unused-function -CFLAGS = $(ENGFLGS) $(PKGFLAG) -g -Wall -Wno-parentheses -Wno-unused-function - -# DISABLE ALL WARNINGS -CFLAGS += -w -std=c++14 -SHELL = bash -OS = $(shell uname -s) - -ifeq ($(OS), Darwin) - OSMACRO += -D__APPLE__ -else - OSMACRO += -D__linux__ -endif - -.PHONY: depend extheader - -%.o: %.cpp - @echo "> compiling: $<" - @$(CC) $(CFLAGS) $(YOSYSFLGS) $(ABCFLGS) $(OSMACRO) -I$(INCDIR) -c -o $@ $< - -top: $(EXTLINK) target - @echo -n - -clean: - @rm -f $(COBJS) - @rm -f $(CDEPS) - -## Make dependencies -depend: .depend.mak -.depend.mak: $(CSRCS) $(CHDRS) - @echo Making dependencies ... - @$(CC) -MM $(DEPDIR) $(YOSYSFLGS) $(ABCFLGS) $(CSRCS) > $@ - -## Linking external headers -extheader: .extheader.mak -.extheader.mak: $(EXTHDRS) - @echo Linking external header files... - @rm -f $@ - @echo -n "$(EXTLINK): " > $@ - @for hdr in $(EXTHDRS); \ - do \ - echo -n "$(INCDIR)/$$hdr " >> $@; \ - rm -f $(INCDIR)/$$hdr; \ - done - @echo >> $@ - @for hdr in $(EXTHDRS); \ - do \ - echo "$(INCDIR)/$$hdr: $$hdr" >> $@; \ - echo " @rm -f $(INCDIR)/$$hdr" >> $@; \ - echo " @ln -fs ../src/$(PKGNAME)/$$hdr $(INCDIR)/$$hdr" >> $@; \ - done - -include .depend.mak -include .extheader.mak diff --git a/src/Makefile.lib b/src/Makefile.lib deleted file mode 100644 index d44da046..00000000 --- a/src/Makefile.lib +++ /dev/null @@ -1,9 +0,0 @@ -LIBNAME = lib$(PKGNAME).a -TARGET = $(LIBDIR)/$(LIBNAME) - -target: $(TARGET) - -$(TARGET): $(COBJS) - @echo "Building $(LIBNAME)..." - @$(AR) $@ $(COBJS) - @touch $(LIBDEP) diff --git a/src/abc/.depend.mak b/src/abc/.depend.mak deleted file mode 100644 index 3db860d4..00000000 --- a/src/abc/.depend.mak +++ /dev/null @@ -1,78 +0,0 @@ -gvAbcCmd.o: gvAbcCmd.cpp gvAbcCmd.h ../../include/gvCmdMgr.h gvAbcMgr.h \ - ../../include/base/abc/abc.h ../../include/misc/vec/vec.h \ - ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/main/abcapis.h \ - ../../include/base/cmd/cmd.h ../../include/base/io/ioAbc.h \ - ../../include/misc/util/utilNam.h ../../include/base/main/mainInt.h \ - ../../include/base/main/main.h ../../include/misc/tim/tim.h \ - ../../include/map/if/if.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/util/utilTruth.h ../../include/opt/dau/dau.h \ - ../../include/misc/vec/vecHash.h ../../include/aig/aig/aig.h \ - ../../include/proof/ssw/ssw.h ../../include/proof/fra/fra.h \ - ../../include/opt/dar/dar.h ../../include/sat/bsat/satSolver.h \ - ../../include/sat/bsat/satVec.h ../../include/sat/bsat/satClause.h \ - ../../include/misc/util/utilDouble.h ../../include/aig/ioa/ioa.h \ - gvAbcNtk.h ../../include/gvModMgr.h ../../include/gvCmdMgr.h \ - ../../include/gvMsg.h ../../include/util.h ../../include/rnGen.h \ - ../../include/myUsage.h -gvAbcMgr.o: gvAbcMgr.cpp gvAbcMgr.h ../../include/base/abc/abc.h \ - ../../include/misc/vec/vec.h ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/main/abcapis.h \ - ../../include/base/cmd/cmd.h ../../include/base/io/ioAbc.h \ - ../../include/misc/util/utilNam.h ../../include/base/main/mainInt.h \ - ../../include/base/main/main.h ../../include/misc/tim/tim.h \ - ../../include/map/if/if.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/util/utilTruth.h ../../include/opt/dau/dau.h \ - ../../include/misc/vec/vecHash.h ../../include/aig/aig/aig.h \ - ../../include/proof/ssw/ssw.h ../../include/proof/fra/fra.h \ - ../../include/opt/dar/dar.h ../../include/sat/bsat/satSolver.h \ - ../../include/sat/bsat/satVec.h ../../include/sat/bsat/satClause.h \ - ../../include/misc/util/utilDouble.h ../../include/aig/ioa/ioa.h \ - gvAbcNtk.h ../../include/bdd/cudd/cudd.h ../../include/bdd/mtr/mtr.h \ - ../../include/bdd/epd/epd.h ../../include/sat/cnf/cnf.h \ - ../../include/opt/dar/darInt.h ../../include/opt/dar/dar.h -gvAbcNtk.o: gvAbcNtk.cpp gvAbcNtk.h ../../include/base/abc/abc.h \ - ../../include/misc/vec/vec.h ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/main/abcapis.h \ - ../../include/base/cmd/cmd.h ../../include/base/io/ioAbc.h \ - ../../include/misc/util/utilNam.h ../../include/base/main/mainInt.h \ - ../../include/base/main/main.h ../../include/misc/tim/tim.h \ - ../../include/map/if/if.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/util/utilTruth.h ../../include/opt/dau/dau.h \ - ../../include/misc/vec/vecHash.h ../../include/aig/aig/aig.h \ - ../../include/proof/ssw/ssw.h ../../include/proof/fra/fra.h \ - ../../include/opt/dar/dar.h ../../include/sat/bsat/satSolver.h \ - ../../include/sat/bsat/satVec.h ../../include/sat/bsat/satClause.h \ - ../../include/misc/util/utilDouble.h ../../include/aig/ioa/ioa.h \ - ../../include/sat/cnf/cnf.h ../../include/opt/dar/darInt.h \ - ../../include/opt/dar/dar.h gvAbcMgr.h diff --git a/src/abc/.extheader.mak b/src/abc/.extheader.mak deleted file mode 100644 index dce52d3e..00000000 --- a/src/abc/.extheader.mak +++ /dev/null @@ -1,10 +0,0 @@ -abc.d: ../../include/gvAbcCmd.h ../../include/gvAbcMgr.h ../../include/gvAbcNtk.h -../../include/gvAbcCmd.h: gvAbcCmd.h - @rm -f ../../include/gvAbcCmd.h - @ln -fs ../src/abc/gvAbcCmd.h ../../include/gvAbcCmd.h -../../include/gvAbcMgr.h: gvAbcMgr.h - @rm -f ../../include/gvAbcMgr.h - @ln -fs ../src/abc/gvAbcMgr.h ../../include/gvAbcMgr.h -../../include/gvAbcNtk.h: gvAbcNtk.h - @rm -f ../../include/gvAbcNtk.h - @ln -fs ../src/abc/gvAbcNtk.h ../../include/gvAbcNtk.h diff --git a/src/abc/Makefile b/src/abc/Makefile deleted file mode 100644 index 2b09cdfe..00000000 --- a/src/abc/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -PKGFLAG = $(DEBUG_FLAG) -EXTHDRS = gvAbcCmd.h gvAbcMgr.h gvAbcNtk.h - -include ../Makefile.in -include ../Makefile.lib \ No newline at end of file diff --git a/src/abc/abcCmd.cpp b/src/abc/abcCmd.cpp new file mode 100644 index 00000000..c35f53c2 --- /dev/null +++ b/src/abc/abcCmd.cpp @@ -0,0 +1,51 @@ +#ifndef GV_ABC_CMD_C +#define GV_ABC_CMD_C + +#include "abcCmd.h" + +#include + +#include +#include + +#include "abcMgr.h" + +bool initAbcCmd() { + if (abcMgr) delete abcMgr; + abcMgr = new gv::engine::AbcMgr; + return (gvCmdMgr->regCmd("ABCCMD", 6, new GVABCOriginalCmd)); +} + +//---------------------------------------------------------------------- +// ABCCMD +//---------------------------------------------------------------------- +GVCmdExecStatus +GVABCOriginalCmd::exec(const string& option) { + vector options; + GVCmdExec::lexOptions(option, options); + size_t n = options.size(); + string command = ""; + for (size_t i = 0; i < n; ++i) { + command += options[i]; + if (i < n - 1) { + command += " "; + } + } + // calling abc's command + char cmd[1024], abcCmd[128]; + strcpy(abcCmd, command.c_str()); + sprintf(cmd, "%s", abcCmd); + abcMgr->execCmd(cmd); + return GV_CMD_EXEC_DONE; +} + +void GVABCOriginalCmd::usage(const bool& verbose) const { + cout << "Usage: ABCCMD " << endl; +} + +void GVABCOriginalCmd::help() const { + cout << setw(20) << left << "ABCCMD: " + << "Directly call ABC's command." << endl; +} + +#endif diff --git a/src/abc/abcCmd.h b/src/abc/abcCmd.h new file mode 100644 index 00000000..3bf6fa77 --- /dev/null +++ b/src/abc/abcCmd.h @@ -0,0 +1,5 @@ +#pragma once + +#include "gvCmdMgr.h" + +GV_COMMAND(GVABCOriginalCmd, GV_CMD_TYPE_ABC); diff --git a/src/abc/abcExt.h b/src/abc/abcExt.h new file mode 100644 index 00000000..1d7f60bc --- /dev/null +++ b/src/abc/abcExt.h @@ -0,0 +1,61 @@ +#pragma once + + +#include + +#include "base/abc/abc.h" +#include "base/main/mainInt.h" +#include "gvType.h" + +/** + * @brief ABC structure type. + * + */ +typedef struct Abc_Frame_t_ Abc_Frame_t; +typedef struct Abc_Ntk_t_ Abc_Ntk_t; +typedef struct Abc_Obj_t_ Abc_Obj_t; +typedef struct Pdr_Par_t_ Pdr_Par_t; + +/** + * @brief Extern functions under the circuit manager + * + */ +extern "C" { + void Abc_Start(); + void Abc_Stop(); + int Cmd_CommandExecute(Abc_Frame_t* pAbc, const char* sCommand); + Abc_Frame_t* Abc_FrameGetGlobalFrame(); + Abc_Ntk_t* Io_Read(char* pFileName, Io_FileType_t FileType, int fCheck, int fBarBufs); + Abc_Ntk_t* Abc_FrameReadNtk(Abc_Frame_t* p); + Gia_Man_t* Wln_BlastSystemVerilog(char* pFileName, char* pTopModule, char* pDefines, int fSkipStrash, int fInvert, int fTechMap, int fLibInDir, int fVerbose); + int Abc_NtkDarPdr(Abc_Ntk_t* pNtk, Pdr_Par_t* pPars); +} + +/** + * @brief Extern functions under the circuit manager + * + */ +extern void initCirMgr(const int& piNum, const int& poNum, const int& regNum, const int& totNum); +extern bool inputIsPi(const int& gateId); +extern void parseInput(const int& idx, const int& gateId); +extern void parseOutput(const int& idx, const int& gateId, const int& in0Id, const int& inv, std::string poName); +extern void parseAig(const int& gateId, const int& in0Id, const int& in0Inv, const int& in1Id, const int& in1Inv); +extern void parseRi(const int& idx, const int& gateId, const int& in0Id, const int& inv); +extern void parseRiRo(const int& riGid, const int& roGid); +extern int parseRo(const int& idx, const int& gateId, const FileType& fileType); +extern void parseConst0(); +extern void parseConst1(); +extern unsigned getNumPIs(); +extern unsigned getNumPOs(); +extern unsigned getNumLATCHs(); +extern unsigned getNumAIGs(); +extern unsigned getAigIn0Gid(const unsigned& idx); +extern unsigned getAigIn1Gid(const unsigned& idx); +extern unsigned getPoIn0Gid(const unsigned& idx); +extern unsigned getRiIn0Gid(const unsigned& idx); +extern int getAigIn0Cp(const unsigned& idx); +extern int getAigIn1Cp(const unsigned& idx); +extern int getPoIn0Cp(const unsigned& idx); +extern int getRiIn0Cp(const unsigned& idx); + + diff --git a/src/abc/abcMgr.cpp b/src/abc/abcMgr.cpp new file mode 100644 index 00000000..77dd3989 --- /dev/null +++ b/src/abc/abcMgr.cpp @@ -0,0 +1,299 @@ +#include "abcMgr.h" + +#include +#include +#include +#include +#include + +#include "abcExt.h" +#include "util.h" + +gv::engine::AbcMgr *abcMgr; + +namespace gv { +namespace engine { + +AbcMgr::AbcMgr() : pGia(NULL) { init(); } + +AbcMgr::~AbcMgr() { reset(); } + +void AbcMgr::init() { + Abc_Start(); + pAbc = Abc_FrameGetGlobalFrame(); +} + +void AbcMgr::reset() { + // delete pAbc; + // delete pNtk; + Abc_Stop(); +} + +void AbcMgr::execCmd(const char *cmd) { + // calling abc's command + Cmd_CommandExecute(abcMgr->get_Abc_Frame_t(), cmd); +} + +static string gateName(const string &name, const int &bit) { return name + "[" + to_string(bit) + "]"; } + +void AbcMgr::readSeqVerilog(const ABCParams &opt) { + char *pFileName = opt.pFileName; + char *pTopModule = opt.pTopModule; + char *pDefines = opt.pDefines; + int fInvert = opt.fInvert; + int fTechMap = opt.fTechMap; + int fSkipStrash = opt.fSkipStrash; + int fLibInDir = opt.fLibInDir; + int fVerbose = opt.fVerbose; + pGia = Wln_BlastSystemVerilog(pFileName, pTopModule, pDefines, fSkipStrash, fInvert, fTechMap, fLibInDir, fVerbose); +} + +void AbcMgr::readCombVerilog(const ABCParams &opt) { + char *pFileName = opt.pFileName; + pNtk = Io_Read(pFileName, IO_FILE_VERILOG, 1, 0); +} + +void AbcMgr::readVerilogNew(const ABCParams &opt) { + // Gia_Man_t *pGia = NULL; + char Command[1000]; + char *pFileTemp = "._temp_.aig"; + pGia = Gia_AigerRead(pFileTemp, 0, opt.fSkipStrash, 0); + if (pGia == NULL) { + printf("Converting to AIG has failed.\n"); + return; + } + ABC_FREE(pGia->pName); + pGia->pName = opt.pTopModule ? Abc_UtilStrsav(opt.pTopModule) + : Extra_FileNameGeneric(Extra_FileNameWithoutPath(opt.pFileName)); + unlink(pFileTemp); + // complement the outputs + if (opt.fInvert) { + Gia_Obj_t *pObj; + int i; + Gia_ManForEachPo(pGia, pObj, i) + Gia_ObjFlipFaninC0(pObj); + } +} + +void AbcMgr::readAiger(const ABCParams &opt) { + char *pFileName = opt.pFileName; + int fSkipStrash = opt.fSkipStrash; + int fGiaSimple = opt.fGiaSimple; + int fCheck = opt.fCheck; + // int fCheck = 1; + pGia = Gia_AigerRead(pFileName, fGiaSimple, fSkipStrash, fCheck); +} + +void AbcMgr::buildAigName(map &id2Name) { + ifstream mapFile; + string buffer; + string type; + string name; + int idx = 0, bit = 0; + + mapFile.open(".map.txt"); + assert(mapFile.is_open()); + + while (mapFile >> type) { + mapFile >> buffer; + myStr2Int(buffer, idx); + mapFile >> buffer; + myStr2Int(buffer, bit); + mapFile >> buffer; + name = buffer; + if (type == "input") id2Name[Gia_ObjId(pGia, Gia_ManPi(pGia, idx))] = gateName(name, bit); + else if (type == "output") id2Name[Gia_ObjId(pGia, Gia_ManPo(pGia, idx))] = gateName(name, bit); + else if (type == "latch") { + Gia_Obj_t *ro = Gia_ObjRiToRo(pGia, Gia_ManRi(pGia, idx)); + Gia_Obj_t *ri = Gia_ManRi(pGia, idx); + + id2Name[Gia_ObjId(pGia, ro)] = gateName(name, bit); + id2Name[Gia_ObjId(pGia, ri)] = gateName(name, bit) + "_ns"; + } + } +} + +void AbcMgr::travPreprocess() { + // increment the global travel id for circuit traversing usage + Gia_ManIncrementTravId(pGia); + // since we don't want to traverse the constant node, set the TravId of the + // constant node to be as the global one + Gia_ObjSetTravIdCurrent(pGia, Gia_ManConst0(pGia)); +} + +void AbcMgr::giaToCir(const FileType &fileType, map id2Name) { + Gia_Obj_t *pObj, *pObjRi, *pObjRo; // the obj element of gia + size_t i, iPi = 0, iPpi = 0, iPo = 0, iRi = 0, iRo = 0; + map PPI2RO; + Gia_ManForEachObj(pGia, pObj, i) { + int gateId = Gia_ObjId(pGia, pObj); + if (Gia_ObjIsPi(pGia, pObj)) { + if (inputIsPi(gateId)) parseInput(iPi++, gateId); + else parseRo(iRo++, gateId, AIGER); + } else if (Gia_ObjIsPo(pGia, pObj)) { + int in0Id = Gia_ObjId(pGia, Gia_ObjFanin0(pObj)); + int inv = Gia_ObjFaninC0(pObj); + string poName = (id2Name.count(gateId)) ? id2Name[gateId] : to_string(gateId); + parseOutput(iPo++, gateId, in0Id, inv, poName); + } else if (Gia_ObjIsAnd(pObj)) { + int in0Id = Gia_ObjId(pGia, Gia_ObjFanin0(pObj)); + int in1Id = Gia_ObjId(pGia, Gia_ObjFanin1(pObj)); + int in0Inv = Gia_ObjFaninC0(pObj); + int in1Inv = Gia_ObjFaninC1(pObj); + if (PPI2RO.count(in0Id)) in0Id = PPI2RO[in0Id]; + if (PPI2RO.count(in1Id)) in1Id = PPI2RO[in1Id]; + parseAig(gateId, in0Id, in0Inv, in1Id, in1Inv); + } else if (Gia_ObjIsRo(pGia, pObj)) { + if (fileType == VERILOG) { + PPI2RO[gateId] = (iPpi < iRo) ? parseRo(iPpi, 0, VERILOG) : 0; + iPpi++; + } else if (fileType == AIGER) { + parseRo(iRo++, gateId, AIGER); + } + } else if (Gia_ObjIsRi(pGia, pObj)) { + int in0Id = Gia_ObjId(pGia, Gia_ObjFanin0(pObj)); + int inv = Gia_ObjFaninC0(pObj); + parseRi(iRi++, gateId, in0Id, inv); + } else if (Gia_ObjIsConst0(pObj)) { + parseConst0(); + } else { + std::cout << "not defined gate type" << endl; + assert(true); + } + } + Gia_ManForEachRiRo(pGia, pObjRi, pObjRo, i) { + if (i == iRo) break; + int riGid = Gia_ObjId(pGia, pObjRi), roGid = 0; + if (fileType == VERILOG) roGid = PPI2RO[Gia_ObjId(pGia, pObjRo)]; + else if (fileType == AIGER) roGid = Gia_ObjId(pGia, pObjRo); + parseRiRo(riGid, roGid); + } + parseConst1(); +} + +void AbcMgr::initCir(const FileType &fileType) { + // Create lists + int piNum = Gia_ManPiNum(pGia), regNum = Gia_ManRegNum(pGia); + int poNum = 0, totNum = 0; + if (fileType == VERILOG) { + piNum = (Gia_ManRegNum(pGia)) ? piNum - regNum + 1 : piNum; + regNum = ((Gia_ManRegNum(pGia) - 1) < 0) ? 0 : Gia_ManRegNum(pGia) - 1; + } else if (fileType == AIGER) { + piNum = Gia_ManPiNum(pGia); + regNum = (Gia_ManRegNum(pGia) < 0) ? 0 : Gia_ManRegNum(pGia); + } + poNum = Gia_ManPoNum(pGia); + totNum = Gia_ManObjNum(pGia); + + initCirMgr(piNum, poNum, regNum, totNum); +} + +void AbcMgr::cirToAig(IDMap &aigIdMap) { + Vec_Ptr_t *vNodes; + Abc_Obj_t *pObj, *pNode0, *pNode1; + Abc_Ntk_t *pNtkNew; + int nTotal, nInputs, nOutputs, nLatches, nAnds; + int nConstr = 0; + int nDigits, i; + char *pCur; + unsigned uLit0, uLit1, uLit; + int c0, c1; + + nInputs = getNumPIs(); + nOutputs = getNumPOs(); + nLatches = getNumLATCHs(); + nAnds = getNumAIGs(); + nTotal = nInputs + nLatches + nAnds; + + // check the parameters + if (nTotal != nInputs + nLatches + nAnds) { + fprintf(stdout, "The number of objects does not match.\n"); + } + + // allocate the empty AIG + pNtkNew = Abc_NtkAlloc(ABC_NTK_STRASH, ABC_FUNC_AIG, 1); + pNtkNew->nConstrs = nConstr; + // prepare the array of nodes + vNodes = Vec_PtrAlloc(1 + nInputs + nLatches + nAnds); + Abc_Obj_t *zero = Abc_ObjNot(Abc_AigConst1(pNtkNew)); + Vec_PtrPush(vNodes, Abc_ObjNot(Abc_AigConst1(pNtkNew))); + + // create the PIs + for (i = 0; i < nInputs; i++) { + pObj = Abc_NtkCreatePi(pNtkNew); + Vec_PtrPush(vNodes, pObj); + } + // create the POs + for (i = 0; i < nOutputs; i++) { + pObj = Abc_NtkCreatePo(pNtkNew); + } + // create the latches + nDigits = Abc_Base10Log(nLatches); + for (i = 0; i < nLatches; i++) { + pObj = Abc_NtkCreateLatch(pNtkNew); + Abc_LatchSetInit0(pObj); + pNode0 = Abc_NtkCreateBi(pNtkNew); + pNode1 = Abc_NtkCreateBo(pNtkNew); + Abc_ObjAddFanin(pObj, pNode0); + Abc_ObjAddFanin(pNode1, pObj); + Vec_PtrPush(vNodes, pNode1); + } + // create the AND gates + for (i = 0; i < nAnds; i++) { + uLit0 = getAigIn0Gid(i); + uLit1 = getAigIn1Gid(i); + c0 = getAigIn0Cp(i); + c1 = getAigIn1Cp(i); + + if (aigIdMap.count(uLit0)) uLit0 = aigIdMap[uLit0]; + if (aigIdMap.count(uLit1)) uLit1 = aigIdMap[uLit1]; + pNode0 = Abc_ObjNotCond((Abc_Obj_t *)Vec_PtrEntry(vNodes, uLit0), c0); + pNode1 = Abc_ObjNotCond((Abc_Obj_t *)Vec_PtrEntry(vNodes, uLit1), c1); + assert(Vec_PtrSize(vNodes) == i + 1 + nInputs + nLatches); + Vec_PtrPush(vNodes, Abc_AigAnd((Abc_Aig_t *)pNtkNew->pManFunc, pNode0, pNode1)); + } + // create the LATCH inputs + Abc_NtkForEachLatchInput(pNtkNew, pObj, i) { + uLit0 = getRiIn0Gid(i); + c0 = getRiIn0Cp(i); + if (aigIdMap.count(uLit0)) uLit0 = aigIdMap[uLit0]; + pNode0 = Abc_ObjNotCond((Abc_Obj_t *)Vec_PtrEntry(vNodes, uLit0), (c0)); + Abc_ObjAddFanin(pObj, pNode0); + } + // read the PO driver literals + Abc_NtkForEachPo(pNtkNew, pObj, i) { + uLit0 = getPoIn0Gid(i); + c0 = getPoIn0Cp(i); + if (aigIdMap.count(uLit0)) uLit0 = aigIdMap[uLit0]; + pNode0 = Abc_ObjNotCond((Abc_Obj_t *)Vec_PtrEntry(vNodes, uLit0), + c0); //^ (uLit0 < 2) ); + Abc_ObjAddFanin(pObj, pNode0); + } + + // read the names if present + Abc_NtkShortNames(pNtkNew); + // skipping the comments + // ABC_FREE(pContents); + Vec_PtrFree(vNodes); + // remove the extra nodes + Abc_AigCleanup((Abc_Aig_t *)pNtkNew->pManFunc); + // check the result + int fCheck = 1; + if (fCheck && !Abc_NtkCheckRead(pNtkNew)) { + printf("Io_ReadAiger: The network check has failed.\n"); + Abc_NtkDelete(pNtkNew); + } + + // save the new network + pNtk = pNtkNew; +} + +void AbcMgr::writeBlif(const string &fileName) { + Abc_Ntk_t *pNtkTemp = Abc_NtkToNetlist(pNtk); + char *pFileName = new char[100]; + strcpy(pFileName, fileName.c_str()); + Io_WriteBlif(pNtkTemp, pFileName, 1, 0, 1); +} + +} // namespace engine +} // namespace gv diff --git a/src/abc/abcMgr.h b/src/abc/abcMgr.h new file mode 100644 index 00000000..fedca124 --- /dev/null +++ b/src/abc/abcMgr.h @@ -0,0 +1,70 @@ +#pragma once +#define GV_ABC_MGR + +#include +#include + +#include "abcExt.h" +#include "cirDef.h" +using namespace std; + +namespace gv { +namespace engine { +class AbcMgr; +} +} // namespace gv + +extern gv::engine::AbcMgr* abcMgr; + +namespace gv { +namespace engine { + +struct ABCParams { + ABCParams() : fInvert(0), fTechMap(0), fSkipStrash(0), fVerbose(0), fGiaSimple(0), + fCheck(0), fLibInDir(0), pTopModule(nullptr), pDefines(nullptr), pFileName(new char[100]) {} + char* pFileName; + char* pTopModule; + char* pDefines; + int fInvert; + int fTechMap; + int fSkipStrash; + int fVerbose; + int fGiaSimple; + int fLibInDir; + int fCheck; +}; + +class AbcMgr { +public: + AbcMgr(); + ~AbcMgr(); + + void init(); + void reset(); + void readAiger(const ABCParams&); + void readSeqVerilog(const ABCParams&); + void readCombVerilog(const ABCParams&); + void readVerilogNew(const ABCParams&); + void buildAigName(map&); + void travPreprocess(); + void travAllObj(const FileType&, map); + void giaToCir(const FileType&, map); + void initCir(const FileType&); + void cirToGia(); + void cirToAig(IDMap&); + void execCmd(const char*); + + // Verification command + void runPDR(const bool&); + void writeBlif(const string&); + + Abc_Frame_t* get_Abc_Frame_t() { return pAbc; } + Gia_Man_t* pGia; + +private: + Abc_Frame_t* pAbc; + Abc_Ntk_t* pNtk; +}; + +} // namespace engine +} // namespace gv diff --git a/src/abc/abcProve.cpp b/src/abc/abcProve.cpp new file mode 100644 index 00000000..22f1ac6c --- /dev/null +++ b/src/abc/abcProve.cpp @@ -0,0 +1,17 @@ +#include "abcMgr.h" +#include "proof/pdr/pdr.h" + +namespace gv { +namespace engine { + +void AbcMgr::runPDR(const bool &verbose) { + // Start PDR + Pdr_Par_t *pPars = new Pdr_Par_t(); + Pdr_ManSetDefaultParams(pPars); + if (verbose) pPars->fVerbose = 1; + pPars->fSolveAll = 1; + pAbc->Status = Abc_NtkDarPdr(pNtk, pPars); +} + +} // namespace engine +} // namespace gv diff --git a/src/abc/gvAbcCmd.cpp b/src/abc/gvAbcCmd.cpp deleted file mode 100644 index 0ecf6174..00000000 --- a/src/abc/gvAbcCmd.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef GV_ABC_CMD_C -#define GV_ABC_CMD_C - -#include "gvAbcCmd.h" -#include "gvAbcMgr.h" -#include "gvModMgr.h" -#include "gvMsg.h" -#include "util.h" -#include -#include - -bool -GVinitAbcCmd() { - if (abcMgr) delete abcMgr; - abcMgr = new AbcMgr; - return (gvCmdMgr->regCmd("ABCRead", 4, new GVABCReadCmd), - gvCmdMgr->regCmd("ABCPrint", 4, new GVABCPrintCmd), - gvCmdMgr->regCmd("ABCCMD", 6, new GVABCOriginalCmd)); -} - -//---------------------------------------------------------------------- -// ABCRead <(string filename)> -//---------------------------------------------------------------------- - -GVCmdExecStatus -GVABCReadCmd ::exec(const string& option) { - vector options; - string fileName = ""; - GVCmdExec::lexOptions(option, options); - size_t n = options.size(); - for (size_t i = 0; i < n; ++i) { - const string& token = options[i]; - if (fileName == "") fileName = options[i]; - else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); - } - if (fileName == "") - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, - "<(string fileName)>"); - abcMgr->abcReadDesign(fileName); - return GV_CMD_EXEC_DONE; -} - -void -GVABCReadCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: ABCRead " << endl; -} - -void -GVABCReadCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "ABCRead: " - << "Read netlist by ABC." << endl; -} - -//---------------------------------------------------------------------- -// ABCPrint [-Verbose] -//---------------------------------------------------------------------- - -GVCmdExecStatus -GVABCPrintCmd ::exec(const string& option) { - vector options; - GVCmdExec::lexOptions(option, options); - bool basic = false, verbose = false; - size_t n = options.size(); - - if (options.size() > 1) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[1]); - else if (options.size()) { - if (myStrNCmp("-Verbose", options[0], 2) == 0) verbose = true; - else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); - } - (abcMgr->get_abcNtkMgr())->printSummary(); - return GV_CMD_EXEC_DONE; -} - -void -GVABCPrintCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: ABCPrint " << endl; -} - -void -GVABCPrintCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "ABCPrint: " - << "Print netlist information." << endl; -} - -//---------------------------------------------------------------------- -// ABCCMD -//---------------------------------------------------------------------- - -GVCmdExecStatus -GVABCOriginalCmd ::exec(const string& option) { - vector options; - GVCmdExec::lexOptions(option, options); - size_t n = options.size(); - string command; - for (size_t i = 0; i < n; ++i) { - command += options[i]; - if (i < n - 1) { - command += " "; - } - } - - // calling abc's command - char Command[1024], abcCmd[128]; - strcpy(abcCmd, command.c_str()); - sprintf(Command, "%s", abcCmd); - Cmd_CommandExecute(abcMgr->get_Abc_Frame_t(), Command); -} - -void -GVABCOriginalCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: ABCCMD " << endl; -} - -void -GVABCOriginalCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "ABCCMD: " - << "Directly call ABC's command." << endl; -} - -#endif \ No newline at end of file diff --git a/src/abc/gvAbcCmd.h b/src/abc/gvAbcCmd.h deleted file mode 100644 index 68371f65..00000000 --- a/src/abc/gvAbcCmd.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef GV_ABC_CMD_H -#define GV_ABC_CMD_H - -#include "gvCmdMgr.h" - -GV_COMMAND(GVABCReadCmd, GV_CMD_TYPE_ABC); -GV_COMMAND(GVABCPrintCmd, GV_CMD_TYPE_ABC); -GV_COMMAND(GVABCOriginalCmd, GV_CMD_TYPE_ABC); - -#endif \ No newline at end of file diff --git a/src/abc/gvAbcMgr.cpp b/src/abc/gvAbcMgr.cpp deleted file mode 100644 index 983ad0c2..00000000 --- a/src/abc/gvAbcMgr.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "gvAbcMgr.h" -#include "base/abc/abc.h" -#include "bdd/cudd/cudd.h" -#include "gvAbcNtk.h" -#include "sat/cnf/cnf.h" -#include -#include -#include - -AbcMgr* abcMgr; - -void -AbcMgr::init() { - Abc_Start(); - pAbc = Abc_FrameGetGlobalFrame(); -} - -void -AbcMgr::reset() { - delete pAbc; -} - -void -AbcMgr::abcReadDesign(string& fileName) { - char pFileName[128]; - strcpy(pFileName, fileName.c_str()); - char Command[1000]; - sprintf(Command, "read %s", pFileName); - Cmd_CommandExecute(pAbc, Command); - pNtkMgr = new abcNtkMgr(pAbc->pNtkCur); -} diff --git a/src/abc/gvAbcMgr.h b/src/abc/gvAbcMgr.h deleted file mode 100644 index c8c92e71..00000000 --- a/src/abc/gvAbcMgr.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef GV_ABC_MGR -#define GV_ABC_MGR - -#include "base/abc/abc.h" -#include "base/main/main.h" -#include "base/main/mainInt.h" -#include "gvAbcNtk.h" -#include - -using namespace std; - -class AbcMgr; -extern AbcMgr* abcMgr; -typedef struct Abc_Frame_t_ Abc_Frame_t; -typedef struct Abc_Ntk_t_ Abc_Ntk_t; -typedef struct Abc_Obj_t_ Abc_Obj_t; - -extern "C" -{ - void Abc_Start(); - void Abc_Stop(); - Abc_Frame_t* Abc_FrameGetGlobalFrame(); - int Cmd_CommandExecute(Abc_Frame_t* pAbc, const char* sCommand); - Abc_Ntk_t* Abc_FrameReadNtk(Abc_Frame_t* p); -} - -class AbcMgr -{ - public: - AbcMgr() { init(); } - ~AbcMgr() { reset(); } - - void init(); - void reset(); - - void abcReadDesign(string&); - - Abc_Frame_t* get_Abc_Frame_t() { return pAbc; } - abcNtkMgr* get_abcNtkMgr() { return pNtkMgr; } - - private: - Abc_Frame_t* pAbc; - abcNtkMgr* pNtkMgr; -}; - -#endif diff --git a/src/abc/gvAbcNtk.cpp b/src/abc/gvAbcNtk.cpp deleted file mode 100644 index 6a56b6ed..00000000 --- a/src/abc/gvAbcNtk.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#ifndef GV_ABC_NTK_C -#define GV_ABC_NTK_C - -#include "gvAbcNtk.h" -#include "base/abc/abc.h" -#include "base/main/main.h" -#include "base/main/mainInt.h" -#include "sat/cnf/cnf.h" -#include "gvAbcMgr.h" -#include -#include - -extern "C" -{ - int Abc_NtkDSat( Abc_Ntk_t * pNtk, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int nLearnedStart, int nLearnedDelta, int nLearnedPerce, int fAlignPol, int fAndOuts, int fNewSolver, int fVerbose ); -} - -AbcMgr* abcNtkMgr::_AbcMgr = 0; - -void -abcNtkMgr::init() { - Total_num = Abc_NtkObjNum(pNtk); - PI_num = Abc_NtkCiNum(pNtk); - PO_num = Abc_NtkCoNum(pNtk); - Node_num = Abc_NtkNodeNum(pNtk); -} - -void -abcNtkMgr::printSummary() const { - cout << endl; - cout << "Circuit Statistics" << endl; - cout << "==================" << endl; - cout << " PI " << setw(10) << right << PI_num << endl; - cout << " PO " << setw(10) << right << PO_num << endl; - cout << " Node " << setw(10) << right << Node_num << endl; - cout << "------------------" << endl; - cout << " Total" << setw(10) << right << PI_num + PO_num + Node_num << endl; -} - -void -abcNtkMgr::sweep(bool verbose) { - if (!Abc_NtkIsLogic(pNtk)) { - cout << "The classical (SIS-like) sweep can only be performed on a logic network.\n" << endl; - return; - } - Abc_NtkSweep(pNtk, verbose); -} - -void Abc_NtkModelToVector( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues ) -{ - int * pModel; - pModel = pNtk->pModel; - for (int i = 0; i < Abc_NtkPiNum(pNtk); i++ ) - Vec_IntWriteEntry( vPiValues, i, pModel[i] ); -} - -void Abc_NtkVectorClearPars( Vec_Int_t * vPiValues, int nPars ) -{ - for (int i = 0; i < nPars; i++ ) - Vec_IntWriteEntry( vPiValues, i, -1 ); -} - -void Abc_NtkVectorClearVars( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues, int nPars ) -{ - for (int i = nPars; i < Abc_NtkPiNum(pNtk); i++ ) - Vec_IntWriteEntry( vPiValues, i, -1 ); -} - -void Abc_NtkVectorPrintPars( Vec_Int_t * vPiValues, int nPars ) -{ - for (int i = 0; i < nPars; i++ ) - printf( "%d", Vec_IntEntry(vPiValues,i) ); -} - -void Abc_NtkVectorPrintVars( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues, int nPars ) -{ - for (int i = nPars; i < Abc_NtkPiNum(pNtk); i++ ) - printf( "%d", Vec_IntEntry(vPiValues,i) ); -} - -void -abcNtkMgr::abcQBF(int nPars, int nIters, bool fVerbose) -{ - if ( !Abc_NtkIsStrash(pNtk) ) { - pNtk = Abc_NtkStrash( pNtk, 0, 1, 0 ); - } - - Abc_Ntk_t * pNtkVer, * pNtkSyn, * pNtkSyn2, * pNtkTemp; - Vec_Int_t * vPiValues; - abctime clkTotal = Abc_Clock(), clkS, clkV; - int nInputs, RetValue, fFound = 0, nItersMax=10000; - - assert( Abc_NtkIsStrash(pNtk) ); - assert( Abc_NtkIsComb(pNtk) ); - assert( Abc_NtkPoNum(pNtk) == 1 ); - assert( nPars > 0 && nPars < Abc_NtkPiNum(pNtk) ); - // assert( Abc_NtkPiNum(pNtk)-nPars < 32 ); - nInputs = Abc_NtkPiNum(pNtk) - nPars; - - // initialize the synthesized network with 0000-combination - vPiValues = Vec_IntStart( Abc_NtkPiNum(pNtk) ); - - // create random init value - { - int i; - srand( time(NULL) ); - for ( i = nPars; i < Abc_NtkPiNum(pNtk); i++ ) - Vec_IntWriteEntry( vPiValues, i, rand() & 1 ); - } - - Abc_NtkVectorClearPars( vPiValues, nPars ); - pNtkSyn = Abc_NtkMiterCofactor( pNtk, vPiValues ); - if ( fVerbose ) - { - printf( "Iter %2d : ", 0 ); - printf( "AIG = %6d ", Abc_NtkNodeNum(pNtkSyn) ); - Abc_NtkVectorPrintVars( pNtk, vPiValues, nPars ); - printf( "\n" ); - } - - // iteratively solve - for ( nIters = 0; nIters < nItersMax; nIters++ ) - { - // solve the synthesis instance - clkS = Abc_Clock(); - // RetValue = Abc_NtkMiterSat( pNtkSyn, 0, 0, 0, NULL, NULL ); - RetValue = Abc_NtkDSat( pNtkSyn, (ABC_INT64_T)0, (ABC_INT64_T)0, 0, 0, 0, 1, 0, 0, 0 ); - clkS = Abc_Clock() - clkS; - if ( RetValue == 0 ) - Abc_NtkModelToVector( pNtkSyn, vPiValues ); - if ( RetValue == 1 ) - { - break; - } - if ( RetValue == -1 ) - { - printf( "Synthesis timed out.\n" ); - break; - } - // there is a counter-example - - // construct the verification instance - Abc_NtkVectorClearVars( pNtk, vPiValues, nPars ); - pNtkVer = Abc_NtkMiterCofactor( pNtk, vPiValues ); - // complement the output - Abc_ObjXorFaninC( Abc_NtkPo(pNtkVer,0), 0 ); - - // solve the verification instance - clkV = Abc_Clock(); - RetValue = Abc_NtkMiterSat( pNtkVer, 0, 0, 0, NULL, NULL ); - clkV = Abc_Clock() - clkV; - if ( RetValue == 0 ) - Abc_NtkModelToVector( pNtkVer, vPiValues ); - Abc_NtkDelete( pNtkVer ); - if ( RetValue == 1 ) - { - fFound = 1; - break; - } - if ( RetValue == -1 ) - { - printf( "Verification timed out.\n" ); - break; - } - // there is a counter-example - - // create a new synthesis network - Abc_NtkVectorClearPars( vPiValues, nPars ); - pNtkSyn2 = Abc_NtkMiterCofactor( pNtk, vPiValues ); - // add to the synthesis instance - pNtkSyn = Abc_NtkMiterAnd( pNtkTemp = pNtkSyn, pNtkSyn2, 0, 0 ); - Abc_NtkDelete( pNtkSyn2 ); - Abc_NtkDelete( pNtkTemp ); - - if ( fVerbose ) - { - printf( "Iter %2d : ", nIters+1 ); - printf( "AIG = %6d ", Abc_NtkNodeNum(pNtkSyn) ); - Abc_NtkVectorPrintVars( pNtk, vPiValues, nPars ); - printf( " " ); - ABC_PRT( "Syn", clkS ); - } - } - Abc_NtkDelete( pNtkSyn ); - // report the results - if ( fFound ) - { - int nZeros = Vec_IntCountZero( vPiValues ); - printf( "Parameters: " ); - Abc_NtkVectorPrintPars( vPiValues, nPars ); - printf( " Statistics: 0=%d 1=%d\n", nZeros, Vec_IntSize(vPiValues) - nZeros ); - printf( "Solved after %d iterations. ", nIters ); - } - else if ( nIters == nItersMax ) - printf( "Quit after %d iterations. ", nItersMax ); - else - printf( "Implementation does not exist. " ); - ABC_PRT( "Total runtime", Abc_Clock() - clkTotal ); - Vec_IntFree( vPiValues ); -} - -#endif \ No newline at end of file diff --git a/src/abc/gvAbcNtk.h b/src/abc/gvAbcNtk.h deleted file mode 100644 index 3cb1ece3..00000000 --- a/src/abc/gvAbcNtk.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef GV_ABC_NTK_H -#define GV_ABC_NTK_H - -#include -using namespace std; - -class AbcMgr; -class abcNtkMgr; -typedef struct Abc_Frame_t_ Abc_Frame_t; -typedef struct Abc_Ntk_t_ Abc_Ntk_t; -typedef struct Abc_Obj_t_ Abc_Obj_t; - -class abcNtkMgr -{ - public: - abcNtkMgr(Abc_Ntk_t* ntk) : pNtk(ntk) { init(); } - ~abcNtkMgr() {} - - void init(); - - void sweep(bool); - - void printSummary() const; - Abc_Ntk_t* getNtk() { return pNtk; } - void abcQBF(int, int, bool); - - private: - Abc_Ntk_t* pNtk; - static AbcMgr* _AbcMgr; - - vector PI_List; - vector PO_List; - vector DFS_List; - unsigned Total_num; - unsigned PI_num; - unsigned PO_num; - unsigned Node_num; -}; -#endif \ No newline at end of file diff --git a/src/app/appCmd.cpp b/src/app/appCmd.cpp new file mode 100644 index 00000000..05ac4ca4 --- /dev/null +++ b/src/app/appCmd.cpp @@ -0,0 +1,36 @@ +#include "appCmd.h" + +#include + +#include "appMgr.h" +#include "gvCmdMgr.h" + +// GVCmdMgr* appCmdMgr = 0; + +AppCmdMgr* appCmdMgr = 0; +bool initAppCmd() { + if (!appCmdMgr) appCmdMgr = new AppCmdMgr; + return (appCmdMgr->regCmd("SAVE", 4, new AppSaveCmd)); +} + +//---------------------------------------------------------------------- +// Save +//---------------------------------------------------------------------- +GVCmdExecStatus AppSaveCmd::exec(const string& option) { + // check option + vector options; + GVCmdExec::lexOptions(option, options); + + return GV_CMD_EXEC_QUIT; + + return GV_CMD_EXEC_DONE; +} + +void AppSaveCmd::usage(const bool& verbose) const { + cout << "Usage: CIRRead <-Verilog | -Aiger | -Blif> <(string fileName)> [-Replace]" << endl; +} + +void AppSaveCmd::help() const { + cout << setw(20) << left << "SAVE:" + << "Save the commands into the script." << endl; +} \ No newline at end of file diff --git a/src/app/appCmd.h b/src/app/appCmd.h new file mode 100644 index 00000000..a9a22e87 --- /dev/null +++ b/src/app/appCmd.h @@ -0,0 +1,7 @@ +#pragma once + + +#include "gvCmdMgr.h" + +GV_COMMAND(AppSaveCmd, GV_CMD_TYPE_APP); + diff --git a/src/app/appMgr.cpp b/src/app/appMgr.cpp new file mode 100644 index 00000000..2474c11b --- /dev/null +++ b/src/app/appMgr.cpp @@ -0,0 +1,128 @@ +#include "appMgr.h" + +#include +#include +#include + +#include "gvCmdMgr.h" +#include "gvType.h" +#include "modMgr.h" + +extern "C" { +#include +#include +} + +GVCmdExecStatus appCmdHandlerItf() { appCmdMgr->appCmdHandler(); } + +AppCmdMgr::AppCmdMgr() : GVCmdMgr("app") { + updateModPrompt("app"); +} + +GVCmdExecStatus AppCmdMgr::execAppCmd(const string& command) { + system(command.c_str()); + return GV_CMD_EXEC_DONE; +} + +GVCmdExec* AppCmdMgr::parseCmd(string& appCmd) { + vector _currHistory = getHistory(); + assert(_currHistory.size()); + string str = _currHistory.back(); + assert(str[0] != 0 && str[0] != ' '); + + GVCmdExec* e = 0; + string cmd; + + // normalize: keep only one space between two words + unsigned delCount = 0; + for (size_t i = 2, n = str.size(); i < n; ++i) { + if ((str[i - 2] == ' ') && (str[i - 1] == ' ')) { + for (size_t j = i; j < n; ++j) str[j - 1] = str[j]; + --i; + ++delCount; + } + } + str.erase(str.length() - delCount); + + // space count: indicates how many words there are in cmd + unsigned spCount = 0; + for (size_t i = 0, n = str.size(); i < n; ++i) + if (str[i] == ' ') ++spCount; + + // try to match commands + size_t idx = 0; + for (unsigned i = 0; (i < spCount + 1) && i < 2; ++i) { + idx = str.find(' ', idx + 1); + cmd = str.substr(0, idx); + + e = getCmd(cmd); + if (e) break; + } + + // can't match any command + if (!e) { + // Chengyin added : Support linux commands + string _cmd = ""; + if (str.size() >= 2) { + // Support comments in dofile, NO execution + if ((str[0] == '/') && (str[1] == '/')) return e; + } + for (idx = 0; idx < str.size(); ++idx) { + if (str[idx] == ' ') break; + } + _cmd = str.substr(0, idx); + if ((_cmd == "ls") || (_cmd == "vi") || (_cmd == "vim") || + (_cmd == "echo") || (_cmd == "cat") || (_cmd == "clear")) + system(str.c_str()); + // else + // gvMsg(GV_MSG_ERR) << "Illegal command!! (" << str << ")" << endl; + } else if (idx != string::npos) { + size_t opt = str.find_first_not_of(' ', idx); + if (opt != string::npos) appCmd = str.substr(opt); + } + + return e; +} + +GVCmdExecStatus AppCmdMgr::execAppCmd() { + // Read User Command Input + string str = ""; + char* execCmd = new char[1024]; + ifstream& _dofile = gvCmdMgr->getDofile(); + if (_dofile.is_open()) { + getline(_dofile, str); + strcpy(execCmd, str.c_str()); + // Detect dofile comment(#) and blank command + if (execCmd[0] != '#' && str.size() > 0) + cout << getPrompt() << execCmd << endl; + if (_dofile.eof()) closeDofile(); + } else + execCmd = readline(getPrompt().c_str()); + assert(execCmd); + + // Detect dofile comment(#) for debugging + if (execCmd[0] == '#') return GV_CMD_EXEC_NOP; + + if (addHistory(execCmd)) { + add_history(getHistory().back().c_str()); + string option = ""; + string appCmd(execCmd); + GVCmdExec* e = parseCmd(option); + if (e) return e->exec(option); + else execAppCmd(appCmd); + } + delete[] execCmd; + return GV_CMD_EXEC_NOP; +} + +GVCmdExecStatus AppCmdMgr::appCmdHandler() { + GVCmdExecStatus status = GV_CMD_EXEC_DONE; + while (status != GV_CMD_EXEC_QUIT) { + appCmdMgr->setPrompt(); + status = execAppCmd(); + cout << endl; + } + // Reset current mode to the setup mode + modeMgr->setGVMode(MOD_TYPE_SETUP); + return GV_CMD_EXEC_DONE; +} \ No newline at end of file diff --git a/src/app/appMgr.h b/src/app/appMgr.h new file mode 100644 index 00000000..777caf0a --- /dev/null +++ b/src/app/appMgr.h @@ -0,0 +1,22 @@ +#pragma once + + +#include + +#include "gvCmdMgr.h" +using namespace std; + +class AppCmdMgr; +extern AppCmdMgr* appCmdMgr; + +class AppCmdMgr : public GVCmdMgr { +public: + AppCmdMgr(); + GVCmdExecStatus execAppCmd(); + GVCmdExecStatus execAppCmd(const string& command); + GVCmdExecStatus appCmdHandler(); + GVCmdExec* parseCmd(string&); + +private: +}; + diff --git a/src/bdd/.depend.mak b/src/bdd/.depend.mak deleted file mode 100644 index 09ce4e74..00000000 --- a/src/bdd/.depend.mak +++ /dev/null @@ -1,36 +0,0 @@ -bddNodeV.o: bddNodeV.cpp bddNodeV.h bddMgrV.h myHash.h -bddMgrV.o: bddMgrV.cpp bddNodeV.h bddMgrV.h myHash.h ../../include/util.h \ - ../../include/rnGen.h ../../include/myUsage.h -bddCmd.o: bddCmd.cpp bddCmd.h ../../include/gvCmdMgr.h bddMgrV.h myHash.h \ - bddNodeV.h ../../include/gvMsg.h ../../include/gvNtk.h \ - ../../include/gvAbcMgr.h ../../include/base/abc/abc.h \ - ../../include/misc/vec/vec.h ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/abc/abc.h \ - ../../include/base/main/abcapis.h ../../include/base/cmd/cmd.h \ - ../../include/base/io/ioAbc.h ../../include/misc/util/utilNam.h \ - ../../include/base/main/mainInt.h ../../include/base/main/main.h \ - ../../include/misc/tim/tim.h ../../include/map/if/if.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/util/utilTruth.h \ - ../../include/opt/dau/dau.h ../../include/misc/vec/vecHash.h \ - ../../include/aig/aig/aig.h ../../include/proof/ssw/ssw.h \ - ../../include/proof/fra/fra.h ../../include/opt/dar/dar.h \ - ../../include/sat/bsat/satSolver.h ../../include/sat/bsat/satVec.h \ - ../../include/sat/bsat/satClause.h ../../include/misc/util/utilDouble.h \ - ../../include/aig/ioa/ioa.h ../../include/gvAbcNtk.h \ - ../../include/kernel/sigtools.h ../../include/kernel/yosys.h \ - /usr/include/tcl8.6/tcl.h /usr/include/tcl8.6/tclDecls.h \ - /usr/include/tcl8.6/tclPlatDecls.h ../../include/kernel/hashlib.h \ - ../../include/kernel/log.h ../../include/kernel/rtlil.h \ - ../../include/kernel/constids.inc ../../include/kernel/register.h \ - ../../include/kernel/utils.h ../../include/kernel/yosys.h \ - ../../include/util.h ../../include/rnGen.h ../../include/myUsage.h diff --git a/src/bdd/.extheader.mak b/src/bdd/.extheader.mak deleted file mode 100644 index 7635a409..00000000 --- a/src/bdd/.extheader.mak +++ /dev/null @@ -1,13 +0,0 @@ -bdd.d: ../../include/bddMgrV.h ../../include/bddNodeV.h ../../include/bddCmd.h ../../include/myHash.h -../../include/bddMgrV.h: bddMgrV.h - @rm -f ../../include/bddMgrV.h - @ln -fs ../src/bdd/bddMgrV.h ../../include/bddMgrV.h -../../include/bddNodeV.h: bddNodeV.h - @rm -f ../../include/bddNodeV.h - @ln -fs ../src/bdd/bddNodeV.h ../../include/bddNodeV.h -../../include/bddCmd.h: bddCmd.h - @rm -f ../../include/bddCmd.h - @ln -fs ../src/bdd/bddCmd.h ../../include/bddCmd.h -../../include/myHash.h: myHash.h - @rm -f ../../include/myHash.h - @ln -fs ../src/bdd/myHash.h ../../include/myHash.h diff --git a/src/bdd/Makefile b/src/bdd/Makefile deleted file mode 100644 index ab89e3d6..00000000 --- a/src/bdd/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -PKGFLAG = -EXTHDRS = bddMgrV.h bddNodeV.h bddCmd.h myHash.h - -include ../Makefile.in -include ../Makefile.lib diff --git a/src/bdd/bddCmd.cpp b/src/bdd/bddCmd.cpp index ccb94edf..38d328ac 100644 --- a/src/bdd/bddCmd.cpp +++ b/src/bdd/bddCmd.cpp @@ -3,24 +3,27 @@ PackageName [ bdd ] Synopsis [ Define BDD commands ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2005-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ #include "bddCmd.h" -#include "bddMgrV.h" -#include "gvMsg.h" -#include "gvNtk.h" -#include "util.h" + #include #include #include #include #include +#include "bddMgrV.h" +#include "cirGate.h" +#include "cirMgr.h" +#include "gvMsg.h" +#include "util.h" + +using namespace gv::cir; using namespace std; -bool -GVinitBddCmd() { +bool initBddCmd() { if (bddMgrV) delete bddMgrV; bddMgrV = new BddMgrV; return (gvCmdMgr->regCmd("BRESET", 6, new BResetCmd) && @@ -43,14 +46,13 @@ GVinitBddCmd() { return true; } -bool -isValidBddName(const string& str) { +bool isValidBddName(const string& str) { int id; return (isValidVarName(str) || (myStr2Int(str, id) && id >= 0)); } extern BddNodeV getBddNodeV(const string& bddName); -bool setBddOrder = false; +bool setBddOrder = false; //---------------------------------------------------------------------- // BRESET <(size_t nSupports)> <(size_t hashSize)> <(size_t cacheSize)> @@ -80,15 +82,13 @@ BResetCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BResetCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) +void BResetCmd::usage(const bool& verbose) const { + cout << "Usage: BRESET <(size_t nSupports)> <(size_t hashSize)> " << "<(size_t cacheSize)>" << endl; } -void -BResetCmd::help() const { +void BResetCmd::help() const { cout << setw(20) << left << "BRESET: " << "BDD reset" << endl; } @@ -116,19 +116,18 @@ BSetVarCmd::exec(const string& option) { !bddMgrV->addBddNodeV(options[1], n())) return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); return GV_CMD_EXEC_DONE; - } else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); + } else + return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); return GV_CMD_EXEC_DONE; } -void -BSetVarCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BSETVar <(size_t level)> <(string varName)>" - << endl; +void BSetVarCmd::usage(const bool& verbose) const { + cout << "Usage: BSETVar <(size_t level)> <(string varName)>" + << endl; } -void -BSetVarCmd::help() const { +void BSetVarCmd::help() const { cout << setw(20) << left << "BSETVar: " << "BDD set a variable name for a support" << endl; } @@ -158,14 +157,12 @@ BInvCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BInvCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BINV <(string varName)> <(string bddName)>" - << endl; +void BInvCmd::usage(const bool& verbose) const { + cout << "Usage: BINV <(string varName)> <(string bddName)>" + << endl; } -void -BInvCmd::help() const { +void BInvCmd::help() const { cout << setw(20) << left << "BINV: " << "BDD Inv" << endl; } @@ -199,14 +196,12 @@ BAndCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BAndCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BAND <(string varName)> <(string bddName)>..." - << endl; +void BAndCmd::usage(const bool& verbose) const { + cout << "Usage: BAND <(string varName)> <(string bddName)>..." + << endl; } -void -BAndCmd::help() const { +void BAndCmd::help() const { cout << setw(20) << left << "BAND: " << "BDD And" << endl; } @@ -240,14 +235,12 @@ BOrCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BOrCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BOR <(string varName)> <(string bddName)>..." - << endl; +void BOrCmd::usage(const bool& verbose) const { + cout << "Usage: BOR <(string varName)> <(string bddName)>..." + << endl; } -void -BOrCmd::help() const { +void BOrCmd::help() const { cout << setw(20) << left << "BOR: " << "BDD Or" << endl; } @@ -282,14 +275,12 @@ BNandCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BNandCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BNAND <(string varName)> <(string bddName)>..." - << endl; +void BNandCmd::usage(const bool& verbose) const { + cout << "Usage: BNAND <(string varName)> <(string bddName)>..." + << endl; } -void -BNandCmd::help() const { +void BNandCmd::help() const { cout << setw(20) << left << "BNAND: " << "BDD Nand" << endl; } @@ -324,14 +315,12 @@ BNorCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BNorCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BNOR <(string varName)> <(string bddName)>..." - << endl; +void BNorCmd::usage(const bool& verbose) const { + cout << "Usage: BNOR <(string varName)> <(string bddName)>..." + << endl; } -void -BNorCmd::help() const { +void BNorCmd::help() const { cout << setw(20) << left << "BNOR: " << "BDD Nor" << endl; } @@ -365,14 +354,12 @@ BXorCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BXorCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BXOR <(string varName)> <(string bddName)>..." - << endl; +void BXorCmd::usage(const bool& verbose) const { + cout << "Usage: BXOR <(string varName)> <(string bddName)>..." + << endl; } -void -BXorCmd::help() const { +void BXorCmd::help() const { cout << setw(20) << left << "BXOR: " << "BDD Xor" << endl; } @@ -407,14 +394,12 @@ BXnorCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BXnorCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BXNOR <(string varName)> <(string bddName)>..." - << endl; +void BXnorCmd::usage(const bool& verbose) const { + cout << "Usage: BXNOR <(string varName)> <(string bddName)>..." + << endl; } -void -BXnorCmd::help() const { +void BXnorCmd::help() const { cout << setw(20) << left << "BXNOR: " << "BDD Xnor" << endl; } @@ -432,7 +417,8 @@ BCofactorCmd::exec(const string& option) { if (n > 3) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[3]); bool posCof = false; - if (myStrNCmp("-Positive", options[0], 2) == 0) posCof = true; + if (myStrNCmp("-Positive", options[0], 2) == 0) + posCof = true; else if (myStrNCmp("-Negative", options[0], 2) != 0) return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); @@ -448,14 +434,12 @@ BCofactorCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BCofactorCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BCOFactor <-Positive | -Negative> <(string " - "varName)> <(string bddName)>\n"; +void BCofactorCmd::usage(const bool& verbose) const { + cout << "Usage: BCOFactor <-Positive | -Negative> <(string " + "varName)> <(string bddName)>\n"; } -void -BCofactorCmd::help() const { +void BCofactorCmd::help() const { cout << setw(20) << left << "BCOFactor: " << "Retrieve BDD cofactor\n"; } @@ -488,14 +472,12 @@ BExistCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BExistCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BEXist <(size_t level)> <(string varName)> " - "<(string bddName)>\n"; +void BExistCmd::usage(const bool& verbose) const { + cout << "Usage: BEXist <(size_t level)> <(string varName)> " + "<(string bddName)>\n"; } -void -BExistCmd::help() const { +void BExistCmd::help() const { cout << setw(20) << left << "BEXist: " << "Perform BDD existential quantification\n"; } @@ -539,14 +521,12 @@ BCompareCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BCompareCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BCOMpare <(string bddName)> <(string bddName)>" - << endl; +void BCompareCmd::usage(const bool& verbose) const { + cout << "Usage: BCOMpare <(string bddName)> <(string bddName)>" + << endl; } -void -BCompareCmd::help() const { +void BCompareCmd::help() const { cout << setw(20) << left << "BCOMpare: " << "BDD comparison" << endl; } @@ -582,15 +562,13 @@ BSimulateCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BSimulateCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) +void BSimulateCmd::usage(const bool& verbose) const { + cout << "Usage: BSIMulate <(string bddName)> <(bit_string inputPattern)>" << endl; } -void -BSimulateCmd::help() const { +void BSimulateCmd::help() const { cout << setw(20) << left << "BSIMulate: " << "BDD simulation" << endl; } @@ -607,8 +585,8 @@ BReportCmd::exec(const string& option) { if (options.empty()) return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, ""); - bool doFile = false, doAddr = false, doRefCount = false; - string bddNodeVName, fileName; + bool doFile = false, doAddr = false, doRefCount = false; + string bddNodeVName, fileName; BddNodeV bnode; for (size_t i = 0, n = options.size(); i < n; ++i) { if (myStrNCmp("-File", options[i], 2) == 0) { @@ -648,7 +626,8 @@ BReportCmd::exec(const string& option) { if (!ofs) return GVCmdExec::errorOption(GV_CMD_OPT_FOPEN_FAIL, fileName); ofs << bnode << endl; - } else cout << bnode << endl; + } else + cout << bnode << endl; // always set to false afterwards BddNodeV::_debugBddAddr = false; @@ -657,15 +636,13 @@ BReportCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BReportCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) +void BReportCmd::usage(const bool& verbose) const { + cout << "Usage: BREPort <(string bddName)> [-ADDRess] [-REFcount]\n " << " [-File <(string fileName)>]" << endl; } -void -BReportCmd::help() const { +void BReportCmd::help() const { cout << setw(20) << left << "BREPort: " << "BDD report node" << endl; } @@ -694,14 +671,11 @@ BDrawCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -BDrawCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BDRAW <(string bddName)> <(string fileName)>" - << endl; +void BDrawCmd::usage(const bool& verbose) const { + cout << "Usage: BDRAW <(string bddName)> <(string fileName)>" << endl; } -void -BDrawCmd::help() const { +void BDrawCmd::help() const { cout << setw(20) << left << "BDRAW: " << "BDD graphic draw" << endl; } @@ -711,7 +685,6 @@ BDrawCmd::help() const { //---------------------------------------------------------------------- GVCmdExecStatus BSetOrderCmd::exec(const string& option) { - // if(!valid()) return GV_CMD_EXEC_ERROR; if (setBddOrder) { gvMsg(GV_MSG_WAR) << "BDD Variable Order Has Been Set !!" << endl; return GV_CMD_EXEC_ERROR; @@ -724,25 +697,26 @@ BSetOrderCmd::exec(const string& option) { return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[1]); } string token = options[0]; - bool file = false; - if (myStrNCmp("-File", token, 2) == 0) file = true; - else if (myStrNCmp("-RFile", token, 3) == 0) file = false; - else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); + bool file = false; + if (myStrNCmp("-File", token, 2) == 0) + file = true; + else if (myStrNCmp("-RFile", token, 3) == 0) + file = false; + else + return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); bddMgrV->restart(); - // V3NtkHandler* const handler = v3Handler.getCurHandler(); - setBddOrder = gvNtkMgr->setBddOrder(file); + setBddOrder = cirMgr->setBddOrder(file); if (!setBddOrder) gvMsg(GV_MSG_ERR) << "Set BDD Variable Order Failed !!" << endl; - else gvMsg(GV_MSG_IFO) << "Set BDD Variable Order Succeed !!" << endl; + else + cout << "Set BDD Variable Order Succeed !!" << endl; return GV_CMD_EXEC_DONE; } -void -BSetOrderCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BSETOrder < -File | -RFile >" << endl; +void BSetOrderCmd::usage(const bool& verbose) const { + cout << "Usage: BSETOrder < -File | -RFile >" << endl; } -void -BSetOrderCmd::help() const { +void BSetOrderCmd::help() const { cout << setw(20) << left << "BSETOrder: " << "Set BDD variable Order From Circuit." << endl; } @@ -765,51 +739,48 @@ BConstructCmd::exec(const string& option) { return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[2]); } - bool isNet = false, isOutput = false; - if (myStrNCmp("-All", options[0], 2) == 0) gvNtkMgr->buildNtkBdd(); - else if (myStrNCmp("-Netid", options[0], 2) == 0) isNet = true; - else if (myStrNCmp("-Output", options[0], 2) == 0) isOutput = true; - else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); - if (isOutput || isNet) { + bool isGate = false, isOutput = false; + if (myStrNCmp("-All", options[0], 2) == 0) + cirMgr->buildNtkBdd(); + else if (myStrNCmp("-Gateid", options[0], 2) == 0) + isGate = true; + else if (myStrNCmp("-Output", options[0], 2) == 0) + isOutput = true; + else + return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); + if (isOutput || isGate) { if (options.size() != 2) return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, options[0]); - int num = 0; - GVNetId netId; + int num = 0; + CirGate* gate; if (!myStr2Int(options[1], num) || (num < 0)) return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); - if (isNet) { - if ((unsigned)num >= gvNtkMgr->getNetSize()) { - gvMsg(GV_MSG_ERR) - << "Net with Id " << num - << " does NOT Exist in Current Ntk !!" << endl; + if (isGate) { + if ((unsigned)num >= cirMgr->getNumTots()) { + gvMsg(GV_MSG_ERR) << "Gate with Id " << num << " does NOT Exist in Current Cir !!" << endl; return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); } - netId = GVNetId::makeNetId(num, 0, gvNtkMgr->getGateType(gvNtkMgr->getGVNetId(num))); + gate = cirMgr->getGate(num); } else if (isOutput) { - if ((unsigned)num >= gvNtkMgr->getOutputSize()) { - gvMsg(GV_MSG_ERR) - << "Output with Index " << num - << " does NOT Exist in Current Ntk !!" << endl; + if ((unsigned)num >= cirMgr->getNumPOs()) { + gvMsg(GV_MSG_ERR) << "Output with Index " << num << " does NOT Exist in Current Cir !!" << endl; return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); } - netId = gvNtkMgr->getOutput(num); + gate = cirMgr->getPo(num); } - gvNtkMgr->buildBdd(netId); + cirMgr->buildBdd(gate); } return GV_CMD_EXEC_DONE; } -void -BConstructCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BConstruct <-Netid | -Output < " - "outputIndex > | -All > " - << endl; +void BConstructCmd::usage(const bool& verbose) const { + cout << "Usage: BConstruct <-Gateid | -Output | -All > " + << endl; } -void -BConstructCmd::help() const { +void BConstructCmd::help() const { cout << setw(20) << left << "BConstruct: " << "Build BDD From Current Design." << endl; } diff --git a/src/bdd/bddCmd.h b/src/bdd/bddCmd.h index efd38418..3508eccd 100644 --- a/src/bdd/bddCmd.h +++ b/src/bdd/bddCmd.h @@ -3,11 +3,11 @@ PackageName [ ] Synopsis [ Define classes for BDD commands ] Author [ Chung-Yang (Ric) Huang, Cheng-Yin Wu ] - Copyright [ Copyleft(c) 2005-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#ifndef BDD_CMD_H -#define BDD_CMD_H +#pragma once + #include "gvCmdMgr.h" @@ -32,4 +32,4 @@ GV_COMMAND(BDrawCmd, GV_CMD_TYPE_BDD); GV_COMMAND(BSetOrderCmd, GV_CMD_TYPE_BDD); GV_COMMAND(BConstructCmd, GV_CMD_TYPE_BDD); -#endif // BDD_CMD_H + diff --git a/src/bdd/bddMgrV.cpp b/src/bdd/bddMgrV.cpp index 3ff9d4ba..c0355baf 100644 --- a/src/bdd/bddMgrV.cpp +++ b/src/bdd/bddMgrV.cpp @@ -3,15 +3,16 @@ PackageName [ ] Synopsis [ BDD Manager functions ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2005-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ +#include "bddMgrV.h" + +#include #include #include -#include + #include "bddNodeV.h" -#include "bddMgrV.h" -// #include "v3StrUtil.h" #include "util.h" using namespace std; @@ -19,7 +20,7 @@ using namespace std; //---------------------------------------------------------------------- // Global variables //---------------------------------------------------------------------- -BddMgrV* bddMgrV = 0; // new BddMgrV; +BddMgrV* bddMgrV = 0; // new BddMgrV; //---------------------------------------------------------------------- // External functions @@ -28,22 +29,22 @@ BddMgrV* bddMgrV = 0; // new BddMgrV; //---------------------------------------------------------------------- // static functions //---------------------------------------------------------------------- -static void swapBddNodeV(BddNodeV& f, BddNodeV& g) -{ - BddNodeV tmp = f; f = g; g = tmp; +static void swapBddNodeV(BddNodeV& f, BddNodeV& g) { + BddNodeV tmp = f; + f = g; + g = tmp; } //---------------------------------------------------------------------- // helper functions //---------------------------------------------------------------------- -BddNodeV getBddNodeV(const string& bddName) -{ - int id; - //if (v3Str2Int(bddName, id)) // bddName is an ID - if (myStr2Int(bddName, id)) // bddName is an ID - return bddMgrV->getBddNodeV(id); - else // bddNameis a name - return bddMgrV->getBddNodeV(bddName); +BddNodeV getBddNodeV(const string& bddName) { + int id; + // if (v3Str2Int(bddName, id)) // bddName is an ID + if (myStr2Int(bddName, id)) // bddName is an ID + return bddMgrV->getBddNodeV(id); + else // bddNameis a name + return bddMgrV->getBddNodeV(bddName); } //---------------------------------------------------------------------- @@ -52,160 +53,168 @@ BddNodeV getBddNodeV(const string& bddName) // _level = 0 ==> const 1 & const 0 // _level = 1 ~ nin ==> supports // -void -BddMgrV::init(size_t nin, size_t h, size_t c) -{ - reset(); - _uniqueTable.init(h); - _computedTable.init(c); - - // This must be called first - BddNodeV::setBddMgrV(this); - BddNodeVInt::_terminal = uniquify(0, 0, 0); - BddNodeV::_one = BddNodeV(BddNodeVInt::_terminal, BDD_POS_EDGEV); - BddNodeV::_zero = BddNodeV(BddNodeVInt::_terminal, BDD_NEG_EDGEV); - - _supports.reserve(nin+1); - _supports.push_back(BddNodeV::_one); - for (size_t i = 1; i <= nin; ++i) - _supports.push_back(BddNodeV(BddNodeV::_one(), BddNodeV::_zero(), i)); +void BddMgrV::init(size_t nin, size_t h, size_t c) { + reset(); + _uniqueTable.init(h); + _computedTable.init(c); + + // This must be called first + BddNodeV::setBddMgrV(this); + BddNodeVInt::_terminal = uniquify(0, 0, 0); + BddNodeV::_one = BddNodeV(BddNodeVInt::_terminal, BDD_POS_EDGEV); + BddNodeV::_zero = BddNodeV(BddNodeVInt::_terminal, BDD_NEG_EDGEV); + + _supports.reserve(nin + 1); + _supports.push_back(BddNodeV::_one); + for (size_t i = 1; i <= nin; ++i) + _supports.push_back(BddNodeV(BddNodeV::_one(), BddNodeV::_zero(), i)); } // Called by the BSETOrder command -void -BddMgrV::restart() -{ - size_t nin = _supports.size() - 1; - size_t h = _uniqueTable.numBuckets(); - size_t c = _computedTable.size(); - - init(nin, h, c); +void BddMgrV::restart() { + size_t nin = _supports.size() - 1; + size_t h = _uniqueTable.numBuckets(); + size_t c = _computedTable.size(); + + init(nin, h, c); } // This is a private function called by init() and restart() -void -BddMgrV::reset() -{ - _supports.clear(); - _bddArr.clear(); - _bddMap.clear(); - BddHash::iterator bi = _uniqueTable.begin(); - for (; bi != _uniqueTable.end(); ++bi) - delete (*bi).second; - _uniqueTable.reset(); - _computedTable.reset(); +void BddMgrV::reset() { + _supports.clear(); + _bddArr.clear(); + _bddMap.clear(); + BddHash::iterator bi = _uniqueTable.begin(); + for (; bi != _uniqueTable.end(); ++bi) + delete (*bi).second; + _uniqueTable.reset(); + _computedTable.reset(); } // [Note] Remeber to check "isNegEdge" when return BddNodeV!!!!! // BddNodeV -BddMgrV::ite(BddNodeV f, BddNodeV g, BddNodeV h) -{ - bool isNegEdge = false; // should only be flipped by "standardize()" +BddMgrV::ite(BddNodeV f, BddNodeV g, BddNodeV h) { + bool isNegEdge = false; // should only be flipped by "standardize()" #define DO_STD_ITE 1 // NOTE: make it '0' if you haven't done standardize()!! - standardize(f, g, h, isNegEdge); - - BddNodeV ret; - - // check terminal cases - if (checkIteTerminal(f, g, h, ret)) { - if (isNegEdge) ret = ~ret; - return ret; // no need to update tables - } - - // check computed table - // based on your definition of BddCacheKey, - // instantiate a BddCacheKey k (i.e. pass in proper data members) - // BddCacheKey k; // Change this line!! - BddCacheKeyV k(f(), g(), h()); - size_t ret_t; - if (_computedTable.read(k, ret_t)) { - if (isNegEdge) ret_t = ret_t ^ BDD_NEG_EDGEV; - return ret_t; - } - - // check top varaible - unsigned v = f.getLevel(); - if (g.getLevel() > v) - v = g.getLevel(); - if (h.getLevel() > v) - v = h.getLevel(); - - // recursion - BddNodeV fl = f.getLeftCofactor(v), - gl = g.getLeftCofactor(v), - hl = h.getLeftCofactor(v); - BddNodeV t = ite(fl, gl, hl); - - BddNodeV fr = f.getRightCofactor(v), - gr = g.getRightCofactor(v), - hr = h.getRightCofactor(v); - BddNodeV e = ite(fr, gr, hr); - - // get result - if (t == e) { - // update computed table - _computedTable.write(k, t()); - if (isNegEdge) t = ~t; - return t; - } - - // move bubble if necessary... ==> update isNedEdge - bool moveBubble = t.isNegEdge(); + standardize(f, g, h, isNegEdge); + + BddNodeV ret; + + // check terminal cases + if (checkIteTerminal(f, g, h, ret)) { + if (isNegEdge) ret = ~ret; + return ret; // no need to update tables + } + + // check computed table + // based on your definition of BddCacheKey, + // instantiate a BddCacheKey k (i.e. pass in proper data members) + // BddCacheKey k; // Change this line!! + BddCacheKeyV k(f(), g(), h()); + size_t ret_t; + if (_computedTable.read(k, ret_t)) { + if (isNegEdge) ret_t = ret_t ^ BDD_NEG_EDGEV; + return ret_t; + } + + // check top varaible + unsigned v = f.getLevel(); + if (g.getLevel() > v) + v = g.getLevel(); + if (h.getLevel() > v) + v = h.getLevel(); + + // recursion + BddNodeV fl = f.getLeftCofactor(v), + gl = g.getLeftCofactor(v), + hl = h.getLeftCofactor(v); + BddNodeV t = ite(fl, gl, hl); + + BddNodeV fr = f.getRightCofactor(v), + gr = g.getRightCofactor(v), + hr = h.getRightCofactor(v); + BddNodeV e = ite(fr, gr, hr); + + // get result + if (t == e) { + // update computed table + _computedTable.write(k, t()); + if (isNegEdge) t = ~t; + return t; + } + + // move bubble if necessary... ==> update isNedEdge + bool moveBubble = t.isNegEdge(); #if DO_STD_ITE - assert(!moveBubble); + assert(!moveBubble); #else - if (moveBubble) { - t = ~t; e = ~e; - } + if (moveBubble) { + t = ~t; + e = ~e; + } #endif - // check unique table - BddNodeVInt* ni = uniquify(t(), e(), v); - ret_t = size_t(ni); + // check unique table + BddNodeVInt* ni = uniquify(t(), e(), v); + ret_t = size_t(ni); #if !(DO_STD_ITE) - if (moveBubble) ret_t = ret_t ^ BDD_NEG_EDGEV; + if (moveBubble) ret_t = ret_t ^ BDD_NEG_EDGEV; #endif - // update computed table - _computedTable.write(k, ret_t); - if (isNegEdge) - ret_t = ret_t ^ BDD_NEG_EDGEV; - return ret_t; + // update computed table + _computedTable.write(k, ret_t); + if (isNegEdge) + ret_t = ret_t ^ BDD_NEG_EDGEV; + return ret_t; } -void -BddMgrV::standardize(BddNodeV &f, BddNodeV &g, BddNodeV &h, bool &isNegEdge) -{ - // (1) Identical/Complement rules - if (f == g) g = BddNodeV::_one; - else if (f == ~g) g = BddNodeV::_zero; - else if (f == h) h = BddNodeV::_zero; - else if (f == ~h) h = BddNodeV::_one; - - // (2) Symmetrical rules - if (g == BddNodeV::_one) { - if (f > h) swapBddNodeV(f, h); - } - else if (g == BddNodeV::_zero) { - if (f > h) { swapBddNodeV(f, h); f = ~f; h = ~h; } - } - else if (h == BddNodeV::_one) { - if (f > g) { swapBddNodeV(f, g); f = ~f; g = ~g; } - } - else if (h == BddNodeV::_zero) { - if (f > g) swapBddNodeV(f, g); - } - else if (g == ~h) { - if (f > g) { swapBddNodeV(f, g); h = ~g; } - } - - // (3) Complement edge rules - // ==> both f and g will be posEdge afterwards - if (f.isNegEdge()) { swapBddNodeV(g, h); f = ~f; } - if (g.isNegEdge()) { - g = ~g; h = ~h; isNegEdge = !isNegEdge; - } +void BddMgrV::standardize(BddNodeV& f, BddNodeV& g, BddNodeV& h, bool& isNegEdge) { + // (1) Identical/Complement rules + if (f == g) + g = BddNodeV::_one; + else if (f == ~g) + g = BddNodeV::_zero; + else if (f == h) + h = BddNodeV::_zero; + else if (f == ~h) + h = BddNodeV::_one; + + // (2) Symmetrical rules + if (g == BddNodeV::_one) { + if (f > h) swapBddNodeV(f, h); + } else if (g == BddNodeV::_zero) { + if (f > h) { + swapBddNodeV(f, h); + f = ~f; + h = ~h; + } + } else if (h == BddNodeV::_one) { + if (f > g) { + swapBddNodeV(f, g); + f = ~f; + g = ~g; + } + } else if (h == BddNodeV::_zero) { + if (f > g) swapBddNodeV(f, g); + } else if (g == ~h) { + if (f > g) { + swapBddNodeV(f, g); + h = ~g; + } + } + + // (3) Complement edge rules + // ==> both f and g will be posEdge afterwards + if (f.isNegEdge()) { + swapBddNodeV(g, h); + f = ~f; + } + if (g.isNegEdge()) { + g = ~g; + h = ~h; + isNegEdge = !isNegEdge; + } } // Check if triplet (l, r, i) is in _uniqueTable, @@ -213,73 +222,73 @@ BddMgrV::standardize(BddNodeV &f, BddNodeV &g, BddNodeV &h, bool &isNegEdge) // else, return the hashed one // BddNodeVInt* -BddMgrV::uniquify(size_t l, size_t r, unsigned i) -{ - BddNodeVInt* n = 0; - BddHashKeyV k(l, r, i); - if (!_uniqueTable.check(k, n)) { - n = new BddNodeVInt(l, r, i); - _uniqueTable.forceInsert(k, n); - } - return n; +BddMgrV::uniquify(size_t l, size_t r, unsigned i) { + BddNodeVInt* n = 0; + BddHashKeyV k(l, r, i); + if (!_uniqueTable.check(k, n)) { + n = new BddNodeVInt(l, r, i); + _uniqueTable.forceInsert(k, n); + } + return n; } // return false if _bddArr[id] has aleady been inserted -bool -BddMgrV::addBddNodeV(unsigned id, size_t n) -{ - if (id >= _bddArr.size()) { - unsigned origSize = _bddArr.size(); - _bddArr.resize(id+1); - for(unsigned i = origSize; i < _bddArr.size(); ++i) - _bddArr[i] = 0; - } else if (_bddArr[id] != 0) - return false; - _bddArr[id] = n; - return true; +bool BddMgrV::addBddNodeV(unsigned id, size_t n) { + if (id >= _bddArr.size()) { + unsigned origSize = _bddArr.size(); + _bddArr.resize(id + 1); + for (unsigned i = origSize; i < _bddArr.size(); ++i) + _bddArr[i] = 0; + } else if (_bddArr[id] != 0) + return false; + _bddArr[id] = n; + return true; } // return 0 if not in the map!! BddNodeV -BddMgrV::getBddNodeV(unsigned id) const -{ - if (id >= _bddArr.size()) - return size_t(0); - return _bddArr[id]; +BddMgrV::getBddNodeV(unsigned id) const { + if (id >= _bddArr.size()) + return size_t(0); + return _bddArr[id]; } // return false if str is already in the _bddMap!! -bool -BddMgrV::addBddNodeV(const string& str, size_t n) -{ - return _bddMap.insert(BddMapPair(str, n)).second; +bool BddMgrV::addBddNodeV(const string& str, size_t n) { + return _bddMap.insert(BddMapPair(str, n)).second; } -void -BddMgrV::forceAddBddNodeV(const string& str, size_t n) -{ - _bddMap[str] = n; +void BddMgrV::forceAddBddNodeV(const string& str, size_t n) { + _bddMap[str] = n; } // return 0 if not in the map!! BddNodeV -BddMgrV::getBddNodeV(const string& name) const -{ - BddMapConstIter bi = _bddMap.find(name); - if (bi == _bddMap.end()) return size_t(0); - return (*bi).second; +BddMgrV::getBddNodeV(const string& name) const { + BddMapConstIter bi = _bddMap.find(name); + if (bi == _bddMap.end()) return size_t(0); + return (*bi).second; } // return true if terminal case -bool -BddMgrV::checkIteTerminal -(const BddNodeV& f, const BddNodeV& g, const BddNodeV& h, BddNodeV& n) -{ - if (g == h) { n = g; return true; } - if (f == BddNodeV::_one) { n = g; return true; } - if (f == BddNodeV::_zero) { n = h; return true; } - if (g == BddNodeV::_one && h == BddNodeV::_zero) { n = f; return true; } - return false; +bool BddMgrV::checkIteTerminal(const BddNodeV& f, const BddNodeV& g, const BddNodeV& h, BddNodeV& n) { + if (g == h) { + n = g; + return true; + } + if (f == BddNodeV::_one) { + n = g; + return true; + } + if (f == BddNodeV::_zero) { + n = h; + return true; + } + if (g == BddNodeV::_one && h == BddNodeV::_zero) { + n = f; + return true; + } + return false; } //---------------------------------------------------------------------- @@ -289,48 +298,43 @@ BddMgrV::checkIteTerminal // // ==> return -1 if pattern is not legal // ==> return 0/1 for evaluated result -int -BddMgrV::evalCube(const BddNodeV& node, const string& pattern) const -{ - size_t v = node.getLevel(); - size_t n = pattern.size(); - if (n < v) { - cerr << "Error: " << pattern << " too short!!" << endl; - return -1; - } - - BddNodeV next = node; - for (int i = v - 1; i >= 0; --i) { - char c = pattern[i]; - if (c == '1') - next = next.getLeftCofactor(i+1); - else if (c == '0') - next = next.getRightCofactor(i+1); - else { - cerr << "Illegal pattern: " << c << "(" << i << ")" << endl; - return -1; - } - } - return (next == BddNodeV::_one)? 1 : 0; +int BddMgrV::evalCube(const BddNodeV& node, const string& pattern) const { + size_t v = node.getLevel(); + size_t n = pattern.size(); + if (n < v) { + cout << "Error: " << pattern << " too short!!" << endl; + return -1; + } + + BddNodeV next = node; + for (int i = v - 1; i >= 0; --i) { + char c = pattern[i]; + if (c == '1') + next = next.getLeftCofactor(i + 1); + else if (c == '0') + next = next.getRightCofactor(i + 1); + else { + cout << "Illegal pattern: " << c << "(" << i << ")" << endl; + return -1; + } + } + return (next == BddNodeV::_one) ? 1 : 0; } -bool -BddMgrV::drawBdd(const string& name, const string& fileName) const -{ - BddNodeV node = ::getBddNodeV(name); - if (node() == 0) { - cerr << "Error: \"" << name << "\" is not a legal BDD node!!" << endl; - return false; - } +bool BddMgrV::drawBdd(const string& name, const string& fileName) const { + BddNodeV node = ::getBddNodeV(name); + if (node() == 0) { + cout << "Error: \"" << name << "\" is not a legal BDD node!!" << endl; + return false; + } - ofstream ofile(fileName.c_str()); - if (!ofile) { - cerr << "Error: cannot open file \"" << fileName << "\"!!" << endl; - return false; - } + ofstream ofile(fileName.c_str()); + if (!ofile) { + cout << "Error: cannot open file \"" << fileName << "\"!!" << endl; + return false; + } - node.drawBdd(name, ofile); + node.drawBdd(name, ofile); - return true; + return true; } - diff --git a/src/bdd/bddMgrV.h b/src/bdd/bddMgrV.h index 53156619..463bb21a 100644 --- a/src/bdd/bddMgrV.h +++ b/src/bdd/bddMgrV.h @@ -3,153 +3,151 @@ PackageName [ ] Synopsis [ Define BDD Manager ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2005-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#ifndef BDD_MGRV_H -#define BDD_MGRV_H +#pragma once + #include -#include "myHash.h" + #include "bddNodeV.h" +#include "myHashMap.h" using namespace std; class BddNodeV; -typedef vector BddArr; -typedef map BddMap; -typedef pair BddMapPair; -typedef map::const_iterator BddMapConstIter; +typedef vector BddArr; +typedef map BddMap; +typedef pair BddMapPair; +typedef map::const_iterator BddMapConstIter; extern BddMgrV* bddMgrV; -class BddHashKeyV -{ +class BddHashKeyV { public: - // HINT: define constructor(s) - BddHashKeyV(size_t l, size_t r, unsigned i) : _l(l), _r(r), _i(i) {} + // HINT: define constructor(s) + BddHashKeyV(size_t l, size_t r, unsigned i) : _l(l), _r(r), _i(i) {} - // HINT: implement "()" and "==" operators - // Get a size_t number; - // ==> to get bucket number, need to % _numBuckers in Hash - size_t operator() () const { return ((_l << 3) + (_r << 3) + _i); } + // HINT: implement "()" and "==" operators + // Get a size_t number; + // ==> to get bucket number, need to % _numBuckers in Hash + size_t operator()() const { return ((_l << 3) + (_r << 3) + _i); } - bool operator == (const BddHashKeyV& k) { - return (_l == k._l) && (_r == k._r) && (_i == k._i); } + bool operator==(const BddHashKeyV& k) { + return (_l == k._l) && (_r == k._r) && (_i == k._i); + } private: - // HINT: define your own data members - size_t _l; - size_t _r; - unsigned _i; + // HINT: define your own data members + size_t _l; + size_t _r; + unsigned _i; }; -class BddCacheKeyV -{ +class BddCacheKeyV { public: - // HINT: define constructor(s) - BddCacheKeyV() {} - BddCacheKeyV(size_t f, size_t g, size_t h) : _f(f), _g(g), _h(h) {} + // HINT: define constructor(s) + BddCacheKeyV() {} + BddCacheKeyV(size_t f, size_t g, size_t h) : _f(f), _g(g), _h(h) {} - // HINT: implement "()" and "==" operators - // Get a size_t number; - // ==> to get cache address, need to % _size in Cache - size_t operator() () const { return ((_f << 3)+(_g << 3)+(_h << 3)); } + // HINT: implement "()" and "==" operators + // Get a size_t number; + // ==> to get cache address, need to % _size in Cache + size_t operator()() const { return ((_f << 3) + (_g << 3) + (_h << 3)); } - bool operator == (const BddCacheKeyV& k) const { - return (_f == k._f) && (_g == k._g) && (_h == k._h); } + bool operator==(const BddCacheKeyV& k) const { + return (_f == k._f) && (_g == k._g) && (_h == k._h); + } private: - // HINT: define your own data members - size_t _f; - size_t _g; - size_t _h; + // HINT: define your own data members + size_t _f; + size_t _g; + size_t _h; }; -class BddMgrV -{ -typedef Hash BddHash; -typedef Cache BddCache; +class BddMgrV { + typedef HashMap BddHash; + typedef Cache BddCache; public: - BddMgrV(size_t nin = 128, size_t h = 8009, size_t c = 30011) - { init(nin, h, c); } - ~BddMgrV() { reset(); } - - void init(size_t nin, size_t h, size_t c); - void restart(); - - // for building BDDs - BddNodeV ite(BddNodeV f, BddNodeV g, BddNodeV h); - - // for _supports - const BddNodeV& getSupport(size_t i) const { return _supports[i]; } - size_t getNumSupports() const { return _supports.size(); } - - // for _uniqueTable - BddNodeVInt* uniquify(size_t l, size_t r, unsigned i); - - // for _bddArr: access by unsigned (ID) - bool addBddNodeV(unsigned id, size_t nodeV); - BddNodeV getBddNodeV(unsigned id) const; - - // for _bddMap: access by string - bool addBddNodeV(const string& nodeName, size_t nodeV); - void forceAddBddNodeV(const string& nodeName, size_t nodeV); - BddNodeV getBddNodeV(const string& nodeName) const; - - // Applications - int evalCube(const BddNodeV& node, const string& vector) const; - bool drawBdd(const string& nodeName, const string& dotFile) const; - - // For prove - void buildPInitialState(); - void buildPTransRelation(); - void buildPImage( int level ); - BddNodeV restrict ( const BddNodeV&, const BddNodeV&); - void runPCheckProperty( const string &name, BddNodeV property ); - bool isPFixed() const { return _isFixed; } - BddNodeV getPInitState() const { return _initState; } - BddNodeV getPTr() const { return _tr; } - BddNodeV getPTri() const { return _tri; } - BddNodeV getPReachState() const { - return ( _reachStates.empty() ) ? _initState : _reachStates.back(); } - void resetProof() {} - BddNodeV find_ns(BddNodeV cs); - BddNodeV ns_to_cs (BddNodeV ns); - // string getNsBdd(size_t t) { - // map::iterator it; - // for (it=_bddMap.begin(); it!=_bddMap.end(); ++it) { - // if(it->second == t) return it->first; break; - // } - // return ""; - // } - - + BddMgrV(size_t nin = 128, size_t h = 8009, size_t c = 30011) { init(nin, h, c); } + ~BddMgrV() { reset(); } + + void init(size_t nin, size_t h, size_t c); + void restart(); + + // for building BDDs + BddNodeV ite(BddNodeV f, BddNodeV g, BddNodeV h); + + // for _supports + const BddNodeV& getSupport(size_t i) const { return _supports[i]; } + size_t getNumSupports() const { return _supports.size(); } + + // for _uniqueTable + BddNodeVInt* uniquify(size_t l, size_t r, unsigned i); + + // for _bddArr: access by unsigned (ID) + bool addBddNodeV(unsigned id, size_t nodeV); + BddNodeV getBddNodeV(unsigned id) const; + + // for _bddMap: access by string + bool addBddNodeV(const string& nodeName, size_t nodeV); + void forceAddBddNodeV(const string& nodeName, size_t nodeV); + BddNodeV getBddNodeV(const string& nodeName) const; + + // Applications + int evalCube(const BddNodeV& node, const string& vector) const; + bool drawBdd(const string& nodeName, const string& dotFile) const; + + // For prove + void buildPInitialState(); + void buildPTransRelation(); + void buildPImage(int level); + BddNodeV restrict(const BddNodeV&, const BddNodeV&); + void runPCheckProperty(const string& name, BddNodeV property); + bool isPFixed() const { return _isFixed; } + BddNodeV getPInitState() const { return _initState; } + BddNodeV getPTr() const { return _tr; } + BddNodeV getPTri() const { return _tri; } + BddNodeV getPReachState() const { + return (_reachStates.empty()) ? _initState : _reachStates.back(); + } + void resetProof() {} + BddNodeV find_ns(BddNodeV cs); + BddNodeV ns_to_cs(BddNodeV ns); + // string getNsBdd(size_t t) { + // map::iterator it; + // for (it=_bddMap.begin(); it!=_bddMap.end(); ++it) { + // if(it->second == t) return it->first; break; + // } + // return ""; + // } private: - // level = 0: const 1; - // level = 1: lowest input variable - // level = nin: highest input variable - vector _supports; - BddHash _uniqueTable; - BddCache _computedTable; - - BddArr _bddArr; - BddMap _bddMap; - - // For prove - bool _isFixed; - BddNodeV _initState; - BddNodeV _tr; - BddNodeV _tri; - vector _reachStates; - - void reset(); - bool checkIteTerminal(const BddNodeV&, const BddNodeV&, const BddNodeV&, - BddNodeV&); - void standardize(BddNodeV &f, BddNodeV &g, BddNodeV &h, bool &isNegEdge); + // level = 0: const 1; + // level = 1: lowest input variable + // level = nin: highest input variable + vector _supports; + BddHash _uniqueTable; + BddCache _computedTable; + + BddArr _bddArr; + BddMap _bddMap; + + // For prove + bool _isFixed; + BddNodeV _initState; + BddNodeV _tr; + BddNodeV _tri; + vector _reachStates; + + void reset(); + bool checkIteTerminal(const BddNodeV&, const BddNodeV&, const BddNodeV&, + BddNodeV&); + void standardize(BddNodeV& f, BddNodeV& g, BddNodeV& h, bool& isNegEdge); }; -#endif // BDD_MGRV_H + diff --git a/src/bdd/bddNodeV.cpp b/src/bdd/bddNodeV.cpp index 2673e267..a4e0cfd4 100644 --- a/src/bdd/bddNodeV.cpp +++ b/src/bdd/bddNodeV.cpp @@ -3,259 +3,241 @@ PackageName [ ] Synopsis [ Define BDD Node member functions ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2005-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#include -#include +#include "bddNodeV.h" + #include #include -#include "bddNodeV.h" +#include +#include + #include "bddMgrV.h" // Initialize static data members // -BddMgrV* BddNodeV::_BddMgrV = 0; +BddMgrV* BddNodeV::_BddMgrV = 0; BddNodeVInt* BddNodeVInt::_terminal = 0; BddNodeV BddNodeV::_one; BddNodeV BddNodeV::_zero; -bool BddNodeV::_debugBddAddr = false; +bool BddNodeV::_debugBddAddr = false; bool BddNodeV::_debugRefCount = false; // We check the hash when a new BddNodeVInt is possibly being created -BddNodeV::BddNodeV(size_t l, size_t r, size_t i, BDD_EDGEV_FLAG f) -{ - BddNodeVInt* n = _BddMgrV->uniquify(l, r, i); - // n should not = 0 - assert(n != 0); - _nodeV = size_t(n) + f; - n->incRefCount(); +BddNodeV::BddNodeV(size_t l, size_t r, size_t i, BDD_EDGEV_FLAG f) { + BddNodeVInt* n = _BddMgrV->uniquify(l, r, i); + // n should not = 0 + assert(n != 0); + _nodeV = size_t(n) + f; + n->incRefCount(); } // Copy constructor also needs to increase the _refCount // Need to check if n._nodeV != 0 -BddNodeV::BddNodeV(const BddNodeV& n) : _nodeV(n._nodeV) -{ - BddNodeVInt* t = getBddNodeVInt(); - if (t) - t->incRefCount(); +BddNodeV::BddNodeV(const BddNodeV& n) : _nodeV(n._nodeV) { + BddNodeVInt* t = getBddNodeVInt(); + if (t) + t->incRefCount(); } // This function is called only when n is obtained from uniquify()... // ==> n should not be "0" -BddNodeV::BddNodeV(BddNodeVInt* n, BDD_EDGEV_FLAG f) -{ - assert(n != 0); - _nodeV = size_t(n) + f; - n->incRefCount(); +BddNodeV::BddNodeV(BddNodeVInt* n, BDD_EDGEV_FLAG f) { + assert(n != 0); + _nodeV = size_t(n) + f; + n->incRefCount(); } // Need to check if n._nodeV != 0 -BddNodeV::BddNodeV(size_t v) : _nodeV(v) -{ - BddNodeVInt* n = getBddNodeVInt(); - if (n) - n->incRefCount(); +BddNodeV::BddNodeV(size_t v) : _nodeV(v) { + BddNodeVInt* n = getBddNodeVInt(); + if (n) + n->incRefCount(); } // Need to check if _nodeV != 0 -BddNodeV::~BddNodeV() -{ - BddNodeVInt* n = getBddNodeVInt(); - if (n) - n->decRefCount(); +BddNodeV::~BddNodeV() { + BddNodeVInt* n = getBddNodeVInt(); + if (n) + n->decRefCount(); } const BddNodeV& -BddNodeV::getLeft() const -{ - assert(getBddNodeVInt() != 0); - return getBddNodeVInt()->getLeft(); +BddNodeV::getLeft() const { + assert(getBddNodeVInt() != 0); + return getBddNodeVInt()->getLeft(); } const BddNodeV& -BddNodeV::getRight() const -{ - assert(getBddNodeVInt() != 0); - return getBddNodeVInt()->getRight(); +BddNodeV::getRight() const { + assert(getBddNodeVInt() != 0); + return getBddNodeVInt()->getRight(); } // [Note] i SHOULD NOT < getLevel() BddNodeV -BddNodeV::getLeftCofactor(unsigned i) const -{ - assert(getBddNodeVInt() != 0); - assert(i > 0); - if (i > getLevel()) return (*this); - if (i == getLevel()) - return isNegEdge()? ~getLeft() : getLeft(); - BddNodeV t = getLeft().getLeftCofactor(i); - BddNodeV e = getRight().getLeftCofactor(i); - if (t == e) return isNegEdge()? ~t : t; - BDD_EDGEV_FLAG f = (isNegEdge() ^ t.isNegEdge())? - BDD_NEG_EDGEV: BDD_POS_EDGEV; - if (t.isNegEdge()) { t = ~t; e = ~e; } - return BddNodeV(t(), e(), getLevel(), f); +BddNodeV::getLeftCofactor(unsigned i) const { + assert(getBddNodeVInt() != 0); + assert(i > 0); + if (i > getLevel()) return (*this); + if (i == getLevel()) + return isNegEdge() ? ~getLeft() : getLeft(); + BddNodeV t = getLeft().getLeftCofactor(i); + BddNodeV e = getRight().getLeftCofactor(i); + if (t == e) return isNegEdge() ? ~t : t; + BDD_EDGEV_FLAG f = (isNegEdge() ^ t.isNegEdge()) ? BDD_NEG_EDGEV : BDD_POS_EDGEV; + if (t.isNegEdge()) { + t = ~t; + e = ~e; + } + return BddNodeV(t(), e(), getLevel(), f); } // [Note] i SHOULD NOT < getLevel() BddNodeV -BddNodeV::getRightCofactor(unsigned i) const -{ - assert(getBddNodeVInt() != 0); - assert(i > 0); - if (i > getLevel()) return (*this); - if (i == getLevel()) - return isNegEdge()? ~getRight() : getRight(); - BddNodeV t = getLeft().getRightCofactor(i); - BddNodeV e = getRight().getRightCofactor(i); - if (t == e) return isNegEdge()? ~t : t; - BDD_EDGEV_FLAG f = (isNegEdge() ^ t.isNegEdge())? - BDD_NEG_EDGEV: BDD_POS_EDGEV; - if (t.isNegEdge()) { t = ~t; e = ~e; } - return BddNodeV(t(), e(), getLevel(), f); +BddNodeV::getRightCofactor(unsigned i) const { + assert(getBddNodeVInt() != 0); + assert(i > 0); + if (i > getLevel()) return (*this); + if (i == getLevel()) + return isNegEdge() ? ~getRight() : getRight(); + BddNodeV t = getLeft().getRightCofactor(i); + BddNodeV e = getRight().getRightCofactor(i); + if (t == e) return isNegEdge() ? ~t : t; + BDD_EDGEV_FLAG f = (isNegEdge() ^ t.isNegEdge()) ? BDD_NEG_EDGEV : BDD_POS_EDGEV; + if (t.isNegEdge()) { + t = ~t; + e = ~e; + } + return BddNodeV(t(), e(), getLevel(), f); } unsigned -BddNodeV::getLevel() const -{ - return getBddNodeVInt()->getLevel(); +BddNodeV::getLevel() const { + return getBddNodeVInt()->getLevel(); } unsigned -BddNodeV::getRefCount() const -{ - return getBddNodeVInt()->getRefCount(); +BddNodeV::getRefCount() const { + return getBddNodeVInt()->getRefCount(); } // Note: BddNodeV a = b; // ==> a's original BddNodeVInt's reference count should -- // a's new BddNodeVInt's reference count should ++ BddNodeV& -BddNodeV::operator = (const BddNodeV& n) -{ - BddNodeVInt* t = getBddNodeVInt(); - if (t) - t->decRefCount(); - _nodeV = n._nodeV; - t = getBddNodeVInt(); - if (t) - t->incRefCount(); - return (*this); +BddNodeV::operator=(const BddNodeV& n) { + BddNodeVInt* t = getBddNodeVInt(); + if (t) + t->decRefCount(); + _nodeV = n._nodeV; + t = getBddNodeVInt(); + if (t) + t->incRefCount(); + return (*this); } BddNodeV -BddNodeV::operator & (const BddNodeV& n) const -{ - return _BddMgrV->ite((*this), n, BddNodeV::_zero); +BddNodeV::operator&(const BddNodeV& n) const { + return _BddMgrV->ite((*this), n, BddNodeV::_zero); } BddNodeV& -BddNodeV::operator &= (const BddNodeV& n) -{ - (*this) = (*this) & n; - return (*this); +BddNodeV::operator&=(const BddNodeV& n) { + (*this) = (*this) & n; + return (*this); } BddNodeV -BddNodeV::operator | (const BddNodeV& n) const -{ - return _BddMgrV->ite((*this), BddNodeV::_one, n); +BddNodeV::operator|(const BddNodeV& n) const { + return _BddMgrV->ite((*this), BddNodeV::_one, n); } BddNodeV& -BddNodeV::operator |= (const BddNodeV& n) -{ - (*this) = (*this) | n; - return (*this); +BddNodeV::operator|=(const BddNodeV& n) { + (*this) = (*this) | n; + return (*this); } BddNodeV -BddNodeV::operator ^ (const BddNodeV& n) const -{ - return _BddMgrV->ite((*this), ~n, n); +BddNodeV::operator^(const BddNodeV& n) const { + return _BddMgrV->ite((*this), ~n, n); } BddNodeV& -BddNodeV::operator ^= (const BddNodeV& n) -{ - (*this) = (*this) ^ n; - return (*this); +BddNodeV::operator^=(const BddNodeV& n) { + (*this) = (*this) ^ n; + return (*this); } // (*this) < n iff // (i) level < n.level // (ii) level == n.level && _nodeV < n._nodeV -bool -BddNodeV::operator < (const BddNodeV& n) const -{ - unsigned l1 = getLevel(); - unsigned l2 = n.getLevel(); - return ((l1 < l2) || - ((l1 == l2) && (_nodeV < n._nodeV))); +bool BddNodeV::operator<(const BddNodeV& n) const { + unsigned l1 = getLevel(); + unsigned l2 = n.getLevel(); + return ((l1 < l2) || + ((l1 == l2) && (_nodeV < n._nodeV))); } // (*this) < n iff // (i) level < n.level // (ii) level == n.level && _nodeV <= n._nodeV -bool -BddNodeV::operator <= (const BddNodeV& n) const -{ - unsigned l1 = getLevel(); - unsigned l2 = n.getLevel(); - return ((l1 < l2) || - ((l1 == l2) && (_nodeV <= n._nodeV))); +bool BddNodeV::operator<=(const BddNodeV& n) const { + unsigned l1 = getLevel(); + unsigned l2 = n.getLevel(); + return ((l1 < l2) || + ((l1 == l2) && (_nodeV <= n._nodeV))); } -bool -BddNodeV::isTerminal() const -{ - return (getBddNodeVInt() == BddNodeVInt::_terminal); +bool BddNodeV::isTerminal() const { + return (getBddNodeVInt() == BddNodeVInt::_terminal); } BddNodeV -BddNodeV::exist(unsigned l) const -{ - if (l == 0) return (*this); +BddNodeV::exist(unsigned l) const { + if (l == 0) return (*this); - map existMap; - return existRecur(l, existMap); + map existMap; + return existRecur(l, existMap); } BddNodeV -BddNodeV::existRecur(unsigned l, map& existMap) const -{ - if (isTerminal()) return (*this); - - unsigned thisLevel = getLevel(); - if (l > thisLevel) return (*this); - - map::iterator mi = existMap.find(_nodeV); - if (mi != existMap.end()) return (*mi).second; - - BddNodeV left = getLeftCofactor(thisLevel); - BddNodeV right = getRightCofactor(thisLevel); - if (l == thisLevel) { - BddNodeV res = left | right; - existMap[_nodeV] = res(); - return res; - } - - // l must < getLevel() - bool isNegEdge = false; - BddNodeV t = left.existRecur(l, existMap); - BddNodeV e = right.existRecur(l, existMap); - if (t == e) { - existMap[_nodeV] = t(); - return t; - } - if (t.isNegEdge()) { - t = ~t; e = ~e; isNegEdge = true; - } - BddNodeV res(_BddMgrV->uniquify(t(), e(), thisLevel)); - if (isNegEdge) res = ~res; - existMap[_nodeV] = res(); - return res; +BddNodeV::existRecur(unsigned l, map& existMap) const { + if (isTerminal()) return (*this); + + unsigned thisLevel = getLevel(); + if (l > thisLevel) return (*this); + + map::iterator mi = existMap.find(_nodeV); + if (mi != existMap.end()) return (*mi).second; + + BddNodeV left = getLeftCofactor(thisLevel); + BddNodeV right = getRightCofactor(thisLevel); + if (l == thisLevel) { + BddNodeV res = left | right; + existMap[_nodeV] = res(); + return res; + } + + // l must < getLevel() + bool isNegEdge = false; + BddNodeV t = left.existRecur(l, existMap); + BddNodeV e = right.existRecur(l, existMap); + if (t == e) { + existMap[_nodeV] = t(); + return t; + } + if (t.isNegEdge()) { + t = ~t; + e = ~e; + isNegEdge = true; + } + BddNodeV res(_BddMgrV->uniquify(t(), e(), thisLevel)); + if (isNegEdge) res = ~res; + existMap[_nodeV] = res(); + return res; } // Move the BDD nodes in the cone >= fromLevel to toLevel. @@ -275,302 +257,270 @@ BddNodeV::existRecur(unsigned l, map& existMap) const // no move will be made, and return (*this). // BddNodeV -BddNodeV::nodeMove(unsigned fromLevel, unsigned toLevel, bool& isMoved) const -{ - assert(fromLevel > 1); - if (int(getLevel() - fromLevel) >= abs(int(fromLevel - toLevel)) || +BddNodeV::nodeMove(unsigned fromLevel, unsigned toLevel, bool& isMoved) const { + assert(fromLevel > 1); + if (int(getLevel() - fromLevel) >= abs(int(fromLevel - toLevel)) || containNode(fromLevel - 1, 1)) { - isMoved = false; - return (*this); - } + isMoved = false; + return (*this); + } - isMoved = true; - map moveMap; - return nodeMoveRecur(fromLevel, toLevel, moveMap); + isMoved = true; + map moveMap; + return nodeMoveRecur(fromLevel, toLevel, moveMap); } BddNodeV -BddNodeV::nodeMoveRecur -(unsigned fromLevel, unsigned toLevel, map& moveMap) const -{ - unsigned thisLevel = getLevel(); - //assert(thisLevel >= fromLevel); +BddNodeV::nodeMoveRecur(unsigned fromLevel, unsigned toLevel, map& moveMap) const { + unsigned thisLevel = getLevel(); + // assert(thisLevel >= fromLevel); - map::iterator mi = moveMap.find(_nodeV); - if (mi != moveMap.end()) return (*mi).second; + map::iterator mi = moveMap.find(_nodeV); + if (mi != moveMap.end()) return (*mi).second; - BddNodeV left = getLeft(); - BddNodeV right = getRight(); + BddNodeV left = getLeft(); + BddNodeV right = getRight(); - if (!left.isTerminal()) - left = left.nodeMoveRecur(fromLevel, toLevel, moveMap); - if (!right.isTerminal()) - right = right.nodeMoveRecur(fromLevel, toLevel, moveMap); + if (!left.isTerminal()) + left = left.nodeMoveRecur(fromLevel, toLevel, moveMap); + if (!right.isTerminal()) + right = right.nodeMoveRecur(fromLevel, toLevel, moveMap); - BddNodeVInt *n - = _BddMgrV->uniquify(left(), right(), thisLevel - fromLevel + toLevel); - BddNodeV ret = BddNodeV(size_t(n)); - if (isNegEdge()) ret = ~ret; + BddNodeVInt* n = _BddMgrV->uniquify(left(), right(), thisLevel - fromLevel + toLevel); + BddNodeV ret = BddNodeV(size_t(n)); + if (isNegEdge()) ret = ~ret; - moveMap[_nodeV] = ret(); - return ret; + moveMap[_nodeV] = ret(); + return ret; } // Check if there is any BddNodeV in the cone of level [bLevel, eLevel] // return true if any // -bool -BddNodeV::containNode(unsigned bLevel, unsigned eLevel) const -{ - bool res = containNodeRecur(bLevel, eLevel); - unsetVisitedRecur(); - return res; -} - -bool -BddNodeV::containNodeRecur(unsigned bLevel, unsigned eLevel) const -{ - BddNodeVInt* n = getBddNodeVInt(); - if (n->isVisited()) - return false; - n->setVisited(); - - unsigned thisLevel = getLevel(); - if (thisLevel < bLevel) return false; - if (thisLevel <= eLevel) return true; - - if (getLeft().containNodeRecur(bLevel, eLevel)) return true; - if (getRight().containNodeRecur(bLevel, eLevel)) return true; - - return false; -} - +bool BddNodeV::containNode(unsigned bLevel, unsigned eLevel) const { + bool res = containNodeRecur(bLevel, eLevel); + unsetVisitedRecur(); + return res; +} + +bool BddNodeV::containNodeRecur(unsigned bLevel, unsigned eLevel) const { + BddNodeVInt* n = getBddNodeVInt(); + if (n->isVisited()) + return false; + n->setVisited(); + + unsigned thisLevel = getLevel(); + if (thisLevel < bLevel) return false; + if (thisLevel <= eLevel) return true; + + if (getLeft().containNodeRecur(bLevel, eLevel)) return true; + if (getRight().containNodeRecur(bLevel, eLevel)) return true; + + return false; +} + size_t -BddNodeV::countCube() const -{ - map numCubeMap; - return countCubeRecur(false, numCubeMap); -} +BddNodeV::countCube() const { + map numCubeMap; + return countCubeRecur(false, numCubeMap); +} size_t -BddNodeV::countCubeRecur(bool phase, map& numCubeMap) const -{ - if (isTerminal()) - return ((phase ^ isNegEdge())? 0 : 1); +BddNodeV::countCubeRecur(bool phase, map& numCubeMap) const { + if (isTerminal()) + return ((phase ^ isNegEdge()) ? 0 : 1); - map::iterator mi = numCubeMap.find(_nodeV); - if (mi != numCubeMap.end()) return (*mi).second; + map::iterator mi = numCubeMap.find(_nodeV); + if (mi != numCubeMap.end()) return (*mi).second; - unsigned numCube = 0; - BddNodeV left = getLeft(); - numCube += left.countCubeRecur(phase ^ isNegEdge(), numCubeMap); - BddNodeV right = getRight(); - numCube += right.countCubeRecur(phase ^ isNegEdge(), numCubeMap); + unsigned numCube = 0; + BddNodeV left = getLeft(); + numCube += left.countCubeRecur(phase ^ isNegEdge(), numCubeMap); + BddNodeV right = getRight(); + numCube += right.countCubeRecur(phase ^ isNegEdge(), numCubeMap); - numCubeMap[_nodeV] = numCube; - return numCube; + numCubeMap[_nodeV] = numCube; + return numCube; } BddNodeV -BddNodeV::getCube(size_t ith) const -{ - ith %= countCube(); - BddNodeV res = BddNodeV::_one; - size_t idx = 0; - getCubeRecur(false, idx, ith, res); - return res; -} - +BddNodeV::getCube(size_t ith) const { + ith %= countCube(); + BddNodeV res = BddNodeV::_one; + size_t idx = 0; + getCubeRecur(false, idx, ith, res); + return res; +} + // return true if the target-th cube is met -bool -BddNodeV::getCubeRecur -(bool phase, size_t& ith, size_t target, BddNodeV& res) const -{ - if (isTerminal()) { - if (!(phase ^ isNegEdge())) { - if (ith == target) return true; - ++ith; - } - return false; - } - - BddNodeV old = res; - BddNodeV left = getLeft(); - res = old & _BddMgrV->getSupport(getLevel()); - if (left.getCubeRecur(phase ^ isNegEdge(), ith, target, res)) - return true; - BddNodeV right = getRight(); - res = old & ~(_BddMgrV->getSupport(getLevel())); - if (right.getCubeRecur(phase ^ isNegEdge(), ith, target, res)) - return true; - - return false; +bool BddNodeV::getCubeRecur(bool phase, size_t& ith, size_t target, BddNodeV& res) const { + if (isTerminal()) { + if (!(phase ^ isNegEdge())) { + if (ith == target) return true; + ++ith; + } + return false; + } + + BddNodeV old = res; + BddNodeV left = getLeft(); + res = old & _BddMgrV->getSupport(getLevel()); + if (left.getCubeRecur(phase ^ isNegEdge(), ith, target, res)) + return true; + BddNodeV right = getRight(); + res = old & ~(_BddMgrV->getSupport(getLevel())); + if (right.getCubeRecur(phase ^ isNegEdge(), ith, target, res)) + return true; + + return false; } vector -BddNodeV::getAllCubes() const -{ - vector allCubes; - BddNodeV cube = BddNodeV::_one; - getAllCubesRecur(false, cube, allCubes); - return allCubes; -} - -void -BddNodeV::getAllCubesRecur -(bool phase, BddNodeV& cube, vector& allCubes) const -{ - if (isTerminal()) { - if (!(phase ^ isNegEdge())) - allCubes.push_back(cube); - return; - } - - BddNodeV old = cube; - BddNodeV left = getLeft(); - cube = old & _BddMgrV->getSupport(getLevel()); - left.getAllCubesRecur(phase ^ isNegEdge(), cube, allCubes); - BddNodeV right = getRight(); - cube = old & ~(_BddMgrV->getSupport(getLevel())); - right.getAllCubesRecur(phase ^ isNegEdge(), cube, allCubes); +BddNodeV::getAllCubes() const { + vector allCubes; + BddNodeV cube = BddNodeV::_one; + getAllCubesRecur(false, cube, allCubes); + return allCubes; +} + +void BddNodeV::getAllCubesRecur(bool phase, BddNodeV& cube, vector& allCubes) const { + if (isTerminal()) { + if (!(phase ^ isNegEdge())) + allCubes.push_back(cube); + return; + } + + BddNodeV old = cube; + BddNodeV left = getLeft(); + cube = old & _BddMgrV->getSupport(getLevel()); + left.getAllCubesRecur(phase ^ isNegEdge(), cube, allCubes); + BddNodeV right = getRight(); + cube = old & ~(_BddMgrV->getSupport(getLevel())); + right.getAllCubesRecur(phase ^ isNegEdge(), cube, allCubes); } // Assume this BddNodeV is a cube string -BddNodeV::toString() const -{ - string str; - toStringRecur(false, str); - return str; +BddNodeV::toString() const { + string str; + toStringRecur(false, str); + return str; } // return true if a cube is found -bool -BddNodeV::toStringRecur(bool phase, string& str) const -{ - if (isTerminal()) - return (!(phase ^ isNegEdge())); - - stringstream sstr; - if (getLeft().toStringRecur(phase ^ isNegEdge(), str)) { - sstr << "(" << getLevel() << ") "; - str += sstr.str(); - return true; - } - else if (getRight().toStringRecur(phase ^ isNegEdge(), str)) { - sstr << "!(" << getLevel() << ") "; - str += sstr.str(); - return true; - } - return false; +bool BddNodeV::toStringRecur(bool phase, string& str) const { + if (isTerminal()) + return (!(phase ^ isNegEdge())); + + stringstream sstr; + if (getLeft().toStringRecur(phase ^ isNegEdge(), str)) { + sstr << "(" << getLevel() << ") "; + str += sstr.str(); + return true; + } else if (getRight().toStringRecur(phase ^ isNegEdge(), str)) { + sstr << "!(" << getLevel() << ") "; + str += sstr.str(); + return true; + } + return false; } ostream& -operator << (ostream& os, const BddNodeV& n) -{ - size_t nNodes = 0; - n.print(os, 0, nNodes); - n.unsetVisitedRecur(); - os << endl << endl << "==> Total #BddNodeVs : " << nNodes << endl; - return os; -} - -void -BddNodeV::print(ostream& os, size_t indent, size_t& nNodes) const -{ - for (size_t i = 0; i < indent; ++i) - os << ' '; - BddNodeVInt* n = getBddNodeVInt(); - os << '[' << getLevel() << "](" << (isNegEdge()? '-' : '+') << ") "; - if (_debugBddAddr) - os << n << " "; - if (_debugRefCount) - os << "(" << n->getRefCount() << ")"; - if (n->isVisited()) { - os << " (*)"; - return; - } - else ++nNodes; - n->setVisited(); - if (!isTerminal()) { - os << endl; - n->getLeft().print(os, indent + 2, nNodes); - os << endl; - n->getRight().print(os, indent + 2, nNodes); - } -} - -void -BddNodeV::unsetVisitedRecur() const -{ - BddNodeVInt* n = getBddNodeVInt(); - if (!n->isVisited()) return; - n->unsetVisited(); - if (!isTerminal()) { - n->getLeft().unsetVisitedRecur(); - n->getRight().unsetVisitedRecur(); - } -} - -void -BddNodeV::drawBdd(const string& name, ofstream& ofile) const -{ - ofile << "digraph {" << endl; - ofile << " node [shape = plaintext];" << endl; - ofile << " "; - for (unsigned l = getLevel(); l > 0; --l) - ofile << l << " -> "; - ofile << "0 [style = invis];" << endl; - ofile << " { rank = source; \"" << name << "\"; }" << endl; - ofile << " node [shape = ellipse];" << endl; - ofile << " \"" << name << "\" -> \"" << getLabel() - << "\" [color = blue]"; - ofile << (isNegEdge()? " [arrowhead = odot]" : ";") << endl; - - drawBddRecur(ofile); - - ofile << " { rank = same; 0; \"One\"; }" << endl; - ofile << "}" << endl; - - unsetVisitedRecur( ); -} - -void -BddNodeV::drawBddRecur(ofstream& ofile) const -{ - BddNodeVInt* n = getBddNodeVInt(); - if (n->isVisited()) - return; - n->setVisited(); - if(isTerminal()) - return; - BddNodeV left = getLeft(); - BddNodeV right = getRight(); - - ofile << " { rank = same; " << getLevel() << "; \"" << getLabel() - << "\"; }\n"; - - ofile << " \"" << getLabel() << "\" -> \"" << left.getLabel() << "\""; - ofile << ((left.isNegEdge())? " [arrowhead=odot]" : ";") << endl; - - ofile << " \"" << getLabel() << "\" -> \"" << right.getLabel() - << "\"[style = dotted ] [color=red]"; - ofile << ((right.isNegEdge())? " [arrowhead=odot]" : ";") << endl; - - left.drawBddRecur(ofile); - right.drawBddRecur(ofile); +operator<<(ostream& os, const BddNodeV& n) { + size_t nNodes = 0; + n.print(os, 0, nNodes); + n.unsetVisitedRecur(); + os << endl + << endl + << "==> Total #BddNodeVs : " << nNodes << endl; + return os; +} + +void BddNodeV::print(ostream& os, size_t indent, size_t& nNodes) const { + for (size_t i = 0; i < indent; ++i) + os << ' '; + BddNodeVInt* n = getBddNodeVInt(); + os << '[' << getLevel() << "](" << (isNegEdge() ? '-' : '+') << ") "; + if (_debugBddAddr) + os << n << " "; + if (_debugRefCount) + os << "(" << n->getRefCount() << ")"; + if (n->isVisited()) { + os << " (*)"; + return; + } else ++nNodes; + n->setVisited(); + if (!isTerminal()) { + os << endl; + n->getLeft().print(os, indent + 2, nNodes); + os << endl; + n->getRight().print(os, indent + 2, nNodes); + } +} + +void BddNodeV::unsetVisitedRecur() const { + BddNodeVInt* n = getBddNodeVInt(); + if (!n->isVisited()) return; + n->unsetVisited(); + if (!isTerminal()) { + n->getLeft().unsetVisitedRecur(); + n->getRight().unsetVisitedRecur(); + } +} + +void BddNodeV::drawBdd(const string& name, ofstream& ofile) const { + ofile << "digraph {" << endl; + ofile << " node [shape = plaintext];" << endl; + ofile << " "; + for (unsigned l = getLevel(); l > 0; --l) + ofile << l << " -> "; + ofile << "0 [style = invis];" << endl; + ofile << " { rank = source; \"" << name << "\"; }" << endl; + ofile << " node [shape = ellipse];" << endl; + ofile << " \"" << name << "\" -> \"" << getLabel() + << "\" [color = blue]"; + ofile << (isNegEdge() ? " [arrowhead = odot]" : ";") << endl; + + drawBddRecur(ofile); + + ofile << " { rank = same; 0; \"One\"; }" << endl; + ofile << "}" << endl; + + unsetVisitedRecur(); +} + +void BddNodeV::drawBddRecur(ofstream& ofile) const { + BddNodeVInt* n = getBddNodeVInt(); + if (n->isVisited()) + return; + n->setVisited(); + if (isTerminal()) + return; + BddNodeV left = getLeft(); + BddNodeV right = getRight(); + + ofile << " { rank = same; " << getLevel() << "; \"" << getLabel() + << "\"; }\n"; + + ofile << " \"" << getLabel() << "\" -> \"" << left.getLabel() << "\""; + ofile << ((left.isNegEdge()) ? " [arrowhead=odot]" : ";") << endl; + + ofile << " \"" << getLabel() << "\" -> \"" << right.getLabel() + << "\"[style = dotted ] [color=red]"; + ofile << ((right.isNegEdge()) ? " [arrowhead=odot]" : ";") << endl; + + left.drawBddRecur(ofile); + right.drawBddRecur(ofile); } // Don't put this->isNegEdge() on label string -BddNodeV::getLabel() const -{ - if (isTerminal()) - return "One"; +BddNodeV::getLabel() const { + if (isTerminal()) + return "One"; - ostringstream str; - str << getBddNodeVInt(); + ostringstream str; + str << getBddNodeVInt(); - return str.str(); + return str.str(); } - diff --git a/src/bdd/bddNodeV.h b/src/bdd/bddNodeV.h index 6c3c0ffc..16dcb03d 100644 --- a/src/bdd/bddNodeV.h +++ b/src/bdd/bddNodeV.h @@ -3,152 +3,150 @@ PackageName [ ] Synopsis [ Define basic BDD Node data structures ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2005-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#ifndef BDD_NODEV_H -#define BDD_NODEV_H +#pragma once + -#include -#include #include +#include +#include using namespace std; -#define BDD_EDGEV_BITS 2 -//#define BDD_NODE_PTR_MASKV ((UINT_MAX >> BDD_EDGEV_BITS) << BDD_EDGEV_BITS) -#define BDD_NODE_PTR_MASKV ((~(size_t(0)) >> BDD_EDGEV_BITS) << BDD_EDGEV_BITS) +#define BDD_EDGEV_BITS 2 +// #define BDD_NODE_PTR_MASKV ((UINT_MAX >> BDD_EDGEV_BITS) << BDD_EDGEV_BITS) +#define BDD_NODE_PTR_MASKV ((~(size_t(0)) >> BDD_EDGEV_BITS) << BDD_EDGEV_BITS) class BddMgrV; class BddNodeVInt; -enum BDD_EDGEV_FLAG -{ - BDD_POS_EDGEV = 0, - BDD_NEG_EDGEV = 1, +enum BDD_EDGEV_FLAG { + BDD_POS_EDGEV = 0, + BDD_NEG_EDGEV = 1, - BDD_EDGEV_DUMMY // dummy end + BDD_EDGEV_DUMMY // dummy end }; -class BddNodeV -{ +class BddNodeV { public: - static BddNodeV _one; - static BddNodeV _zero; - static bool _debugBddAddr; - static bool _debugRefCount; - - // no node association yet - BddNodeV() : _nodeV(0) {} - // We check the hash when a new node is possibly being created - BddNodeV(size_t l, size_t r, size_t i, BDD_EDGEV_FLAG f = BDD_POS_EDGEV); - // Copy constructor also needs to increase the _refCount - BddNodeV(const BddNodeV& n); - // n must have been uniquified... - BddNodeV(BddNodeVInt* n, BDD_EDGEV_FLAG f = BDD_POS_EDGEV); - // - BddNodeV(size_t v); - // Destructor is the only place to decrease _refCount - ~BddNodeV(); - - // Basic access functions - const BddNodeV& getLeft() const; - const BddNodeV& getRight() const; - BddNodeV getLeftCofactor(unsigned i) const; - BddNodeV getRightCofactor(unsigned i) const; - unsigned getLevel() const; - unsigned getRefCount() const; - bool isNegEdge() const { return (_nodeV & BDD_NEG_EDGEV); } - bool isPosEdge() const { return !isNegEdge(); } - - // Operators overloading - size_t operator () () const { return _nodeV; } - BddNodeV operator ~ () const { return (_nodeV ^ BDD_NEG_EDGEV); } - BddNodeV& operator = (const BddNodeV& n); - BddNodeV operator & (const BddNodeV& n) const; - BddNodeV& operator &= (const BddNodeV& n); - BddNodeV operator | (const BddNodeV& n) const; - BddNodeV& operator |= (const BddNodeV& n); - BddNodeV operator ^ (const BddNodeV& n) const; - BddNodeV& operator ^= (const BddNodeV& n); - bool operator == (const BddNodeV& n) const { return (_nodeV == n._nodeV); } - bool operator != (const BddNodeV& n) const { return (_nodeV != n._nodeV); } - bool operator < (const BddNodeV& n) const; - bool operator <= (const BddNodeV& n) const; - bool operator > (const BddNodeV& n) const { return !((*this) <= n); } - bool operator >= (const BddNodeV& n) const { return !((*this) < n); } - - // Other BDD operations - BddNodeV exist(unsigned l) const; - BddNodeV nodeMove(unsigned fLevel, unsigned tLevel, bool& isMoved) const; - size_t countCube() const; - BddNodeV getCube(size_t ith=0) const; - vector getAllCubes() const; - string toString() const; - - friend ostream& operator << (ostream& os, const BddNodeV& n); - - // For BDD drawing - void drawBdd(const string&, ofstream&) const; - string getLabel() const; - - // Static functions - static void setBddMgrV(BddMgrV* m) { _BddMgrV = m; } + static BddNodeV _one; + static BddNodeV _zero; + static bool _debugBddAddr; + static bool _debugRefCount; + + // no node association yet + BddNodeV() : _nodeV(0) {} + // We check the hash when a new node is possibly being created + BddNodeV(size_t l, size_t r, size_t i, BDD_EDGEV_FLAG f = BDD_POS_EDGEV); + // Copy constructor also needs to increase the _refCount + BddNodeV(const BddNodeV& n); + // n must have been uniquified... + BddNodeV(BddNodeVInt* n, BDD_EDGEV_FLAG f = BDD_POS_EDGEV); + // + BddNodeV(size_t v); + // Destructor is the only place to decrease _refCount + ~BddNodeV(); + + // Basic access functions + const BddNodeV& getLeft() const; + const BddNodeV& getRight() const; + BddNodeV getLeftCofactor(unsigned i) const; + BddNodeV getRightCofactor(unsigned i) const; + unsigned getLevel() const; + unsigned getRefCount() const; + bool isNegEdge() const { return (_nodeV & BDD_NEG_EDGEV); } + bool isPosEdge() const { return !isNegEdge(); } + + // Operators overloading + size_t operator()() const { return _nodeV; } + BddNodeV operator~() const { return (_nodeV ^ BDD_NEG_EDGEV); } + BddNodeV& operator=(const BddNodeV& n); + BddNodeV operator&(const BddNodeV& n) const; + BddNodeV& operator&=(const BddNodeV& n); + BddNodeV operator|(const BddNodeV& n) const; + BddNodeV& operator|=(const BddNodeV& n); + BddNodeV operator^(const BddNodeV& n) const; + BddNodeV& operator^=(const BddNodeV& n); + bool operator==(const BddNodeV& n) const { return (_nodeV == n._nodeV); } + bool operator!=(const BddNodeV& n) const { return (_nodeV != n._nodeV); } + bool operator<(const BddNodeV& n) const; + bool operator<=(const BddNodeV& n) const; + bool operator>(const BddNodeV& n) const { return !((*this) <= n); } + bool operator>=(const BddNodeV& n) const { return !((*this) < n); } + + // Other BDD operations + BddNodeV exist(unsigned l) const; + BddNodeV nodeMove(unsigned fLevel, unsigned tLevel, bool& isMoved) const; + size_t countCube() const; + BddNodeV getCube(size_t ith = 0) const; + vector getAllCubes() const; + string toString() const; + + friend ostream& operator<<(ostream& os, const BddNodeV& n); + + // For BDD drawing + void drawBdd(const string&, ofstream&) const; + string getLabel() const; + + // Static functions + static void setBddMgrV(BddMgrV* m) { _BddMgrV = m; } private: - size_t _nodeV; - - // Static data mebers - static BddMgrV* _BddMgrV; - - // Private functions - BddNodeVInt* getBddNodeVInt() const { - return (BddNodeVInt*)(_nodeV & BDD_NODE_PTR_MASKV); } - bool isTerminal() const; - void print(ostream&, size_t, size_t&) const; - void unsetVisitedRecur() const; - void drawBddRecur(ofstream&) const; - BddNodeV existRecur(unsigned l, map&) const; - BddNodeV nodeMoveRecur(unsigned f, unsigned t, map&) const; - bool containNode(unsigned b, unsigned e) const; - bool containNodeRecur(unsigned b, unsigned e) const; - size_t countCubeRecur(bool phase, map& numCubeMap) const; - bool getCubeRecur(bool p, size_t& ith, size_t target, BddNodeV& res) const; - void getAllCubesRecur(bool p, BddNodeV& c, vector& aCubes) const; - bool toStringRecur(bool p, string& str) const; + size_t _nodeV; + + // Static data mebers + static BddMgrV* _BddMgrV; + + // Private functions + BddNodeVInt* getBddNodeVInt() const { + return (BddNodeVInt*)(_nodeV & BDD_NODE_PTR_MASKV); + } + bool isTerminal() const; + void print(ostream&, size_t, size_t&) const; + void unsetVisitedRecur() const; + void drawBddRecur(ofstream&) const; + BddNodeV existRecur(unsigned l, map&) const; + BddNodeV nodeMoveRecur(unsigned f, unsigned t, map&) const; + bool containNode(unsigned b, unsigned e) const; + bool containNodeRecur(unsigned b, unsigned e) const; + size_t countCubeRecur(bool phase, map& numCubeMap) const; + bool getCubeRecur(bool p, size_t& ith, size_t target, BddNodeV& res) const; + void getAllCubesRecur(bool p, BddNodeV& c, vector& aCubes) const; + bool toStringRecur(bool p, string& str) const; }; // Private class -class BddNodeVInt -{ - friend class BddNodeV; - friend class BddMgrV; - - // For const 1 and const 0 - BddNodeVInt() : _level(0), _refCount(0), _visited(0) {} - - // Don't initialize _refCount here... - // BddNodeV() will call incRefCount() or decRefCount() instead... - BddNodeVInt(size_t l, size_t r, unsigned ll) - : _left(l), _right(r), _level(ll), _refCount(0), _visited(0) {} - - const BddNodeV& getLeft() const { return _left; } - const BddNodeV& getRight() const { return _right; } - unsigned getLevel() const { return _level; } - unsigned getRefCount() const { return _refCount; } - void incRefCount() { ++_refCount; } - void decRefCount() { --_refCount; } - bool isVisited() const { return (_visited == 1); } - void setVisited() { _visited = 1; } - void unsetVisited() { _visited = 0; } - - BddNodeV _left; - BddNodeV _right; - unsigned _level : 16; - unsigned _refCount : 15; - unsigned _visited : 1; - - static BddNodeVInt* _terminal; +class BddNodeVInt { + friend class BddNodeV; + friend class BddMgrV; + + // For const 1 and const 0 + BddNodeVInt() : _level(0), _refCount(0), _visited(0) {} + + // Don't initialize _refCount here... + // BddNodeV() will call incRefCount() or decRefCount() instead... + BddNodeVInt(size_t l, size_t r, unsigned ll) + : _left(l), _right(r), _level(ll), _refCount(0), _visited(0) {} + + const BddNodeV& getLeft() const { return _left; } + const BddNodeV& getRight() const { return _right; } + unsigned getLevel() const { return _level; } + unsigned getRefCount() const { return _refCount; } + void incRefCount() { ++_refCount; } + void decRefCount() { --_refCount; } + bool isVisited() const { return (_visited == 1); } + void setVisited() { _visited = 1; } + void unsetVisited() { _visited = 0; } + + BddNodeV _left; + BddNodeV _right; + unsigned _level : 16; + unsigned _refCount : 15; + unsigned _visited : 1; + + static BddNodeVInt* _terminal; }; -#endif // BDD_NODEV_H + diff --git a/src/bdd/myHash.h b/src/bdd/myHash.h index f900efa7..617a0dcf 100644 --- a/src/bdd/myHash.h +++ b/src/bdd/myHash.h @@ -1,344 +1,343 @@ -/**************************************************************************** - FileName [ myHash.h ] - PackageName [ util ] - Synopsis [ Define Hash and Cache ADT ] - Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2009-present LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#ifndef MY_HASH_H -#define MY_HASH_H - -#include - -using namespace std; - -//-------------------- -// Define Hash classes -//-------------------- -// To use Hash ADT, you should define your own HashKey class. -// It should at least overload the "()" and "==" operators. -// -// class HashKey +// /**************************************************************************** +// FileName [ myHash.h ] +// PackageName [ util ] +// Synopsis [ Define Hash and Cache ADT ] +// Author [ Chung-Yang (Ric) Huang ] +// Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] +// ****************************************************************************/ + +// #pragma once +// + +// #include + +// using namespace std; + +// //-------------------- +// // Define Hash classes +// //-------------------- +// // To use Hash ADT, you should define your own HashKey class. +// // It should at least overload the "()" and "==" operators. +// // +// // class HashKey +// // { +// // public: +// // BddHashKey() {} +// // +// // size_t operator() () const { return 0; } +// // +// // bool operator == (const HashKey& k) { return true; } +// // +// // private: +// // }; +// // +// template +// class Hash // { +// typedef pair HashNode; + // public: -// BddHashKey() {} -// -// size_t operator() () const { return 0; } -// -// bool operator == (const HashKey& k) { return true; } -// +// Hash() : _numBuckets(0), _buckets(0) {} +// Hash(size_t b) : _numBuckets(0), _buckets(0) { init(b); } +// ~Hash() { reset(); } + +// // HINT: implement the Hash::iterator +// // o An iterator should be able to go through all the valid HashNodes +// // in the Hash +// // o Functions to be implemented: +// // - constructor(s), destructor +// // - operator '*': return the HashNode +// // - ++/--iterator, iterator++/-- +// // - operators '=', '==', !=" +// // +// // (_bId, _bnId) range from (0, 0) to (_numBuckets, 0) +// // +// class iterator +// { +// friend class Hash; + +// public: +// iterator(Hash* h = 0, size_t b = 0, size_t bn = 0) +// : _hash(h), _bId(b), _bnId(bn) {} +// iterator(const iterator& i) +// : _hash(i._hash), _bId(i._bId), _bnId(i._bnId) {} +// ~iterator() {} // Should NOT delete HashData + +// // HINT: implement these overloaded operators +// const HashNode& operator * () const { return (*_hash)[_bId][_bnId]; } +// HashNode& operator * () { return (*_hash)[_bId][_bnId]; } +// iterator& operator ++ () { +// if (_hash == 0) return (*this); +// if (_bId >= _hash->_numBuckets) return (*this); +// if (++_bnId >= (*_hash)[_bId].size()) { +// while ((++_bId < _hash->_numBuckets) && (*_hash)[_bId].empty()); +// _bnId = 0; +// } +// return (*this); +// } +// iterator& operator -- () { +// if (_hash == 0) return (*this); +// if (_bnId == 0) { +// if (_bId == 0) return (*this); +// while ((*_hash)[--_bId].empty()) +// if (_bId == 0) return (*this); +// _bnId = (*_hash)[_bId].size() - 1; +// } +// else +// --_bnId; +// return (*this); +// } +// iterator operator ++ (int) { iterator li=(*this); ++(*this); return li; } +// iterator operator -- (int) { iterator li=(*this); --(*this); return li; } + +// iterator& operator = (const iterator& i) { +// _hash = i._hash; _bId = i._bId; _bnId = i._bnId; return (*this); } + +// bool operator != (const iterator& i) const { return !(*this == i); } +// bool operator == (const iterator& i) const { +// return (_hash == i._hash && _bId == i._bId && _bnId == i._bnId); } + +// private: +// Hash* _hash; +// size_t _bId; +// size_t _bnId; +// }; + +// // HINT: implement these functions +// // +// // Point to the first valid data +// iterator begin() const { +// size_t i = 0; +// if (_buckets == 0) return end(); +// while (_buckets[i].empty()) ++i; +// return iterator(const_cast*>(this), i, 0); +// } +// // Pass the end +// iterator end() const { +// return iterator(const_cast*>(this), +// _numBuckets, 0); +// } +// // return true if no valid data +// bool empty() const { +// for (size_t i = 0; i < _numBuckets; ++i) +// if (_buckets[i].size() != 0) return false; +// return true; +// } +// // number of valid data +// size_t size() const { +// size_t s = 0; +// for (size_t i = 0; i < _numBuckets; ++i) s += _buckets[i].size(); +// return s; +// } +// size_t numBuckets() const { return _numBuckets; } + +// vector& operator [] (size_t i) { return _buckets[i]; } +// const vector& operator [](size_t i) const { return _buckets[i]; } + +// void init(size_t b) { +// reset(); _numBuckets = b; _buckets = new vector[b]; } +// void reset() { +// _numBuckets = 0; +// if (_buckets) { delete [] _buckets; _buckets = 0; } +// } + +// // check if k is in the hash... +// // if yes, update n and return true; +// // else return false; +// bool check(const HashKey& k, HashData& n) const { +// size_t b = bucketNum(k); +// for (size_t i = 0, bn = _buckets[b].size(); i < bn; ++i) +// if (_buckets[b][i].first == k) { +// n = _buckets[b][i].second; +// return true; +// } +// return false; +// } + +// // return true if inserted successfully (i.e. k is not in the hash) +// // return false is k is already in the hash ==> will not insert +// bool insert(const HashKey& k, const HashData& d) { +// size_t b = bucketNum(k); +// for (size_t i = 0, bn = _buckets[b].size(); i < bn; ++i) +// if (_buckets[b][i].first == k) +// return false; +// _buckets[b].push_back(HashNode(k, d)); +// return true; +// } + +// // return true if inserted successfully (i.e. k is not in the hash) +// // return false is k is already in the hash ==> still do the insertion +// bool replaceInsert(const HashKey& k, const HashData& d) { +// size_t b = bucketNum(k); +// for (size_t i = 0, bn = _buckets[b].size(); i < bn; ++i) +// if (_buckets[b][i].first == k) { +// _buckets[b][i].second = d; +// return false; +// } +// _buckets[b].push_back(HashNode(k, d)); +// return true; +// } + +// // Need to be sure that k is not in the hash +// void forceInsert(const HashKey& k, const HashData& d) { +// _buckets[bucketNum(k)].push_back(HashNode(k, d)); } + // private: +// // Do not add any extra data member +// size_t _numBuckets; +// vector* _buckets; + +// size_t bucketNum(const HashKey& k) const { +// return (k() % _numBuckets); } + // }; -// -template -class Hash -{ -typedef pair HashNode; - -public: - Hash() : _numBuckets(0), _buckets(0) {} - Hash(size_t b) : _numBuckets(0), _buckets(0) { init(b); } - ~Hash() { reset(); } - - // HINT: implement the Hash::iterator - // o An iterator should be able to go through all the valid HashNodes - // in the Hash - // o Functions to be implemented: - // - constructor(s), destructor - // - operator '*': return the HashNode - // - ++/--iterator, iterator++/-- - // - operators '=', '==', !=" - // - // (_bId, _bnId) range from (0, 0) to (_numBuckets, 0) - // - class iterator - { - friend class Hash; - - public: - iterator(Hash* h = 0, size_t b = 0, size_t bn = 0) - : _hash(h), _bId(b), _bnId(bn) {} - iterator(const iterator& i) - : _hash(i._hash), _bId(i._bId), _bnId(i._bnId) {} - ~iterator() {} // Should NOT delete HashData - - // HINT: implement these overloaded operators - const HashNode& operator * () const { return (*_hash)[_bId][_bnId]; } - HashNode& operator * () { return (*_hash)[_bId][_bnId]; } - iterator& operator ++ () { - if (_hash == 0) return (*this); - if (_bId >= _hash->_numBuckets) return (*this); - if (++_bnId >= (*_hash)[_bId].size()) { - while ((++_bId < _hash->_numBuckets) && (*_hash)[_bId].empty()); - _bnId = 0; - } - return (*this); - } - iterator& operator -- () { - if (_hash == 0) return (*this); - if (_bnId == 0) { - if (_bId == 0) return (*this); - while ((*_hash)[--_bId].empty()) - if (_bId == 0) return (*this); - _bnId = (*_hash)[_bId].size() - 1; - } - else - --_bnId; - return (*this); - } - iterator operator ++ (int) { iterator li=(*this); ++(*this); return li; } - iterator operator -- (int) { iterator li=(*this); --(*this); return li; } - - iterator& operator = (const iterator& i) { - _hash = i._hash; _bId = i._bId; _bnId = i._bnId; return (*this); } - - bool operator != (const iterator& i) const { return !(*this == i); } - bool operator == (const iterator& i) const { - return (_hash == i._hash && _bId == i._bId && _bnId == i._bnId); } - - private: - Hash* _hash; - size_t _bId; - size_t _bnId; - }; - - // HINT: implement these functions - // - // Point to the first valid data - iterator begin() const { - size_t i = 0; - if (_buckets == 0) return end(); - while (_buckets[i].empty()) ++i; - return iterator(const_cast*>(this), i, 0); - } - // Pass the end - iterator end() const { - return iterator(const_cast*>(this), - _numBuckets, 0); - } - // return true if no valid data - bool empty() const { - for (size_t i = 0; i < _numBuckets; ++i) - if (_buckets[i].size() != 0) return false; - return true; - } - // number of valid data - size_t size() const { - size_t s = 0; - for (size_t i = 0; i < _numBuckets; ++i) s += _buckets[i].size(); - return s; - } - size_t numBuckets() const { return _numBuckets; } - - vector& operator [] (size_t i) { return _buckets[i]; } - const vector& operator [](size_t i) const { return _buckets[i]; } - - void init(size_t b) { - reset(); _numBuckets = b; _buckets = new vector[b]; } - void reset() { - _numBuckets = 0; - if (_buckets) { delete [] _buckets; _buckets = 0; } - } - - // check if k is in the hash... - // if yes, update n and return true; - // else return false; - bool check(const HashKey& k, HashData& n) const { - size_t b = bucketNum(k); - for (size_t i = 0, bn = _buckets[b].size(); i < bn; ++i) - if (_buckets[b][i].first == k) { - n = _buckets[b][i].second; - return true; - } - return false; - } - - // return true if inserted successfully (i.e. k is not in the hash) - // return false is k is already in the hash ==> will not insert - bool insert(const HashKey& k, const HashData& d) { - size_t b = bucketNum(k); - for (size_t i = 0, bn = _buckets[b].size(); i < bn; ++i) - if (_buckets[b][i].first == k) - return false; - _buckets[b].push_back(HashNode(k, d)); - return true; - } - - // return true if inserted successfully (i.e. k is not in the hash) - // return false is k is already in the hash ==> still do the insertion - bool replaceInsert(const HashKey& k, const HashData& d) { - size_t b = bucketNum(k); - for (size_t i = 0, bn = _buckets[b].size(); i < bn; ++i) - if (_buckets[b][i].first == k) { - _buckets[b][i].second = d; - return false; - } - _buckets[b].push_back(HashNode(k, d)); - return true; - } - - // Need to be sure that k is not in the hash - void forceInsert(const HashKey& k, const HashData& d) { - _buckets[bucketNum(k)].push_back(HashNode(k, d)); } - -private: - // Do not add any extra data member - size_t _numBuckets; - vector* _buckets; - - size_t bucketNum(const HashKey& k) const { - return (k() % _numBuckets); } - -}; - - -//--------------------- -// Define Cache classes -//--------------------- -// To use Cache ADT, you should define your own HashKey class. -// It should at least overload the "()" and "==" operators. -// -// class CacheKey + +// //--------------------- +// // Define Cache classes +// //--------------------- +// // To use Cache ADT, you should define your own HashKey class. +// // It should at least overload the "()" and "==" operators. +// // +// // class CacheKey +// // { +// // public: +// // CacheKey() {} +// // +// // size_t operator() () const { return 0; } +// // +// // bool operator == (const CacheKey&) const { return true; } +// // +// // private: +// // }; +// // +// template +// class Cache // { +// typedef pair CacheNode; + // public: -// CacheKey() {} -// -// size_t operator() () const { return 0; } -// -// bool operator == (const CacheKey&) const { return true; } -// +// Cache() : _size(0), _cache(0) {} +// Cache(size_t s) : _size(0), _cache(0) { init(s); } +// ~Cache() { reset(); } + +// // NO NEED to implement Cache::iterator class + +// // HINT: implement these functions +// // +// // Initialize _cache with size s +// void init(size_t s) { reset(); _size = s; _cache = new CacheNode[s]; } +// void reset() { _size = 0; if (_cache) { delete [] _cache; _cache = 0; } } + +// size_t size() const { return _size; } + +// CacheNode& operator [] (size_t i) { return _cache[i]; } +// const CacheNode& operator [](size_t i) const { return _cache[i]; } + +// // return false if cache miss +// bool read(const CacheKey& k, CacheData& d) const { +// size_t i = k() % _size; +// if (k == _cache[i].first) { +// d = _cache[i].second; +// return true; +// } +// return false; +// } +// // If k is already in the Cache, overwrite the CacheData +// void write(const CacheKey& k, const CacheData& d) { +// size_t i = k() % _size; +// _cache[i].first = k; +// _cache[i].second = d; +// } + // private: -// }; +// // Do not add any extra data member +// size_t _size; +// CacheNode* _cache; +// }; + +// template +// class HashMap +// { +// typedef pair HashNode; + +// public: +// HashMap(size_t b=0) : _numBuckets(0), _buckets(0) { if (b != 0) init(b); } +// ~HashMap() { reset(); } + +// // [Optional] TODO: implement the HashMap::iterator +// // o An iterator should be able to go through all the valid HashNodes +// // in the HashMap +// // o Functions to be implemented: +// // - constructor(s), destructor +// // - operator '*': return the HashNode +// // - ++/--iterator, iterator++/-- +// // - operators '=', '==', !=" +// // +// class iterator +// { +// friend class HashMap; + +// public: + +// private: +// }; + +// void init(size_t b) { +// reset(); _numBuckets = b; _buckets = new vector[b]; } +// void reset() { +// _numBuckets = 0; +// if (_buckets) { delete [] _buckets; _buckets = 0; } +// } +// void clear() { +// for (size_t i = 0; i < _numBuckets; ++i) _buckets[i].clear(); +// } +// size_t numBuckets() const { return _numBuckets; } + +// vector& operator [] (size_t i) { return _buckets[i]; } +// const vector& operator [](size_t i) const { return _buckets[i]; } + +// // TODO: implement these functions +// // +// // Point to the first valid data +// iterator begin() const { return iterator(); } +// // Pass the end +// iterator end() const { return iterator(); } +// // return true if no valid data +// bool empty() const { return true; } +// // number of valid data +// size_t size() const { size_t s = 0; return s; } + +// // check if k is in the hash... +// // if yes, return true; +// // else return false; +// bool check(const HashKey& k) const { return false; } + +// // query if k is in the hash... +// // if yes, replace d with the data in the hash and return true; +// // else return false; +// bool query(const HashKey& k, HashData& d) const { return false; } + +// // update the entry in hash that is equal to k (i.e. == return true) +// // if found, update that entry with d and return true; +// // else insert d into hash as a new entry and return false; +// bool update(const HashKey& k, HashData& d) { return false; } + +// // return true if inserted d successfully (i.e. k is not in the hash) +// // return false is k is already in the hash ==> will not insert +// bool insert(const HashKey& k, const HashData& d) { return true; } + +// // return true if removed successfully (i.e. k is in the hash) +// // return fasle otherwise (i.e. nothing is removed) +// bool remove(const HashKey& k) { return false; } + +// private: +// // Do not add any extra data member +// size_t _numBuckets; +// vector* _buckets; + +// size_t bucketNum(const HashKey& k) const { +// return (k() % _numBuckets); } + +// }; + // -template -class Cache -{ -typedef pair CacheNode; - -public: - Cache() : _size(0), _cache(0) {} - Cache(size_t s) : _size(0), _cache(0) { init(s); } - ~Cache() { reset(); } - - // NO NEED to implement Cache::iterator class - - // HINT: implement these functions - // - // Initialize _cache with size s - void init(size_t s) { reset(); _size = s; _cache = new CacheNode[s]; } - void reset() { _size = 0; if (_cache) { delete [] _cache; _cache = 0; } } - - size_t size() const { return _size; } - - CacheNode& operator [] (size_t i) { return _cache[i]; } - const CacheNode& operator [](size_t i) const { return _cache[i]; } - - // return false if cache miss - bool read(const CacheKey& k, CacheData& d) const { - size_t i = k() % _size; - if (k == _cache[i].first) { - d = _cache[i].second; - return true; - } - return false; - } - // If k is already in the Cache, overwrite the CacheData - void write(const CacheKey& k, const CacheData& d) { - size_t i = k() % _size; - _cache[i].first = k; - _cache[i].second = d; - } - -private: - // Do not add any extra data member - size_t _size; - CacheNode* _cache; -}; - -template -class HashMap -{ -typedef pair HashNode; - -public: - HashMap(size_t b=0) : _numBuckets(0), _buckets(0) { if (b != 0) init(b); } - ~HashMap() { reset(); } - - // [Optional] TODO: implement the HashMap::iterator - // o An iterator should be able to go through all the valid HashNodes - // in the HashMap - // o Functions to be implemented: - // - constructor(s), destructor - // - operator '*': return the HashNode - // - ++/--iterator, iterator++/-- - // - operators '=', '==', !=" - // - class iterator - { - friend class HashMap; - - public: - - private: - }; - - void init(size_t b) { - reset(); _numBuckets = b; _buckets = new vector[b]; } - void reset() { - _numBuckets = 0; - if (_buckets) { delete [] _buckets; _buckets = 0; } - } - void clear() { - for (size_t i = 0; i < _numBuckets; ++i) _buckets[i].clear(); - } - size_t numBuckets() const { return _numBuckets; } - - vector& operator [] (size_t i) { return _buckets[i]; } - const vector& operator [](size_t i) const { return _buckets[i]; } - - // TODO: implement these functions - // - // Point to the first valid data - iterator begin() const { return iterator(); } - // Pass the end - iterator end() const { return iterator(); } - // return true if no valid data - bool empty() const { return true; } - // number of valid data - size_t size() const { size_t s = 0; return s; } - - // check if k is in the hash... - // if yes, return true; - // else return false; - bool check(const HashKey& k) const { return false; } - - // query if k is in the hash... - // if yes, replace d with the data in the hash and return true; - // else return false; - bool query(const HashKey& k, HashData& d) const { return false; } - - // update the entry in hash that is equal to k (i.e. == return true) - // if found, update that entry with d and return true; - // else insert d into hash as a new entry and return false; - bool update(const HashKey& k, HashData& d) { return false; } - - // return true if inserted d successfully (i.e. k is not in the hash) - // return false is k is already in the hash ==> will not insert - bool insert(const HashKey& k, const HashData& d) { return true; } - - // return true if removed successfully (i.e. k is in the hash) - // return fasle otherwise (i.e. nothing is removed) - bool remove(const HashKey& k) { return false; } - -private: - // Do not add any extra data member - size_t _numBuckets; - vector* _buckets; - - size_t bucketNum(const HashKey& k) const { - return (k() % _numBuckets); } - -}; - -#endif // MY_HASH_H diff --git a/src/cir/.depend.mak b/src/cir/.depend.mak deleted file mode 100644 index bb1fc31f..00000000 --- a/src/cir/.depend.mak +++ /dev/null @@ -1,99 +0,0 @@ -cirAig.o: cirAig.cpp cirMgr.h cirDef.h ../../include/myHash.h \ - ../../include/base/abc/abc.h ../../include/misc/vec/vec.h \ - ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h cirGate.h \ - ../../include/sat.h ../../include/sat/bsat/satSolver.h \ - ../../include/sat/bsat/satVec.h ../../include/sat/bsat/satClause.h \ - ../../include/misc/util/utilDouble.h ../../include/gvModMgr.h \ - ../../include/gvCmdMgr.h ../../include/gvAbcMgr.h \ - ../../include/base/abc/abc.h ../../include/base/main/main.h \ - ../../include/base/main/abcapis.h ../../include/base/cmd/cmd.h \ - ../../include/base/io/ioAbc.h ../../include/misc/util/utilNam.h \ - ../../include/base/main/mainInt.h ../../include/base/main/main.h \ - ../../include/misc/tim/tim.h ../../include/map/if/if.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/util/utilTruth.h \ - ../../include/opt/dau/dau.h ../../include/misc/vec/vecHash.h \ - ../../include/aig/aig/aig.h ../../include/proof/ssw/ssw.h \ - ../../include/proof/fra/fra.h ../../include/opt/dar/dar.h \ - ../../include/sat/bsat/satSolver.h ../../include/aig/ioa/ioa.h \ - ../../include/gvAbcNtk.h -cirCmd.o: cirCmd.cpp cirMgr.h cirDef.h ../../include/myHash.h \ - ../../include/base/abc/abc.h ../../include/misc/vec/vec.h \ - ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h cirGate.h \ - ../../include/sat.h ../../include/sat/bsat/satSolver.h \ - ../../include/sat/bsat/satVec.h ../../include/sat/bsat/satClause.h \ - ../../include/misc/util/utilDouble.h cirCmd.h ../../include/gvCmdMgr.h \ - ../../include/util.h ../../include/rnGen.h ../../include/myUsage.h \ - ../../include/gvMsg.h -cirFraig.o: cirFraig.cpp -cirGate.o: cirGate.cpp cirGate.h cirDef.h ../../include/myHash.h \ - ../../include/sat.h ../../include/sat/bsat/satSolver.h \ - ../../include/sat/bsat/satVec.h ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h \ - ../../include/sat/bsat/satClause.h ../../include/misc/util/utilDouble.h \ - cirMgr.h ../../include/base/abc/abc.h ../../include/misc/vec/vec.h \ - ../../include/misc/vec/vecInt.h ../../include/misc/vec/vecFlt.h \ - ../../include/misc/vec/vecStr.h ../../include/misc/vec/vecPtr.h \ - ../../include/misc/vec/vecVec.h ../../include/misc/vec/vecAtt.h \ - ../../include/misc/vec/vecWrd.h ../../include/misc/vec/vecBit.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/vec/vecWec.h \ - ../../include/aig/hop/hop.h ../../include/aig/gia/gia.h \ - ../../include/misc/vec/vecWec.h ../../include/misc/util/utilCex.h \ - ../../include/misc/st/st.h ../../include/misc/st/stmm.h \ - ../../include/misc/nm/nm.h ../../include/misc/mem/mem.h \ - ../../include/misc/extra/extra.h ../../include/util.h \ - ../../include/rnGen.h ../../include/myUsage.h -cirMgr.o: cirMgr.cpp cirMgr.h cirDef.h ../../include/myHash.h \ - ../../include/base/abc/abc.h ../../include/misc/vec/vec.h \ - ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h cirGate.h \ - ../../include/sat.h ../../include/sat/bsat/satSolver.h \ - ../../include/sat/bsat/satVec.h ../../include/sat/bsat/satClause.h \ - ../../include/misc/util/utilDouble.h ../../include/util.h \ - ../../include/rnGen.h ../../include/myUsage.h -cirOpt.o: cirOpt.cpp cirMgr.h cirDef.h ../../include/myHash.h \ - ../../include/base/abc/abc.h ../../include/misc/vec/vec.h \ - ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h cirGate.h \ - ../../include/sat.h ../../include/sat/bsat/satSolver.h \ - ../../include/sat/bsat/satVec.h ../../include/sat/bsat/satClause.h \ - ../../include/misc/util/utilDouble.h ../../include/util.h \ - ../../include/rnGen.h ../../include/myUsage.h -cirSim.o: cirSim.cpp diff --git a/src/cir/.extheader.mak b/src/cir/.extheader.mak deleted file mode 100644 index 09d0ee5b..00000000 --- a/src/cir/.extheader.mak +++ /dev/null @@ -1,16 +0,0 @@ -cir.d: ../../include/cirCmd.h ../../include/cirDef.h ../../include/cirFraig.h ../../include/cirGate.h ../../include/cirMgr.h -../../include/cirCmd.h: cirCmd.h - @rm -f ../../include/cirCmd.h - @ln -fs ../src/cir/cirCmd.h ../../include/cirCmd.h -../../include/cirDef.h: cirDef.h - @rm -f ../../include/cirDef.h - @ln -fs ../src/cir/cirDef.h ../../include/cirDef.h -../../include/cirFraig.h: cirFraig.h - @rm -f ../../include/cirFraig.h - @ln -fs ../src/cir/cirFraig.h ../../include/cirFraig.h -../../include/cirGate.h: cirGate.h - @rm -f ../../include/cirGate.h - @ln -fs ../src/cir/cirGate.h ../../include/cirGate.h -../../include/cirMgr.h: cirMgr.h - @rm -f ../../include/cirMgr.h - @ln -fs ../src/cir/cirMgr.h ../../include/cirMgr.h diff --git a/src/cir/Makefile b/src/cir/Makefile deleted file mode 100644 index cd7e522a..00000000 --- a/src/cir/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -PKGFLAG = $(DEBUG_FLAG) -EXTHDRS = cirCmd.h cirDef.h cirFraig.h cirGate.h cirMgr.h - -include ../Makefile.in -include ../Makefile.lib diff --git a/src/cir/cirAig.cpp b/src/cir/cirAig.cpp index d0441c1e..844e4394 100644 --- a/src/cir/cirAig.cpp +++ b/src/cir/cirAig.cpp @@ -1,128 +1,167 @@ /**************************************************************************** FileName [ cirAig.cpp ] PackageName [ cir ] - Synopsis [ Define basic cir package commands ] - Author [ Chung-Yang (Ric) Huang ] - Copyright [ ] + Synopsis [ Define GV cir/aig functions ] + Author [ Design Verification Lab ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#include + #include -#include "base/abc/abc.h" -#include "gvModMgr.h" -#include "gvAbcMgr.h" +#include +#include -void -CirMgr::readCirFromAbc(string fileName, CirFileType fileType) { - // TODO : Convert abc ntk to gv aig ntk - CirGateV gateV; - Gia_Man_t* pGia = NULL; // the gia pointer of abc - Gia_Obj_t *pObj, *pObjRi, *pObjRo; // the obj element of gia - unsigned iPi = 0, iPo = 0, iRi = 0, iRo = 0; +#include +#include - // abc function parameters - char* pFileName = new char[100]; - cout << "filename = " << fileName << endl; - strcpy(pFileName, fileName.c_str()); - char* pTopModule = - NULL; // the top module can be auto detected by yosys, no need to set - char* pDefines = NULL; - int fBlast = 1; // blast the ntk to gia (abc's aig data structure) - int fInvert = 0; - int fTechMap = 1; - int fSkipStrash = 0; - int fCollapse = 0; - int c, fVerbose = 1; // set verbose to 1 to see which yosys command is used - int i, *pWire; +#include "abcMgr.h" +#include "cirDef.h" +#include "cirGate.h" +#include "cirMgr.h" - if(fileType == AIGER) - pGia = Gia_AigerRead(pFileName, 0, fSkipStrash, 0); - else if(fileType == VERILOG) { - pGia = abcMgr->get_Abc_Frame_t()->pGia; - cout << Gia_ManPoNum(pGia) << endl; - } +using namespace gv::cir; - // initialize the size of the containers - initCir(pGia); - // increment the global travel id for circuit traversing usage - Gia_ManIncrementTravId(pGia); - - // since we don't want to traverse the constant node, set the TravId of the - // constant node to be as the global one - Gia_ObjSetTravIdCurrent(pGia, Gia_ManConst0(pGia)); +/** + * @brief Reads a circuit from the ABC Gia. + * + * @param fileName The name of the file containing the circuit. + * @param fileType The type of file (AIGER or VERILOG) to be read. + * @return Returns true if the circuit is successfully read; otherwise, false. + */ +const bool CirMgr::readCirFromAbc(string fileName, FileType fileType) { + // ABCParams param; + // map id2Name; + // ifstream cirin(fileName); + // if (!cirin) { + // cout << "Cannot open design \"" << fileName << "\"!!" << endl; + // return false; + // } + // strcpy(param.pFileName, fileName.c_str()); + // setFileName(fileName); + // if (fileType == AIGER) { + // _abcMgr->readAiger(param); + // } else if (fileType == VERILOG) { + // param.fTechMap = 1; + // param.fVerbose = 0; + // _abcMgr->readVerilog(param); + // _ysyMgr->createMapping(fileName); + // _abcMgr->buildAigName(id2Name); + // } + // // initialize the size of the containers + // _abcMgr->initCir(fileType); + // _abcMgr->travPreprocess(); + // _abcMgr->travAllObj(fileType, id2Name); + // genDfsList(); + // return true; +} - // traverse the obj's in topological order - Gia_ManForEachObj(pGia, pObj, i) { - if(Gia_ObjIsPi(pGia, pObj)) { - CirPiGate* gate = new CirPiGate(Gia_ObjId(pGia, pObj), 0); - _piList[iPi++] = gate; - _totGateList[Gia_ObjId(pGia, pObj)] = gate; - } - else if(Gia_ObjIsPo(pGia, pObj)) { - CirPoGate *gate = new CirPoGate(Gia_ObjId(pGia, pObj), 0, Gia_ObjId(pGia, Gia_ObjFanin0(pObj))); - gate->setIn0(getGate(Gia_ObjId(pGia, Gia_ObjFanin0(pObj))), Gia_ObjFaninC0(pObj)); - _poList[iPo++] = gate; - _totGateList[Gia_ObjId(pGia, pObj)] = gate; +/** + * @brief Reorder all the gates id for AIG. + * + * @param aigIdMap The mapping bewtween the old id and the new id. + */ +void CirMgr::reorderGateId(IDMap& aigIdMap) { + unsigned nxtId = 1; + for (int i = 0, n = cirMgr->getNumPIs(); i < n; ++i) { + CirGate* gate = cirMgr->getPi(i); + unsigned gateId = gate->getGid(); + if (nxtId != gate->getGid()) { + aigIdMap[gateId] = nxtId; } - else if(Gia_ObjIsAnd(pObj)) { - CirAigGate *gate = new CirAigGate(Gia_ObjId(pGia, pObj), 0); - _totGateList[Gia_ObjId(pGia, pObj)] = gate; - gate->setIn0(getGate(Gia_ObjId(pGia, Gia_ObjFanin0(pObj))), Gia_ObjFaninC0(pObj)); - gate->setIn1(getGate(Gia_ObjId(pGia, Gia_ObjFanin1(pObj))), Gia_ObjFaninC1(pObj)); - } - else if(Gia_ObjIsRo(pGia, pObj)) { - CirRoGate* gate = new CirRoGate(Gia_ObjId(pGia, pObj), 0); - _roList[iRo++] = gate; - _totGateList[Gia_ObjId(pGia, pObj)] = gate; + nxtId++; + } + for (int i = 0, n = cirMgr->getNumLATCHs(); i < n; ++i) { + CirGate* gate = cirMgr->getRo(i); + unsigned gateId = gate->getGid(); + if (nxtId != gate->getGid()) { + aigIdMap[gateId] = nxtId; } - else if(Gia_ObjIsRi(pGia, pObj)) { - CirRiGate *gate = new CirRiGate(Gia_ObjId(pGia, pObj), 0, Gia_ObjId(pGia, Gia_ObjFanin0(pObj))); - gate->setIn0(getGate(Gia_ObjId(pGia, Gia_ObjFanin0(pObj))), Gia_ObjFaninC0(pObj)); - _riList[iPo++] = gate; - _totGateList[Gia_ObjId(pGia, pObj)] = gate; + nxtId++; + } + for (int i = 0, n = cirMgr->getNumAIGs(); i < n; ++i) { + CirGate* gate = cirMgr->getAig(i); + unsigned gateId = gate->getGid(); + if (!gate->isGlobalRef()) { + assert(true); + cout << "Redundant AIG Node !!\n"; } - else if(Gia_ObjIsConst0(pObj)) { - cout << "I am const0 " << Gia_ObjId(pGia, pObj) << endl; + if (nxtId != gate->getGid()) { + aigIdMap[gateId] = nxtId; } - else { - cout << "not defined gate type" << endl; + nxtId++; + } + for (int i = 0, n = cirMgr->getNumPOs(); i < n; ++i) { + CirGate* gate = cirMgr->getPo(i); + unsigned gateId = gate->getGid(); + if (nxtId != gate->getGid()) { + aigIdMap[gateId] = nxtId; } + nxtId++; } +} +/** + * @brief Creates a NOT gate in the circuit. + * + * @param in0 The input gate for the NOT gate. + * @return Returns a pointer to the created NOT gate. + */ +CirGate* CirMgr::createNotGate(CirGate* in0) { + CirGate* notGate = new CirAigGate(getNumTots(), 0); + addTotGate(notGate); + notGate->setIn0(in0, true); + notGate->setIn1(_const1, false); + return notGate; +} - // genConnections(); - genDfsList(); - // checkFloatList(); - // checkUnusedList(); - +/** + * @brief Creates an AND gate in the circuit. + * + * @param in0 The first input gate for the AND gate. + * @param in1 The second input gate for the AND gate. + * @return Returns a pointer to the created AND gate. + */ +CirGate* CirMgr::createAndGate(CirGate* in0, CirGate* in1) { + CirGate* andGate = new CirAigGate(getNumTots(), 0); + addTotGate(andGate); + andGate->setIn0(in0, false); + andGate->setIn1(in1, false); + return andGate; } -CirGate* -CirMgr::createGate(unsigned id, GateType type) { - CirGate* gate = _totGateList[id]; - unsigned l = 0; - switch (type) { - case PI_GATE: gate = new CirPiGate(id, l); break; - case AIG_GATE: gate = new CirAigGate(id, l); break; - //case LATCH: gate = new CirRoGate(litId/2, lineNo+1); break; - default: cerr << "Error: Unknown gate type (" << type << ")!!\n"; - exit(-1); - } - return gate; +/** + * @brief Creates an OR gate in the circuit. + * + * @param in0 The first input gate for the OR gate. + * @param in1 The second input gate for the OR gate. + * @return Returns a pointer to the created OR gate. + */ +CirGate* CirMgr::createOrGate(CirGate* in0, CirGate* in1) { + CirGate* tmpGate = new CirAigGate(getNumTots(), 0); + addTotGate(tmpGate); + tmpGate->setIn0(in0, true); + tmpGate->setIn1(in1, true); + return createNotGate(tmpGate); } -void -CirMgr::initCir(Gia_Man_t* pGia) { - // TODO : Resize the list (PI/PO ...) - // Create lists - cout << "initializing..." << endl; - _numDecl[PI] = Gia_ManPiNum(pGia); - _piList = new CirPiGate*[_numDecl[PI]]; - _numDecl[PO] = Gia_ManPoNum(pGia); - _poList = new CirPoGate*[_numDecl[PO]]; - _numDecl[LATCH] = Gia_ManRegNum(pGia); - _riList = new CirRiGate*[_numDecl[LATCH]]; - _roList = new CirRoGate*[_numDecl[LATCH]]; - _numDecl[VARS] = Gia_ManObjNum(pGia); - _totGateList = new CirGate*[_numDecl[VARS]]; - _numDecl[AIG] = Gia_ManAndNum(pGia); +/** + * @brief Creates an XOR gate in the circuit. + * + * @param in0 The first input gate for the XOR gate. + * @param in1 The second input gate for the XOR gate. + * @return Returns a pointer to the created XOR gate. + */ +CirGate* CirMgr::createXorGate(CirGate* in0, CirGate* in1) { + CirGate* tmpGate0 = new CirAigGate(getNumTots(), 0); + addTotGate(tmpGate0); + CirGate* tmpGate1 = new CirAigGate(getNumTots(), 0); + addTotGate(tmpGate1); + CirGate* tmpGate2 = new CirAigGate(getNumTots(), 0); + addTotGate(tmpGate2); + tmpGate0->setIn0(in0, true); + tmpGate0->setIn1(in1, false); + tmpGate1->setIn0(in0, false); + tmpGate1->setIn1(in1, true); + tmpGate2->setIn0(tmpGate0, true); + tmpGate2->setIn1(tmpGate1, true); + return createNotGate(tmpGate2); } diff --git a/src/cir/cirBdd.cpp b/src/cir/cirBdd.cpp new file mode 100644 index 00000000..56495293 --- /dev/null +++ b/src/cir/cirBdd.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** + FileName [ cirBdd.cpp ] + PackageName [ cir ] + Synopsis [ Define BDD manager functions ] + Author [ Design Verification Lab ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] +****************************************************************************/ + +#include "bddMgrV.h" // MODIFICATION FOR SoCV BDD +#include "bddNodeV.h" // MODIFICATION FOR SoCV BDD +#include "cirGate.h" +#include "cirMgr.h" +#include "gvMsg.h" +#include "util.h" + +extern BddMgrV* bddMgrV; // MODIFICATION FOR SoCV BDD + +namespace gv { +namespace cir { + +const bool CirMgr::setBddOrder(const bool& file) { + unsigned supportSize = getNumPIs() + 2 * getNumLATCHs(); + unsigned bddspsize = bddMgrV->getNumSupports(); + if (supportSize >= bddMgrV->getNumSupports()) { + gvMsg(GV_MSG_ERR) << "BDD Support Size is Smaller Than Current Design Required !!" << endl; + return false; + } + // build support + unsigned supportId = 1; + // build PI (primary input) + for (unsigned i = 0, n = getNumPIs(); i < n; ++i) { + CirPiGate* gate = (file) ? getPi(i) : getPi(n - i - 1); + bddMgrV->addBddNodeV(gate->getGid(), bddMgrV->getSupport(supportId)()); + ++supportId; + } + // build FF_CS (X: current state) + for (unsigned i = 0, n = getNumLATCHs(); i < n; ++i) { + CirRoGate* gate = (file) ? getRo(i) : getRo(n - i - 1); + bddMgrV->addBddNodeV(gate->getGid(), bddMgrV->getSupport(supportId)()); + ++supportId; + } + // build FF_NS (Y: next state) + // here we only create "CS_name + _ns" for y_i + for (unsigned i = 0, n = getNumLATCHs(); i < n; ++i) { + CirRiGate* gate = (file) ? getRi(i) : getRi(n - i - 1); + bddMgrV->addBddNodeV(gate->getName(), bddMgrV->getSupport(supportId)()); + ++supportId; + } + // Constants (const0 node, id=0) + bddMgrV->addBddNodeV(_const0->getGid(), BddNodeV::_zero()); + ++supportId; + + return true; +} + +void CirMgr::buildNtkBdd() { + // TODO: build BDD for ntk here + // Perform DFS traversal from DFF inputs, inout, and output gates. + // Collect ordered nets to a GVNetVec + // Construct BDDs in the DFS order + + // build PO + for (unsigned i = 0; i < getNumPOs(); ++i) { + buildBdd(getPo(i)); + } + + // build next state (RI) + for (unsigned i = 0; i < getNumLATCHs(); ++i) { + CirGate* left = getRi(i); // get RI + if (bddMgrV->getBddNodeV(left->getGid()) == (size_t)0) { + buildBdd(left); + } + } +} + +void CirMgr::buildBdd(CirGate* gate) { + GateVec orderedGates; + clearList(orderedGates); + CirGate::setGlobalRef(); + gate->genDfsList(orderedGates); + assert(orderedGates.size() <= getNumTots()); + + // TODO: build BDD for the specified net here + CirGateV left; + CirGateV right; + for (unsigned i = 0; i < orderedGates.size(); ++i) { + if (orderedGates[i]->getType() == AIG_GATE) { + // build fanin + left = orderedGates[i]->getIn0(); + right = orderedGates[i]->getIn1(); + BddNodeV newNode = ((left.isInv()) ? ~bddMgrV->getBddNodeV(left.gateId()) + : bddMgrV->getBddNodeV(left.gateId())) & + ((right.isInv()) ? ~bddMgrV->getBddNodeV(right.gateId()) + : bddMgrV->getBddNodeV(right.gateId())); + bddMgrV->addBddNodeV(orderedGates[i]->getGid(), newNode()); + } + // PO, RI + else if ((orderedGates[i]->getType() == RI_GATE) || (orderedGates[i]->getType() == PO_GATE)) { + CirGateV in0 = orderedGates[i]->getIn0(); + BddNodeV newNode = (in0.isInv()) ? ~bddMgrV->getBddNodeV(in0.gateId()) : bddMgrV->getBddNodeV(in0.gateId()); + bddMgrV->addBddNodeV(orderedGates[i]->getGid(), newNode()); + } + } +} + +} // namespace cir +} // namespace gv diff --git a/src/cir/cirCmd.cpp b/src/cir/cirCmd.cpp index 0bdf3dc2..be8f0c96 100644 --- a/src/cir/cirCmd.cpp +++ b/src/cir/cirCmd.cpp @@ -3,275 +3,342 @@ PackageName [ cir ] Synopsis [ Define basic cir package commands ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2008-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ +#include "cirCmd.h" + #include -#include +#include #include -#include "cirMgr.h" +#include + +#include "cirECO.h" #include "cirGate.h" -#include "cirCmd.h" +#include "cirMgr.h" +#include "fmt/core.h" +#include "gvCmdMgr.h" +#include "gvType.h" #include "util.h" -#include "gvMsg.h" +#include "yosysMgr.h" using namespace std; -extern CirMgr* cirMgr; +extern gv::cir::CirMgr* cirMgr; extern int effLimit; -bool -GVinitCirCmd() -{ - return (gvCmdMgr->regCmd("CIRRead", 4, new CirReadCmd) && - gvCmdMgr->regCmd("CIRPrint", 4, new CirPrintCmd) && - gvCmdMgr->regCmd("CIRGate", 4, new CirGateCmd)); - // gvCmdMgr->regCmd("CIRSWeep", 5, new CirSweepCmd) && - // gvCmdMgr->regCmd("CIROPTimize", 6, new CirOptCmd) && - // gvCmdMgr->regCmd("CIRSTRash", 6, new CirStrashCmd) && - // gvCmdMgr->regCmd("CIRSIMulate", 6, new CirSimCmd) && - // gvCmdMgr->regCmd("CIRFraig", 4, new CirFraigCmd) && - // gvCmdMgr->regCmd("CIRWrite", 4, new CirWriteCmd) && - // gvCmdMgr->regCmd("CIRMiter", 4, new CirMiterCmd) && - // gvCmdMgr->regCmd("CIREFFort", 6, new CirEffortCmd)); +bool initCirCmd() { + return (gvCmdMgr->regCmd("CIRRead", 4, new CirReadCmd) && + gvCmdMgr->regCmd("CIRPrint", 4, new CirPrintCmd) && + gvCmdMgr->regCmd("CIRGate", 4, new CirGateCmd) && + // gvCmdMgr->regCmd("CIRSWeep", 5, new CirSweepCmd) && + // gvCmdMgr->regCmd("CIROPTimize", 6, new CirOptCmd) && + // gvCmdMgr->regCmd("CIRSTRash", 6, new CirStrashCmd) && + // gvCmdMgr->regCmd("CIRSIMulate", 6, new CirSimCmd) && + // gvCmdMgr->regCmd("CIRFraig", 4, new CirFraigCmd) && + // gvCmdMgr->regCmd("CIRWrite", 4, new CirWriteCmd) && + // gvCmdMgr->regCmd("CIRMiter", 4, new CirMiterCmd) && + // gvCmdMgr->regCmd("CIREFFort", 6, new CirEffortCmd)); + gvCmdMgr->regCmd("CIRGate", 4, new CirGateCmd) && + gvCmdMgr->regCmd("CIRWrite", 4, new CirWriteCmd)); + // gvCmdMgr->regCmd("CIRBlast", 4, new CirBlastCmd)); } -enum CirCmdState -{ - // Order matters! Do not change the order!! - CIRINIT, - CIRREAD, - CIROPT, - CIRSTRASH, - CIRSIMULATE, - CIRFRAIG, - // dummy end - CIRCMDTOT +enum CirCmdState { + // Order matters! Do not change the order!! + CIRINIT, + CIRREAD, + CIROPT, + CIRSTRASH, + CIRSIMULATE, + // dummy end + CIRCMDTOT }; static CirCmdState curCmd = CIRINIT; //---------------------------------------------------------------------- -// CIRRead <(string fileName)> [-Replace] +// CIRRead <-Verilog | -Aiger> <(string fileName)> [-Replace] //---------------------------------------------------------------------- -GVCmdExecStatus -CirReadCmd::exec(const string& option) -{ - // check option - vector options; - GVCmdExec::lexOptions(option, options); - CirFileType fileType = VERILOG; - - if (options.empty()) - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, ""); - - bool doReplace = false; - string fileName; - for (size_t i = 0, n = options.size(); i < n; ++i) { - if (myStrNCmp("-Replace", options[i], 2) == 0) { - if (doReplace) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA,options[i]); - doReplace = true; - } - else if (myStrNCmp("-Aiger", options[i], 1) == 0) { - fileType = AIGER; - } - else { - if (fileName.size()) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); - fileName = options[i]; - } - } - - if (cirMgr != 0) { - if (doReplace) { - cerr << "Note: original circuit is replaced..." << endl; - curCmd = CIRINIT; - delete cirMgr; cirMgr = 0; - } - else { - cerr << "Error: circuit already exists!!" << endl; - return GV_CMD_EXEC_ERROR; - } - } - cirMgr = new CirMgr; - cirMgr->readCirFromAbc(fileName, fileType); - - // curCmd = CIRREAD; - - return GV_CMD_EXEC_DONE; +GVCmdExecStatus CirReadCmd::exec(const string& option) { + // check option + vector options; + GVCmdExec::lexOptions(option, options); + FileType fileType = VERILOG; + + if (options.empty()) + return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, ""); + + bool doReplace = false, fileError = false; + string fileName = "", fileExt = ""; + for (size_t i = 0, n = options.size(); i < n; ++i) { + if (myStrNCmp("-Replace", options[i], 2) == 0) { + if (doReplace) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[i]); + doReplace = true; + } else if (myStrNCmp("-Verilog", options[i], 2) == 0) { + fileType = VERILOG; + } else if (myStrNCmp("-Aiger", options[i], 2) == 0) { + fileType = AIGER; + } else if (myStrNCmp("-Blif", options[i], 2) == 0) { + fileType = BLIF; + } else { + if (fileName.size()) + return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); + fileName = options[i]; + ifstream infile; + infile.open(options[i].c_str()); + if (!infile) + return GVCmdExec::errorOption(GV_CMD_OPT_FOPEN_FAIL, options[i]); + infile.close(); + } + } + if (!fileName.empty()) { + if (fileType == VERILOG) { + fileExt = fileName.substr(fileName.size() - 2); + fileError = (fileExt != ".v"); + } else if (fileType == AIGER) { + fileExt = fileName.substr(fileName.size() - 4); + fileError = (fileExt != ".aig"); + } else if (fileType == BLIF) { + fileExt = fileName.substr(fileName.size() - 5); + fileError = (fileExt != ".blif"); + } + } else fileError = true; + + if (fileError) return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, fileName); + if (cirMgr != 0) { + if (doReplace) { + cout << "Note: original circuit is replaced..." << endl; + curCmd = CIRINIT; + delete cirMgr; + cirMgr = 0; + } else { + cout << "Error: circuit already exists!!" << endl; + return GV_CMD_EXEC_ERROR; + } + } + + cirMgr = new gv::cir::CirMgr(); + cirMgr->setFileName(fileName); + cirMgr->setFileType(fileType); + if (!cirMgr->readCircuitNew()) { + delete cirMgr; + cirMgr = 0; + return GV_CMD_EXEC_NOP; + } + curCmd = CIRREAD; + return GV_CMD_EXEC_DONE; } -void -CirReadCmd::usage(const bool& verbose) const -{ - gvMsg(GV_MSG_IFO) << "Usage: CIRRead <(string fileName)> [-Replace]" << endl; +void CirReadCmd::usage(const bool& verbose) const { + cout << "Usage: CIRRead <-Verilog | -Aiger | -Blif> <(string fileName)> [-Replace]" << endl; } -void -CirReadCmd::help() const -{ - cout << setw(15) << left << "CIRRead: " - << "read in a circuit and construct the netlist" << endl; +void CirReadCmd::help() const { + cout << setw(20) << left << "CIRRead:" + << "Read in a circuit and construct the netlist" << endl; } //---------------------------------------------------------------------- -// CIRPrint [-Summary | -Netlist | -PI | -PO | -FLoating | -FECpairs] +// CIRPrint [-Summary | -Netlist | -PI | -PO] //---------------------------------------------------------------------- GVCmdExecStatus -CirPrintCmd::exec(const string& option) -{ - // check option - string token; - GVCmdExec::lexSingleOption(option, token); - - if (!cirMgr) { - cerr << "Error: circuit is not yet constructed!!" << endl; - return GV_CMD_EXEC_ERROR; - } - if (token.empty() || myStrNCmp("-Summary", token, 2) == 0) - cirMgr->printSummary(); - else if (myStrNCmp("-Netlist", token, 2) == 0) - cirMgr->printNetlist(); - else if (myStrNCmp("-PI", token, 3) == 0) - cirMgr->printPIs(); - else if (myStrNCmp("-PO", token, 3) == 0) - cirMgr->printPOs(); - else if (myStrNCmp("-FLoating", token, 3) == 0) - cirMgr->printFloatGates(); - else if (myStrNCmp("-FECpairs", token, 4) == 0) - cirMgr->printFECPairs(); - else - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); - - return GV_CMD_EXEC_DONE; +CirPrintCmd::exec(const string& option) { + // check option + string token; + GVCmdExec::lexSingleOption(option, token); + + if (!cirMgr) { + cout << "Error: circuit is not yet constructed!!" << endl; + return GV_CMD_EXEC_ERROR; + } + if (token.empty() || myStrNCmp("-Summary", token, 2) == 0) + cirMgr->printSummary(); + else if (myStrNCmp("-Netlist", token, 2) == 0) + cirMgr->printNetlist(); + else if (myStrNCmp("-PI", token, 3) == 0) + cirMgr->printPIs(); + else if (myStrNCmp("-PO", token, 3) == 0) + cirMgr->printPOs(); + // else if (myStrNCmp("-FLoating", token, 3) == 0) + // cirMgr->printFloatGates(); + // else if (myStrNCmp("-FECpairs", token, 4) == 0) + // cirMgr->printFECPairs(); + else + return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); + + return GV_CMD_EXEC_DONE; } -void -CirPrintCmd::usage(const bool& verbose) const -{ - gvMsg(GV_MSG_IFO) << "Usage: CIRPrint [-Summary | -Netlist | -PI | -PO | -FLoating " - << "| -FECpairs]" << endl; +void CirPrintCmd::usage(const bool& verbose) const { + cout << "Usage: CIRPrint [-Summary | -Netlist | -PI | -PO]" << endl; } -void -CirPrintCmd::help() const -{ - cout << setw(15) << left << "CIRPrint: " << "print circuit\n"; +void CirPrintCmd::help() const { + cout << setw(20) << left << "CIRPrint: " + << "Print circuit" << endl; } //---------------------------------------------------------------------- // CIRGate <<(int gateId)> [<-FANIn | -FANOut><(int level)>]> //---------------------------------------------------------------------- GVCmdExecStatus -CirGateCmd::exec(const string& option) -{ - if (!cirMgr) { - cerr << "Error: circuit has not been read!!" << endl; - return GV_CMD_EXEC_ERROR; - } - - // check option - vector options; - GVCmdExec::lexOptions(option, options); - - if (options.empty()) - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, ""); - - int gateId = -1, level = 0; - bool doFanin = false, doFanout = false; - CirGate* thisGate = 0; - for (size_t i = 0, n = options.size(); i < n; ++i) { - bool checkLevel = false; - if (myStrNCmp("-FANIn", options[i], 5) == 0) { - if (doFanin || doFanout) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); - doFanin = true; - checkLevel = true; - } - else if (myStrNCmp("-FANOut", options[i], 5) == 0) { - if (doFanin || doFanout) +CirGateCmd::exec(const string& option) { + if (!cirMgr) { + cout << "Error: circuit has not been read!!" << endl; + return GV_CMD_EXEC_ERROR; + } + + // check option + vector options; + GVCmdExec::lexOptions(option, options); + + if (options.empty()) + return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, ""); + + int gateId = -1, level = 0; + bool doFanin = false, doFanout = false; + gv::cir::CirGate* thisGate = 0; + for (size_t i = 0, n = options.size(); i < n; ++i) { + bool checkLevel = false; + if (myStrNCmp("-FANIn", options[i], 5) == 0) { + if (doFanin || doFanout) + return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); + doFanin = true; + checkLevel = true; + } else if (myStrNCmp("-FANOut", options[i], 5) == 0) { + if (doFanin || doFanout) + return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); + doFanout = true; + checkLevel = true; + } else if (!thisGate) { + if (!myStr2Int(options[i], gateId) || gateId < 0) + return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); + thisGate = cirMgr->getGate(gateId); + if (!thisGate) { + cout << "Error: Gate(" << gateId << ") not found!!" << endl; + return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); + } + } else if (thisGate) + return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[i]); + else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); - doFanout = true; - checkLevel = true; - } - else if (!thisGate) { - if (!myStr2Int(options[i], gateId) || gateId < 0) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); - thisGate = cirMgr->getGate(gateId); - if (!thisGate) { - cerr << "Error: Gate(" << gateId << ") not found!!" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); - } - } - else if (thisGate) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[i]); - else - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); - if (checkLevel) { - if (++i == n) - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, options[i-1]); - if (!myStr2Int(options[i], level) || level < 0) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); - checkLevel = true; - } - } - - if (!thisGate) { - cerr << "Error: Gate id is not specified!!" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, options.back()); - } - - if (doFanin) - thisGate->reportFanin(level); - else if (doFanout) - thisGate->reportFanout(level); - else - thisGate->reportGate(); - - return GV_CMD_EXEC_DONE; + if (checkLevel) { + if (++i == n) + return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, options[i - 1]); + if (!myStr2Int(options[i], level) || level < 0) + return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); + checkLevel = true; + } + } + + if (!thisGate) { + cout << "Error: Gate id is not specified!!" << endl; + return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, options.back()); + } + + if (doFanin) + thisGate->reportFanin(level); + else if (doFanout) + thisGate->reportFanout(level); + else + thisGate->reportGate(); + + return GV_CMD_EXEC_DONE; } -void -CirGateCmd::usage(const bool& verbose) const -{ - gvMsg(GV_MSG_IFO) << "Usage: CIRGate <<(int gateId)> [<-FANIn | -FANOut><(int level)>]>" - << endl; +void CirGateCmd::usage(const bool& verbose) const { + cout << "Usage: CIRGate <<(int gateId)> [<-FANIn | -FANOut><(int level)>]>" << endl; } -void -CirGateCmd::help() const -{ - cout << setw(15) << left << "CIRGate: " << "report a gate\n"; +void CirGateCmd::help() const { + cout << setw(20) << left << "CIRGate:" + << "Report a gate" << endl; } -// //---------------------------------------------------------------------- -// // CIRSWeep -// //---------------------------------------------------------------------- -// GVCmdExecStatus -// CirSweepCmd::exec(const string& option) -// { -// if (!cirMgr) { -// cerr << "Error: circuit is not yet constructed!!" << endl; -// return GV_CMD_EXEC_ERROR; -// } -// // check option -// vector options; -// GVCmdExec::lexOptions(option, options); - -// if (!options.empty()) -// return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[0]); - -// assert(curCmd != CIRINIT); -// cirMgr->sweep(); +//---------------------------------------------------------------------- +// CIRWrite <-Aag [(int gateId)] | -Aig | -Blif> <-Output (string fileName)> +//---------------------------------------------------------------------- +GVCmdExecStatus +CirWriteCmd::exec(const string& option) { + if (!cirMgr) { + cout << "Error: circuit is not yet constructed!!" << endl; + return GV_CMD_EXEC_ERROR; + } + // check option + vector options; + GVCmdExec::lexOptions(option, options); + + if (options.empty()) { + cirMgr->writeAag(cout); + return GV_CMD_EXEC_DONE; + } + FileType fileType; + bool hasFile = false; + int gateId; + gv::cir::CirGate* thisGate = NULL; + string outFileName; + ofstream outfile; + for (size_t i = 0, n = options.size(); i < n; ++i) { + if (myStrNCmp("-Aiger", options[i], 2) == 0) { + fileType = AIGER; + } else if (myStrNCmp("-Aag", options[i], 2) == 0) { + fileType = AAG; + } else if (myStrNCmp("-Blif", options[i], 2) == 0) { + fileType = BLIF; + } else if (myStrNCmp("-Output", options[i], 2) == 0) { + if (hasFile) + return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[i]); + if (++i == n) + return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, options[i - 1]); + outFileName = options[i].c_str(); + outfile.open(options[i].c_str(), ios::out); + if (!outfile) + return GVCmdExec::errorOption(GV_CMD_OPT_FOPEN_FAIL, options[1]); + hasFile = true; + cirMgr->setFileName(outFileName); + } else if (myStr2Int(options[i], gateId) && gateId >= 0) { + if (fileType != AAG) + return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[i]); + if (thisGate != NULL) + return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[i]); + thisGate = cirMgr->getGate(gateId); + if (!thisGate) { + cout << "Error: Gate(" << gateId << ") not found!!" << endl; + return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); + } + if (!thisGate->isAig()) { + cout << "Error: Gate(" << gateId << ") is NOT an AIG!!" << endl; + return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); + } + } else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); + } + + if (!hasFile) return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, "-Output"); + + // cout << outFileName << "\n"; + // TODO: Fix the CIRWRITE command with the new functions + /*if (fileType == BLIF) yosysMgr->writeBlif(outFileName);*/ + /*else if (fileType == AIGER) cirMgr->getYosysMgr()->writeAiger(outFileName);*/ + if (fileType == AIGER) cirMgr->getYosysMgr()->writeAiger(outFileName); + // else { + // if (!thisGate) { + // assert(hasFile); + // cirMgr->writeAag(outfile); + // } else if (hasFile) cirMgr->writeGate(outfile, thisGate); + // else cirMgr->writeGate(cout, thisGate); + // } + return GV_CMD_EXEC_DONE; +} -// return GV_CMD_EXEC_DONE; -// } +void CirWriteCmd::usage(const bool& verbose) const { + cout << "Usage: CIRWrite <-Aag [(int gateId)] | -Aig | -Blif> <-Output (string fileName)>" << endl; +} -// void -// CirSweepCmd::usage(const bool& verbose) const -// { -// gvMsg(GV_MSG_IFO) << "Usage: CIRSWeep" << endl; -// } +void CirWriteCmd::help() const { + cout << setw(20) << left << "CIRWrite: " + << "Write the netlist to an AIG/AAG/BLIF file\n"; +} // void // CirSweepCmd::help() const @@ -287,7 +354,7 @@ CirGateCmd::help() const // CirOptCmd::exec(const string& option) // { // if (!cirMgr) { -// cerr << "Error: circuit is not yet constructed!!" << endl; +// cout << "Error: circuit is not yet constructed!!" << endl; // return GV_CMD_EXEC_ERROR; // } // // check option @@ -299,7 +366,7 @@ CirGateCmd::help() const // assert(curCmd != CIRINIT); // if (curCmd == CIRSIMULATE) { -// cerr << "Error: circuit has been simulated!! Do \"CIRFraig\" first!!" +// cout << "Error: circuit has been simulated!! Do \"CIRFraig\" first!!" // << endl; // return GV_CMD_EXEC_ERROR; // } @@ -312,7 +379,7 @@ CirGateCmd::help() const // void // CirOptCmd::usage(const bool& verbose) const // { -// gvMsg(GV_MSG_IFO) << "Usage: CIROPTimize" << endl; +// cout << "Usage: CIROPTimize" << endl; // } // void @@ -329,7 +396,7 @@ CirGateCmd::help() const // CirStrashCmd::exec(const string& option) // { // if (!cirMgr) { -// cerr << "Error: circuit is not yet constructed!!" << endl; +// cout << "Error: circuit is not yet constructed!!" << endl; // return GV_CMD_EXEC_ERROR; // } // // check option @@ -341,11 +408,11 @@ CirGateCmd::help() const // assert(curCmd != CIRINIT); // if (curCmd == CIRSTRASH) { -// cerr << "Error: circuit has been strashed!!" << endl; +// cout << "Error: circuit has been strashed!!" << endl; // return GV_CMD_EXEC_ERROR; // } // else if (curCmd == CIRSIMULATE) { -// cerr << "Error: circuit has been simulated!! Do \"CIRFraig\" first!!" +// cout << "Error: circuit has been simulated!! Do \"CIRFraig\" first!!" // << endl; // return GV_CMD_EXEC_ERROR; // } @@ -358,7 +425,7 @@ CirGateCmd::help() const // void // CirStrashCmd::usage(const bool& verbose) const // { -// gvMsg(GV_MSG_IFO) << "Usage: CIRSTRash" << endl; +// cout << "Usage: CIRSTRash" << endl; // } // void @@ -368,86 +435,104 @@ CirGateCmd::help() const // << "perform structural hash on the circuit netlist\n"; // } -// //---------------------------------------------------------------------- -// // CIRSIMulate <-Random | -File > -// // [-Output (string logFile)] -// //---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// CIRSIMulate <-Random | -File > +// [-Output (string logFile)] +//---------------------------------------------------------------------- // GVCmdExecStatus -// CirSimCmd::exec(const string& option) -// { -// if (!cirMgr) { -// cerr << "Error: circuit is not yet constructed!!" << endl; -// return GV_CMD_EXEC_ERROR; -// } -// // check option -// vector options; -// GVCmdExec::lexOptions(option, options); - -// ifstream patternFile; -// ofstream logFile; -// bool doRandom = false, doFile = false, doLog = false; -// for (size_t i = 0, n = options.size(); i < n; ++i) { -// if (myStrNCmp("-Random", options[i], 2) == 0) { -// if (doRandom || doFile) +// CirSimCmd::exec(const string& option) { +// if (!cirMgr) { +// cout << "Error: circuit is not yet constructed!!" << endl; +// return GV_CMD_EXEC_ERROR; +// } +// // check option +// vector options; +// GVCmdExec::lexOptions(option, options); + +// ifstream patternFile; +// ofstream logFile; +// bool doRandom = false, doFile = false, doLog = false; +// for (size_t i = 0, n = options.size(); i < n; ++i) { +// if (myStrNCmp("-Random", options[i], 2) == 0) { +// if (doRandom || doFile) +// return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); +// doRandom = true; +// } else if (myStrNCmp("-File", options[i], 2) == 0) { +// if (doRandom || doFile) +// return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); +// if (++i == n) +// return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, options[i - 1]); +// patternFile.open(options[i].c_str(), ios::in); +// if (!patternFile) +// return GVCmdExec::errorOption(GV_CMD_OPT_FOPEN_FAIL, options[i]); +// doFile = true; +// } else if (myStrNCmp("-Output", options[i], 2) == 0) { +// if (doLog) +// return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); +// if (++i == n) +// return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, options[i - 1]); +// logFile.open(options[i].c_str(), ios::out); +// if (!logFile) +// return GVCmdExec::errorOption(GV_CMD_OPT_FOPEN_FAIL, options[i]); +// doLog = true; +// } else // return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); -// doRandom = true; -// } -// else if (myStrNCmp("-File", options[i], 2) == 0) { -// if (doRandom || doFile) -// return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); -// if (++i == n) -// return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, options[i-1]); -// patternFile.open(options[i].c_str(), ios::in); -// if (!patternFile) -// return GVCmdExec::errorOption(GV_CMD_OPT_FOPEN_FAIL, options[i]); -// doFile = true; -// } -// else if (myStrNCmp("-Output", options[i], 2) == 0) { -// if (doLog) -// return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); -// if (++i == n) -// return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, options[i-1]); -// logFile.open(options[i].c_str(), ios::out); -// if (!logFile) -// return GVCmdExec::errorOption(GV_CMD_OPT_FOPEN_FAIL, options[i]); -// doLog = true; -// } -// else -// return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); -// } +// } -// if (!doRandom && !doFile) -// return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, ""); +// if (!doRandom && !doFile) +// return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, ""); -// assert (curCmd != CIRINIT); -// if (doLog) -// cirMgr->setSimLog(&logFile); -// else cirMgr->setSimLog(0); - -// if (doRandom) -// cirMgr->randomSim(); -// else -// cirMgr->fileSim(patternFile); -// cirMgr->setSimLog(0); -// curCmd = CIRSIMULATE; - -// return GV_CMD_EXEC_DONE; +// assert(curCmd != CIRINIT); +// if (doLog) +// cirMgr->setSimLog(&logFile); +// else cirMgr->setSimLog(0); + +// if (doRandom) +// cirMgr->randomSim(); +// else +// cirMgr->fileSim(patternFile); +// cirMgr->setSimLog(0); +// curCmd = CIRSIMULATE; + +// return GV_CMD_EXEC_DONE; // } -// void -// CirSimCmd::usage(const bool& verbose) const -// { -// gvMsg(GV_MSG_IFO) << "Usage: CIRSIMulate <-Random | -File >\n" -// << " [-Output (string logFile)]" << endl; +// void CirSimCmd::usage(const bool& verbose) const { +// cout << "Usage: CIRSIMulate <-Random | -File >\n" +// << " [-Output (string logFile)]" << endl; // } -// void -// CirSimCmd::help() const -// { -// cout << setw(15) << left << "CIRSIMulate: " -// << "perform Boolean logic simulation on the circuit\n"; +// void CirSimCmd::help() const { +// cout << setw(20) << left << "CIRSIMulate: " +// << "Perform Boolean logic simulation on the circuit\n"; +// } + +// ---------------------------------------------------------------------- +// CIRBlast +// ---------------------------------------------------------------------- +// GVCmdExecStatus +// CirBlastCmd::exec(const string& option) { +// // check option +// vector options; +// GVCmdExec::lexOptions(option, options); +// string fileName = cirMgr->getFileName(); +// FileType fileType = cirMgr->getFileType(); +// if (!cirMgr->readCirFromAbc(fileName, fileType)) { +// delete cirMgr; +// cirMgr = 0; +// } + +// return GV_CMD_EXEC_DONE; // } +// void CirBlastCmd::usage(const bool& verbose) const { +// cout << "Usage: CIRBlast" << endl; +// } + +// void CirBlastCmd::help() const { +// cout << setw(20) << left << "CIRBlast:" +// << "Convert network to AIG." << endl; +// } // //---------------------------------------------------------------------- // // CIRFraig // //---------------------------------------------------------------------- @@ -455,7 +540,7 @@ CirGateCmd::help() const // CirFraigCmd::exec(const string& option) // { // if (!cirMgr) { -// cerr << "Error: circuit is not yet constructed!!" << endl; +// cout << "Error: circuit is not yet constructed!!" << endl; // return GV_CMD_EXEC_ERROR; // } // // check option @@ -466,7 +551,7 @@ CirGateCmd::help() const // return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[0]); // if (curCmd != CIRSIMULATE) { -// cerr << "Error: circuit is not yet simulated!!" << endl; +// cout << "Error: circuit is not yet simulated!!" << endl; // return GV_CMD_EXEC_ERROR; // } // cirMgr->fraig(); @@ -478,7 +563,7 @@ CirGateCmd::help() const // void // CirFraigCmd::usage(const bool& verbose) const // { -// gvMsg(GV_MSG_IFO) << "Usage: CIRFraig" << endl; +// cout << "Usage: CIRFraig" << endl; // } // void @@ -495,7 +580,7 @@ CirGateCmd::help() const // CirWriteCmd::exec(const string& option) // { // if (!cirMgr) { -// cerr << "Error: circuit is not yet constructed!!" << endl; +// cout << "Error: circuit is not yet constructed!!" << endl; // return GV_CMD_EXEC_ERROR; // } // // check option @@ -512,7 +597,7 @@ CirGateCmd::help() const // ofstream outfile; // for (size_t i = 0, n = options.size(); i < n; ++i) { // if (myStrNCmp("-Output", options[i], 2) == 0) { -// if (hasFile) +// if (hasFile) // return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[i]); // if (++i == n) // return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, options[i-1]); @@ -526,11 +611,11 @@ CirGateCmd::help() const // return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[i]); // thisGate = cirMgr->getGate(gateId); // if (!thisGate) { -// cerr << "Error: Gate(" << gateId << ") not found!!" << endl; +// cout << "Error: Gate(" << gateId << ") not found!!" << endl; // return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); // } // if (!thisGate->isAig()) { -// cerr << "Error: Gate(" << gateId << ") is NOT an AIG!!" << endl; +// cout << "Error: Gate(" << gateId << ") is NOT an AIG!!" << endl; // return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); // } // } @@ -550,7 +635,7 @@ CirGateCmd::help() const // void // CirWriteCmd::usage(const bool& verbose) const // { -// gvMsg(GV_MSG_IFO) << "Usage: CIRWrite [(int gateId)][-Output (string aagFile)]" << endl; +// cout << "Usage: CIRWrite [(int gateId)][-Output (string aagFile)]" << endl; // } // void @@ -571,7 +656,7 @@ CirGateCmd::help() const // GVCmdExec::lexOptions(option, options); // if (cirMgr != 0) { -// cerr << "Note: original circuit is replaced..." << endl; +// cout << "Note: original circuit is replaced..." << endl; // curCmd = CIRINIT; // delete cirMgr; cirMgr = 0; // } @@ -588,15 +673,15 @@ CirGateCmd::help() const // } // if (cm[0]->getNumPIs() != cm[1]->getNumPIs()) { -// cerr << "Error: numbers of PIs are different!!" << endl; +// cout << "Error: numbers of PIs are different!!" << endl; // delete cm[0]; delete cm[1]; cirMgr = 0; // return GV_CMD_EXEC_ERROR; -// } +// } // if (cm[0]->getNumPOs() != cm[1]->getNumPOs()) { -// cerr << "Error: numbers of POs are different!!" << endl; +// cout << "Error: numbers of POs are different!!" << endl; // delete cm[0]; delete cm[1]; cirMgr = 0; // return GV_CMD_EXEC_ERROR; -// } +// } // cirMgr = new CirMgr; // if (!cirMgr->createMiter(cm[0], cm[1])) { @@ -614,7 +699,7 @@ CirGateCmd::help() const // void // CirMiterCmd::usage(const bool& verbose) const // { -// gvMsg(GV_MSG_IFO) << "Usage: CIRMiter <(string inFile1)> <(string inFile2)> " << endl; +// cout << "Usage: CIRMiter <(string inFile1)> <(string inFile2)> " << endl; // } // void @@ -647,13 +732,12 @@ CirGateCmd::help() const // void // CirEffortCmd::usage(const bool& verbose) const -// { -// gvMsg(GV_MSG_IFO) << "Usage: CIREFFort <(int effortLimit)>" << endl; +// { +// cout << "Usage: CIREFFort <(int effortLimit)>" << endl; // } // void // CirEffortCmd::help() const -// { +// { // cout << setw(15) << left << "CIREFFort: " << "set SAT proof effort\n"; // } - diff --git a/src/cir/cirCmd.h b/src/cir/cirCmd.h index fa1c871e..d766b467 100644 --- a/src/cir/cirCmd.h +++ b/src/cir/cirCmd.h @@ -3,24 +3,25 @@ PackageName [ cir ] Synopsis [ Define basic cir package commands ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2008-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#ifndef CIR_CMD_H -#define CIR_CMD_H +#pragma once + #include "gvCmdMgr.h" GV_COMMAND(CirReadCmd, GV_CMD_TYPE_NETWORK); GV_COMMAND(CirPrintCmd, GV_CMD_TYPE_NETWORK); GV_COMMAND(CirGateCmd, GV_CMD_TYPE_NETWORK); +GV_COMMAND(CirWriteCmd, GV_CMD_TYPE_NETWORK); +// GV_COMMAND(CirSimCmd, GV_CMD_TYPE_NETWORK); +// GV_COMMAND(CirBlastCmd, GV_CMD_TYPE_NETWORK); // GV_COMMAND(CirSweepCmd, GV_CMD_TYPE_NETWORK); // GV_COMMAND(CirOptCmd, GV_CMD_TYPE_NETWORK); // GV_COMMAND(CirStrashCmd, GV_CMD_TYPE_NETWORK); -// GV_COMMAND(CirSimCmd, GV_CMD_TYPE_NETWORK); // GV_COMMAND(CirFraigCmd, GV_CMD_TYPE_NETWORK); -// GV_COMMAND(CirWriteCmd, GV_CMD_TYPE_NETWORK); // GV_COMMAND(CirMiterCmd, GV_CMD_TYPE_NETWORK); // GV_COMMAND(CirEffortCmd, GV_CMD_TYPE_NETWORK); -#endif // CIR_CMD_H + diff --git a/src/cir/cirDef.h b/src/cir/cirDef.h index 5be5eb04..7bb2f3d6 100644 --- a/src/cir/cirDef.h +++ b/src/cir/cirDef.h @@ -3,52 +3,66 @@ PackageName [ cir ] Synopsis [ Define basic data or var for cir package ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2012-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#ifndef CIR_DEF_H -#define CIR_DEF_H +#pragma once +#include #include -#include "myHash.h" + +#include "myHashMap.h" using namespace std; // TODO: define your own typedef or enum -class CirPValue; +namespace gv { +namespace cir { +class CirMgr; class CirGateV; class CirGate; class CirPiGate; class CirPoGate; class CirRiGate; class CirRoGate; -class CirMgr; +class CirAigGate; +class CirCut; +class CirCutMan; +class CirPValue; +} // namespace cir +} // namespace gv class SatSolver; -typedef vector GateList; -typedef vector GateVList; -typedef vector IdList; -typedef CirGate** GateArray; -typedef CirPiGate** PiArray; -typedef CirPoGate** PoArray; -typedef CirRiGate** RiArray; -typedef CirRoGate** RoArray; -typedef HashMap FECHash; -typedef size_t* SimPattern; -typedef vector SimVector; - -enum GateType -{ - UNDEF_GATE = 0, - PI_GATE = 1, - PO_GATE = 2, - AIG_GATE = 3, - CONST_GATE = 4, - RO_GATE = 5, - RI_GATE = 6, - - TOT_GATE +typedef vector IdList; +typedef vector GateVec; +typedef vector GateVVec; +typedef vector GateVec; +typedef vector RiVec; +typedef vector RoVec; +typedef vector PiVec; +typedef vector PoVec; +typedef vector AigVec; +typedef vector VarVec; +typedef HashMap FECHash; +typedef unordered_map IDMap; +typedef size_t* SimPattern; +typedef vector SimVector; + +enum GateType { + UNDEF_GATE = 0, + PI_GATE = 1, + PO_GATE = 2, + AIG_GATE = 3, + CONST_GATE = 4, + RO_GATE = 5, + RI_GATE = 6, + + TOT_GATE }; -#endif // CIR_DEF_H +enum class CirType { + COMB = 0, + SEQ = 1, + ECO = 2, +}; diff --git a/src/cir/cirECO.h b/src/cir/cirECO.h new file mode 100644 index 00000000..b77321b8 --- /dev/null +++ b/src/cir/cirECO.h @@ -0,0 +1,14 @@ +#pragma once + +#include "cirMgr.h" + +class CirECO : public gv::cir::CirMgr { +public: + CirECO() : CirMgr() {} + ~CirECO() override {} + +private: + CirMgr* _cir0; + CirMgr* _cir1; +}; + diff --git a/src/cir/cirFraig.cpp b/src/cir/cirFraig.cpp deleted file mode 100644 index 447c9647..00000000 --- a/src/cir/cirFraig.cpp +++ /dev/null @@ -1,266 +0,0 @@ -// /**************************************************************************** -// FileName [ cirFraig.cpp ] -// PackageName [ cir ] -// Synopsis [ Define cir FRAIG functions ] -// Author [ Chung-Yang (Ric) Huang ] -// Copyright [ Copyleft(c) 2012-present LaDs(III), GIEE, NTU, Taiwan ] -// ****************************************************************************/ - -// #include -// #include "cirMgr.h" -// #include "cirGate.h" -// #include "cirFraig.h" -// #include "sat.h" -// #include "myHashMap.h" -// #include "util.h" - -// using namespace std; - -// // TODO: Please keep "CirMgr::strash()" and "CirMgr::fraig()" for cir cmd. -// // Feel free to define your own variables or functions - -// /*******************************/ -// /* Global variable and enum */ -// /*******************************/ - -// /**************************************/ -// /* Static varaibles and functions */ -// /**************************************/ - -// /*******************************************/ -// /* Public member functions about fraig */ -// /*******************************************/ -// // _floatList may be changed. -// // _unusedList and _undefList won't be changed -// void -// CirMgr::strash() -// { -// size_t numDfs = _dfsList.size(); -// size_t hSize = getHashSize(numDfs); -// HashMap sh(hSize); -// size_t des = 0; -// for (size_t i = 0, n = _dfsList.size(); i < n; ++i) { -// CirGate *g = _dfsList[i]; -// if (!g->isAig()) { _dfsList[des] = g; ++des; continue; } -// CirGateV in0 = g->getIn0(); -// CirGateV in1 = g->getIn1(); -// StrashKey k(in0(), in1()); -// CirGateV v; -// if (sh.check(k, v)) { // Strash!!! remove gate g -// in0.gate()->removeFanout(g); -// in1.gate()->removeFanout(g); -// v.gate()->merge("Strashing: ", g, false); -// deleteAigGate(g); -// } -// else { // keep this gate; insert to hash -// v = size_t(g); -// sh.forceInsert(k, v); -// _dfsList[des] = g; -// ++des; -// } -// } -// _dfsList.resize(des); -// checkFloatList(); -// } - -// void -// CirMgr::fraig() -// { -// if (_fecGrps.empty()) return; - -// SatSolver solver; - -// // build proof model -// initProofModel(solver, _dfsList); - -// unsigned nin = getNumPIs(); -// size_t patterns[nin]; -// size_t nPatterns = 0; -// size_t nUnsat = 0; -// bool doSimplify = false; -// size_t UNSAT_RESTART = _dfsList.size() / 128 + 16; -// // SAT: collect sim patterns; update FEC groups after 64 patterns -// // UNSAT: set EQ gate, DO NOT merge -// for (size_t i = 0, n = _dfsList.size(); i < n; ++i) { -// CirGate *g = _dfsList[i]; -// if (g->getEqGate() != 0 || !g->isFEC()) continue; -// CirPValue valG = g->getPValue(); -// if (((valG == size_t(0)) || (valG == ~size_t(0))) && -// (g->getFECId() / 2 == 0)) { -// if (!g->isAig()) continue; -// bool checkValue = (valG == 0); -// if (satCheckConst(solver, g, checkValue, patterns)) { -// unsigned litId = g->getFECId(); -// IdList *fecs = getFECGrps(litId/2); -// removeData(*fecs, g->getGid()*2+litId%2); -// g->resetFECId(); -// if (++nPatterns == 64) doSimplify = true; -// } -// else ++nUnsat; -// } -// else { -// Var varG = g->getSatVar(); -// IdList *fecs = getFECGrps(g->getFECId()/2); -// size_t j = 0, m = fecs->size(); -// for ( ; j < m; ++j) { -// CirGate *f = litId2Gate((*fecs)[j]); -// Var varF = f->getSatVar(); -// if ((varF <= varG) || f->getEqGate() != 0) continue; -// if (satCheckFEC(solver, g, f, (*fecs)[j]%2, patterns)) { -// ++nPatterns; -// if (nPatterns == 64) doSimplify = true; -// break; // break when meet diff -// } -// else ++nUnsat; -// } -// removeData(*fecs, g->getGid()*2+g->getFECId()%2); -// g->resetFECId(); -// } -// if (doSimplify) { -// cout << char(13) << setw(35) << ' ' << char(13); -// // if (nUnsat >= 128) { -// if (nUnsat >= UNSAT_RESTART) { -// simplifyByEQ(); -// nUnsat = 0; -// i = 0; n = _dfsList.size(); -// } // restart -// if (nPatterns != 0) { -// updateFECbySatPattern(patterns); nPatterns = 0; } -// doSimplify = false; -// } -// } -// cout << char(13) << setw(35) << ' ' << char(13); -// if (nUnsat != 0) simplifyByEQ(); -// if (nPatterns != 0) updateFECbySatPattern(patterns); -// checkFloatList(); -// checkUnusedList(); -// clearFECGrps(); -// unsetFlag(NO_FEC); // in order to perform sim and fraig again -// strash(); -// } - -// /********************************************/ -// /* Private member functions about fraig */ -// /********************************************/ -// void -// CirMgr::initProofModel(SatSolver& solver, const GateList& gates) -// { -// solver.initialize(); -// _const0->setSatVar(solver.newVar()); // CANNOT assume const gate's SAT Var=0 -// for (size_t i = 0, n = gates.size(); i < n; ++i) { -// CirGate *g = gates[i]; -// g->setSatVar(solver.newVar()); -// if (!g->isAig()) continue; -// CirGateV in0 = g->getIn0(); -// CirGateV in1 = g->getIn1(); -// solver.addAigCNF(g->getSatVar(), in0.gate()->getSatVar(), in0.isInv(), -// in1.gate()->getSatVar(), in1.isInv()); -// } -// } - -// // return true if SAT -// bool -// CirMgr::satCheckConst(SatSolver& solver, CirGate *g, bool value, -// SimPattern patterns) -// { -// // g->setToGlobalRef(); -// cout << char(13) << setw(35) << ' ' << char(13) << "Proving " -// << g->getGid() << " = " << (value?"1":"0") << "..." << flush; -// Var var = g->getSatVar(); -// solver.assumeRelease(); -// solver.assumeProperty(_const0->getSatVar(), false); -// solver.assumeProperty(var, value); -// switch (solver.assumpSolve()) { -// case SAT: -// cout << "SAT!!" << flush; -// getSatAssignment(solver, patterns); -// return true; -// case UNSAT: -// cout << "UNSAT!!" << flush; -// g->setEqGate(_const0, !value); -// break; -// case UNDECIDED: -// cout << "Aborting..." << flush; -// break; -// } -// return false; -// } - -// bool -// CirMgr::satCheckFEC(SatSolver& solver, CirGate *g, CirGate *f, bool isInvF, -// SimPattern patterns) -// { -// bool isInvG = g->getFECId() & 1; -// cout << char(13) << setw(35) << ' ' << char(13) << "Proving (" -// << (isInvG?"!":"") << g->getGid() << ", " << (isInvF?"!":"") -// << f->getGid() << ")..." << flush; -// Var varG = g->getSatVar(); -// Var varF = f->getSatVar(); -// Var newV = solver.newVar(); -// solver.addXorCNF(newV, varG, isInvG, varF, isInvF); -// solver.assumeRelease(); -// solver.assumeProperty(_const0->getSatVar(), false); -// solver.assumeProperty(newV, true); -// switch (solver.assumpSolve()) { -// case SAT: -// cout << "SAT!!" << flush; -// getSatAssignment(solver, patterns); -// return true; -// case UNSAT: -// cout << "UNSAT!!" << flush; -// f->setEqGate(g, isInvG ^ isInvF); -// break; -// case UNDECIDED: -// cout << "Aborting..." << flush; -// break; -// } -// return false; -// } - -// void -// CirMgr::getSatAssignment(SatSolver& solver, SimPattern patterns) const -// { -// for (unsigned i = 0, nin = getNumPIs(); i < nin; ++i) { -// unsigned v = solver.getValue(_piList[i]->getSatVar()); -// patterns[i] <<= 1; -// if (v == 1) patterns[i] += 1; -// } -// } - -// void -// CirMgr::simplifyByEQ() -// { -// for (size_t j = 0, n = _dfsList.size(); j < n; ++j) { -// CirGate *gate = _dfsList[j]; -// CirGateV eq = gate->getEqGate(); -// if (eq == 0) continue; -// assert(gate->isAig()); -// CirGate *in0 = gate->getIn0Gate(); -// CirGate *in1 = gate->getIn1Gate(); -// in0->removeFanout(gate); -// in1->removeFanout(gate); -// eq.gate()->merge("Fraig: ", gate, eq.isInv()); -// deleteAigGate(gate); -// } -// // simplify(); -// genDfsList(); -// simplifyFECGrps(); -// cout << "Updating by UNSAT... Total #FEC Group = " -// << _fecGrps.size() << endl; -// } - -// void -// CirMgr::updateFECbySatPattern(SimPattern patterns) -// { -// setPPattern(patterns); -// pSim1Pattern(); -// checkFEC(); -// finalizeFEC(); -// cout << "Updating by SAT... Total #FEC Group = " -// << _fecGrps.size() << endl; -// size_t nin = getNumPIs(); -// SimPattern pp = new size_t[nin]; -// for (size_t i = 0; i < nin; ++i) { pp[i] = patterns[i]; patterns[i] = 0; } -// _fecVector.push_back(pp); -// } - diff --git a/src/cir/cirFraig.h b/src/cir/cirFraig.h deleted file mode 100644 index 55b9ee60..00000000 --- a/src/cir/cirFraig.h +++ /dev/null @@ -1,33 +0,0 @@ -/**************************************************************************** - FileName [ cirFraig.h ] - PackageName [ cir ] - Synopsis [ Define FRIAG related data structure ] - Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2014-present LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#ifndef CIR_FRAIG_H -#define CIR_FRAIG_H - -// TODO: remove this file for TODO... - -class StrashKey -{ -public: - // Make sure _in0 <= _in1 - StrashKey(size_t in0, size_t in1) { - if (in0 > in1) { _in0 = in1; _in1 = in0; } - else { _in0 = in0; _in1 = in1; } - } - - size_t operator() () const { return ((_in0 >> 3) + (_in1 >> 3)); } - - bool operator == (const StrashKey& k) const { - return (_in0 == k._in0) && (_in1 == k._in1); } - -private: - size_t _in0; - size_t _in1; -}; - -#endif // CIR_FRAIG_H diff --git a/src/cir/cirGate.cpp b/src/cir/cirGate.cpp index 16340b02..0fda0e0d 100644 --- a/src/cir/cirGate.cpp +++ b/src/cir/cirGate.cpp @@ -3,18 +3,19 @@ PackageName [ cir ] Synopsis [ Define class CirAigGate member functions ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2008-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#include -#include -#include +#include "cirGate.h" + #include + #include -#include "cirGate.h" +#include +#include +#include + #include "cirMgr.h" -#include "util.h" -#include "base/abc/abc.h" using namespace std; @@ -22,11 +23,15 @@ using namespace std; // "CirGate::reportFanout()" for cir cmds. Feel free to define // your own variables and functions. -extern CirMgr *cirMgr; + +extern gv::cir::CirMgr* cirMgr; + +namespace gv { +namespace cir { unsigned CirGate::_globalRef_s = 0; -#if 1 // 1 for opt mode +#if 1 // 1 for opt mode #define NDEBUG #endif @@ -35,188 +40,182 @@ unsigned CirGate::_globalRef_s = 0; /***************************************/ unsigned CirGateV::gateId() const { return gate()->getGid(); } unsigned CirGateV::litId() const { - return (gate()->getGid()*2 + (isInv()?AIG_NEG_FANIN:0)); } + return (gate()->getGid() * 2 + (isInv() ? AIG_NEG_FANIN : 0)); +} -ostream& operator << (ostream& os, const CirGateV& gv) -{ - if (gv.isFloat()) os << "*"; - if (gv.isInv()) os << "!"; - os << gv.gateId(); - return os; +ostream& operator<<(ostream& os, const CirGateV& gv) { + if (gv.isFloat()) os << "*"; + if (gv.isInv()) os << "!"; + os << gv.gateId(); + return os; } /**************************************/ /* class CirGate member functions */ /**************************************/ -void -CirPiGate::printGate() const -{ - cout << setw(4) << left << getTypeStr() << _gid; - if (_name) cout << " (" << _name << ")"; - cout << endl; -} - -void -CirRoGate::printGate() const -{ - cout << setw(4) << left << getTypeStr() << _gid; - if (_name) cout << " (" << _name << ")"; - cout << endl; -} - -void -CirPoGate::printGate() const -{ - cout << setw(4) << left << getTypeStr() << _gid << " " << _in0; - if (_name) cout << " (" << _name << ")"; - cout << endl; -} - -void -CirRiGate::printGate() const -{ - cout << setw(4) << left << getTypeStr() << _gid << " " << _in0; - if (_name) cout << " (" << _name << ")"; - cout << endl; -} - -void -CirAigGate::printGate() const -{ - cout << setw(4) << left << getTypeStr() << _gid << " " << _in0 << " " - << _in1 << endl; -} - -void -CirConstGate::printGate() const -{ - cout << setw(4) << left << getTypeStr() << _gid << endl; -} - -void -CirGate::reportGate() const -{ - unsigned w = 80; - for (unsigned i = 0; i < w; ++i) cout << '='; - cout << endl; - - // Printing gate info - cout << "= " << getTypeStr() << "(" << _gid << ")"; - if (getName()) cout << "\"" << getName() << "\""; - cout << ", line " << _lineNo << endl; - - // Printing FEC Pairs - cout << "= FECs:"; - if (isFEC()) { - IdList *fecs = cirMgr->getFECGrps(_fecId/2); - bool isInv = _fecId & 1; - for (size_t i = 0, n = fecs->size(); i < n; ++i) { - CirGate *g = cirMgr->litId2Gate((*fecs)[i]); - if (g == this) continue; - cout << ((isInv ^ ((*fecs)[i]%2 != 0))?" !":" ") << g->getGid(); - } - } - cout << endl; - - // Printing sim value - // cout << "= Value: " << _pValue << endl; - - for (unsigned i = 0; i < w; ++i) cout << '='; - cout << endl; -} - -void -CirGate::reportFanin(int level) const -{ - assert (level >= 0); - setGlobalRef(); - reportFaninRecur(level, 0, false); -} - -void -CirGate::reportFaninRecur(int level, int repLevel, bool isInv) const -{ - if (repLevel > 0) cout << setw(repLevel*2) << ' '; - cout << (isInv?"!":"") << getTypeStr() << " " << _gid; - #ifndef NDEBUG - cout << " " << (_pValue()&size_t(0x1)); - #endif - if (level == repLevel) { cout << endl; return; } - assert (level > repLevel); - if (isGlobalRef() && getNumFanins() != 0) { - cout << " (*)" << endl; return; } - cout << endl; - setToGlobalRef(); - CirGateV in0 = getIn0(); - if (in0.gate()) - in0.gate()->reportFaninRecur(level, repLevel + 1, in0.isInv()); - CirGateV in1 = getIn1(); - if (in1.gate()) - in1.gate()->reportFaninRecur(level, repLevel + 1, in1.isInv()); -} - -void -CirGate::reportFanout(int level) const -{ - assert (level >= 0); - setGlobalRef(); - reportFanoutRecur(level, 0, false); -} - -void -CirGate::reportFanoutRecur(int level, int repLevel, bool isInv) const -{ - if (repLevel > 0) cout << setw(repLevel*2) << ' '; - cout << (isInv?"!":"") << getTypeStr() << " " << _gid; - if (level == repLevel) { cout << endl; return; } - assert (level > repLevel); - GateList& fanouts = cirMgr->getFanouts(_gid); - size_t nFanouts = fanouts.size(); - if (isGlobalRef() && nFanouts != 0) { cout << " (*)" << endl; return; } - cout << endl; - setToGlobalRef(); - for (size_t i = 0; i < nFanouts; ++i) { - CirGate *fanout = fanouts[i]; - CirGateV in0 = fanout->getIn0(); - assert (in0.gate() != 0); - bool fanoutInv = false; - if (in0.gate() == this) - fanoutInv = in0.isInv(); - else { - CirGateV in1 = fanout->getIn1(); - assert (in1.gate() != 0); - assert (in1.gate() == this); - fanoutInv = in1.isInv(); - } - fanouts[i]->reportFanoutRecur(level, repLevel + 1, fanoutInv); - } +void CirPiGate::printGate() const { + cout << setw(4) << left << getTypeStr() << _gid; + if (_name) cout << " (" << _name << ")"; + cout << endl; +} + +void CirRoGate::printGate() const { + cout << setw(4) << left << getTypeStr() << _gid << " " << _in0; + if (_name) cout << " (" << _name << ")"; + cout << endl; +} + +void CirPoGate::printGate() const { + cout << setw(4) << left << getTypeStr() << _gid << " " << _in0; + if (_name) cout << " (" << _name << ")"; + cout << endl; +} + +void CirRiGate::printGate() const { + cout << setw(4) << left << getTypeStr() << _gid << " " << _in0; + if (_name) cout << " (" << _name << ")"; + cout << endl; +} + +void CirAigGate::printGate() const { + cout << setw(4) << left << getTypeStr() << _gid << " " << _in0 << " " + << _in1 << endl; +} + +void CirConstGate::printGate() const { + cout << setw(4) << left << getTypeStr() << _gid << endl; +} + +void CirGate::reportGate() const { + unsigned w = 80; + for (unsigned i = 0; i < w; ++i) cout << '='; + cout << endl; + + // Printing gate info + cout << "= " << getTypeStr() << "(" << _gid << ")"; + if (getName()) cout << "\"" << getName() << "\""; + cout << ", line " << _lineNo << endl; + + // Printing FEC Pairs + // cout << "= FECs:"; + // if (isFEC()) { + // IdList *fecs = cirMgr->getFECGrps(_fecId/2); + // bool isInv = _fecId & 1; + // for (size_t i = 0, n = fecs->size(); i < n; ++i) { + // CirGate *g = cirMgr->litId2Gate((*fecs)[i]); + // if (g == this) continue; + // cout << ((isInv ^ ((*fecs)[i]%2 != 0))?" !":" ") << g->getGid(); + // } + // } + // cout << endl; + + // Printing sim value + // cout << "= Value: " << _pValue << endl; + + for (unsigned i = 0; i < w; ++i) cout << '='; + cout << endl; +} + +void CirGate::reportFanin(int level) const { + assert(level >= 0); + setGlobalRef(); + reportFaninRecur(level, 0, false); +} + +void CirGate::reportFaninRecur(int level, int repLevel, bool isInv) const { + if (repLevel > 0) cout << setw(repLevel * 2) << ' '; + cout << (isInv ? "!" : "") << getTypeStr() << " " << _gid; +#ifndef NDEBUG + cout << " " << (_pValue() & size_t(0x1)); +#endif + if (level == repLevel) { + cout << endl; + return; + } + assert(level > repLevel); + if (isGlobalRef() && getNumFanins() != 0) { + cout << " (*)" << endl; + return; + } + cout << endl; + setToGlobalRef(); + CirGateV in0 = getIn0(); + if (in0.gate()) + in0.gate()->reportFaninRecur(level, repLevel + 1, in0.isInv()); + CirGateV in1 = getIn1(); + if (in1.gate()) + in1.gate()->reportFaninRecur(level, repLevel + 1, in1.isInv()); +} + +void CirGate::reportFanout(int level) const { + assert(level >= 0); + setGlobalRef(); + reportFanoutRecur(level, 0, false); +} + +void CirGate::reportFanoutRecur(int level, int repLevel, bool isInv) const { + if (repLevel > 0) cout << setw(repLevel * 2) << ' '; + cout << (isInv ? "!" : "") << getTypeStr() << " " << _gid; + if (level == repLevel) { + cout << endl; + return; + } + assert(level > repLevel); + GateVec& fanouts = cirMgr->getFanouts(_gid); + size_t nFanouts = fanouts.size(); + if (isGlobalRef() && nFanouts != 0) { + cout << " (*)" << endl; + return; + } + cout << endl; + setToGlobalRef(); + for (size_t i = 0; i < nFanouts; ++i) { + CirGate* fanout = fanouts[i]; + CirGateV in0 = fanout->getIn0(); + assert(in0.gate() != 0); + bool fanoutInv = false; + if (in0.gate() == this) + fanoutInv = in0.isInv(); + else { + CirGateV in1 = fanout->getIn1(); + assert(in1.gate() != 0); + assert(in1.gate() == this); + fanoutInv = in1.isInv(); + } + fanouts[i]->reportFanoutRecur(level, repLevel + 1, fanoutInv); + } } // set in0 by the cirgate -void -CirPoGate::setIn0(CirGate* faninGate, bool inv) { - CirGateV gateV = size_t(faninGate); - gateV.setInv(inv); - setIn0(gateV()); +void CirPoGate::setIn0(CirGate* faninGate, bool inv) { + CirGateV gateV = size_t(faninGate); + gateV.setInv(inv); + setIn0(gateV()); +} + +void CirRoGate::setIn0(CirGate* faninGate, bool inv) { + CirGateV gateV = size_t(faninGate); + gateV.setInv(inv); + setIn0(gateV()); } -void -CirRiGate::setIn0(CirGate* faninGate, bool inv) { - CirGateV gateV = size_t(faninGate); - gateV.setInv(inv); - setIn0(gateV()); +void CirRiGate::setIn0(CirGate* faninGate, bool inv) { + CirGateV gateV = size_t(faninGate); + gateV.setInv(inv); + setIn0(gateV()); } -void -CirAigGate::setIn0(CirGate* faninGate, bool inv) { - CirGateV gateV = size_t(faninGate); - gateV.setInv(inv); - setIn0(gateV()); +void CirAigGate::setIn0(CirGate* faninGate, bool inv) { + CirGateV gateV = size_t(faninGate); + gateV.setInv(inv); + setIn0(gateV()); } -void -CirAigGate::setIn1(CirGate* faninGate, bool inv) { - CirGateV gateV = size_t(faninGate); - gateV.setInv(inv); - setIn1(gateV()); +void CirAigGate::setIn1(CirGate* faninGate, bool inv) { + CirGateV gateV = size_t(faninGate); + gateV.setInv(inv); + setIn1(gateV()); } + +} // namespace cir +} // namespace gv diff --git a/src/cir/cirGate.h b/src/cir/cirGate.h index ec53624a..28d81fea 100644 --- a/src/cir/cirGate.h +++ b/src/cir/cirGate.h @@ -3,444 +3,490 @@ PackageName [ cir ] Synopsis [ Define basic gate data structures ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2008-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#ifndef CIR_GATE_H -#define CIR_GATE_H +#pragma once -#include -#include -#include +#include #include #include -#include "cirDef.h" -#include "sat.h" +#include +#include +#include +#include "cirDef.h" using namespace std; // TODO: Feel free to define your own classes, variables, or functions. -class CirGate; +/*class CirGate;*/ + +namespace gv { +namespace cir { //------------------------------------------------------------------------ // Define classes //------------------------------------------------------------------------ -class CirPValue -{ +class CirPValue { public: - CirPValue(size_t v = 0): _pValue(v) {} - - void rand(); - - inline size_t operator()() const { return _pValue; } - inline CirPValue operator ~() const { return ~_pValue; } - inline CirPValue operator & (const CirPValue& p) const { - size_t v = _pValue & p._pValue; return v; } - inline CirPValue& operator &= (const CirPValue& v) { - _pValue &= v._pValue; return *this; } - inline CirPValue& operator =(const CirPValue& v) { - _pValue = v._pValue; return *this; } - inline bool operator == (const CirPValue& v) const { - return (_pValue == v._pValue); } - - friend ostream& operator << (ostream& os, const CirPValue& v); + CirPValue(size_t v = 0) : _pValue(v) {} + + void rand(); + + inline size_t operator()() const { return _pValue; } + inline CirPValue operator~() const { return ~_pValue; } + inline CirPValue operator&(const CirPValue& p) const { + size_t v = _pValue & p._pValue; + return v; + } + inline CirPValue& operator&=(const CirPValue& v) { + _pValue &= v._pValue; + return *this; + } + inline CirPValue& operator=(const CirPValue& v) { + _pValue = v._pValue; + return *this; + } + inline bool operator==(const CirPValue& v) const { + return (_pValue == v._pValue); + } + + friend ostream& operator<<(ostream& os, const CirPValue& v); private: - size_t _pValue; + size_t _pValue; }; -class CirGateV -{ +class CirGateV { public: - CirGateV(size_t v = 0): _gateV(v) {} - - size_t operator()() const { return _gateV; } - CirGate* gate() const { return (CirGate*)(_gateV & AIG_PTR_MASK); } - unsigned gateId() const; - unsigned litId() const; - bool isInv() const { return (_gateV & AIG_NEG_FANIN); } - bool isPos() const { return !(_gateV & AIG_NEG_FANIN); } - void setInv() { _gateV |= AIG_NEG_FANIN; } - // if inv == true, flip the phase - void setInv(bool inv) { if (inv) _gateV ^= AIG_NEG_FANIN; } - bool isFloat() const { return (_gateV & AIG_FLT_FANIN); } - void setFloat() { _gateV |= AIG_FLT_FANIN; } - bool operator == (const CirGateV& v) const { return (_gateV == v._gateV); } - bool operator != (const CirGateV& v) const { return (_gateV != v._gateV); } - bool operator < (const CirGateV& v) const { return (_gateV < v._gateV); } - - // inv ==> to reverse phase - void set(CirGate* g, bool inv) { _gateV = size_t(g); if (inv) setInv(); } - void replace(CirGate* g, bool inv) { _gateV = size_t(g) + (inv^isInv()); } - - friend ostream& operator << (ostream&, const CirGateV&); - - static const size_t AIG_EDGE_BITS = 2; - static const size_t AIG_NEG_FANIN = 0x1; - static const size_t AIG_FLT_FANIN = 0x2; - static const size_t AIG_PTR_MASK = - (~(size_t(0)) >> AIG_EDGE_BITS) << AIG_EDGE_BITS; - + CirGateV(size_t v = 0) : _gateV(v) {} + + size_t operator()() const { return _gateV; } + CirGate* gate() const { return (CirGate*)(_gateV & AIG_PTR_MASK); } + unsigned gateId() const; + unsigned litId() const; + bool isInv() const { return (_gateV & AIG_NEG_FANIN); } + bool isPos() const { return !(_gateV & AIG_NEG_FANIN); } + void setInv() { _gateV |= AIG_NEG_FANIN; } + // if inv == true, flip the phase + void setInv(bool inv) { + if (inv) _gateV ^= AIG_NEG_FANIN; + } + bool isFloat() const { return (_gateV & AIG_FLT_FANIN); } + void setFloat() { _gateV |= AIG_FLT_FANIN; } + bool operator==(const CirGateV& v) const { return (_gateV == v._gateV); } + bool operator!=(const CirGateV& v) const { return (_gateV != v._gateV); } + bool operator<(const CirGateV& v) const { return (_gateV < v._gateV); } + + // inv ==> to reverse phase + void set(CirGate* g, bool inv) { + _gateV = size_t(g); + if (inv) setInv(); + } + void replace(CirGate* g, bool inv) { _gateV = size_t(g) + (inv ^ isInv()); } + + friend ostream& operator<<(ostream&, const CirGateV&); + + static const size_t AIG_EDGE_BITS = 2; + static const size_t AIG_NEG_FANIN = 0x1; + static const size_t AIG_FLT_FANIN = 0x2; + static const size_t AIG_PTR_MASK = + (~(size_t(0)) >> AIG_EDGE_BITS) << AIG_EDGE_BITS; private: - size_t _gateV; + size_t _gateV; }; -class CirGate -{ +class CirGate { public: - CirGate(unsigned g, unsigned l) : _gid(g), _lineNo(l), _fecId(UINT_MAX), - _ref(0), _pValue(0), _eqGate(0), _satVar(0) {} - virtual ~CirGate() {} - - // Basic access methods -// void setGid(unsigned i) { _gid = i; } -// void setLineNo(unsigned l) { _lineNo = l; } - unsigned getGid() const { return _gid; } - unsigned getLineNo() const { return _lineNo; } - virtual GateType getType() const = 0; - virtual string getTypeStr() const = 0; - virtual CirGateV getIn0() const { return 0; } - virtual CirGateV getIn1() const { return 0; } - virtual CirGate* getIn0Gate() const { return 0; } - virtual CirGate* getIn1Gate() const { return 0; } - virtual unsigned getNumFanins() const { return 0; } - virtual char* getName() const { return 0; } - virtual bool isPi() const { return false; } - virtual bool isPo() const { return false; } - virtual bool isAig() const { return false; } - virtual bool isConst() const { return false; } - virtual bool isUndef() const { return false; } - - // Methods about circuit construction - virtual void genConnections() {} - virtual void genDfsList(vector&) { setToGlobalRef(); } - - // Methods about circuit optimization - virtual CirGateV optimize(bool phase, GateList&) { - setToGlobalRef(); - return size_t(this) + (phase?1: 0); } - void merge(const string&, CirGate *, bool); - // void replace(CirGate*, bool); - void removeFanout(CirGate*) const; - - // Methods about circuit simulation - virtual void pSim() {} - void setPValue(const CirPValue& v) { _pValue = v; } - const CirPValue& getPValue() const { return _pValue; } - - // Methods about FRAIG - void setFECId(unsigned i) { _fecId = i; } - void resetFECId() { _fecId = UINT_MAX; } - bool isFEC() const { return (_fecId != UINT_MAX); } - unsigned getFECId() const { return _fecId; } - void setEqGate(CirGate *g, bool inv) { - CirGateV nv; - while ((nv = g->getEqGate()) != 0) { g = nv.gate(); inv ^= nv.isInv(); } - _eqGate.set(g, inv); - } - void resetEqGate() { _eqGate = 0; } - const CirGateV& getEqGate() const { return _eqGate; } - void setSatVar(Var v) { _satVar = v; } - Var getSatVar() const { return _satVar; } - - // Printing functions - virtual void printGate() const = 0; - void reportGate() const; - void reportFanin(int level) const; - void reportFanout(int level) const; - - // Methods about _globalRef_s - bool isGlobalRef() const { return (_ref == _globalRef_s); } - bool isGlobalRef(unsigned diff) const { - return ((_ref + diff) == _globalRef_s); } - void setToGlobalRef() const { _ref = _globalRef_s; } - void setToGlobalRef(unsigned diff) const { - _ref = unsigned(_globalRef_s - diff); } - static void setGlobalRef() { _globalRef_s++; } - static void setGlobalRef(unsigned offset) { _globalRef_s += offset; } - -// friend ostream& operator << (ostream& os, const CirAigGate* g); + // CirGate(unsigned g, unsigned l) : _gid(g), _lineNo(l), _fecId(UINT_MAX), + // _ref(0), _pValue(0), _eqGate(0), _satVar(0) {} + CirGate(unsigned g, unsigned l) : _gid(g), _lineNo(l), _fecId(UINT_MAX), + _ref(0), _pValue(0), _eqGate(0), _satVar({}) {} + virtual ~CirGate() {} + + // Basic access methods + // void setGid(unsigned i) { _gid = i; } + // void setLineNo(unsigned l) { _lineNo = l; } + unsigned getGid() const { return _gid; } + unsigned getLineNo() const { return _lineNo; } + virtual GateType getType() const = 0; + virtual string getTypeStr() const = 0; + virtual void setIn0(CirGate*, bool inv) {}; + virtual void setIn1(CirGate*, bool inv) {}; + virtual CirGateV getIn0() const { return 0; } + virtual CirGateV getIn1() const { return 0; } + virtual CirGate* getIn0Gate() const { return 0; } + virtual CirGate* getIn1Gate() const { return 0; } + virtual unsigned getNumFanins() const { return 0; } + virtual char* getName() const { return 0; } + virtual bool isPi() const { return false; } + virtual bool isPo() const { return false; } + virtual bool isAig() const { return false; } + virtual bool isConst() const { return false; } + virtual bool isUndef() const { return false; } + + // Methods about circuit construction + virtual void genDfsList(vector&) { setToGlobalRef(); } + + // Methods about circuit optimization + // virtual CirGateV optimize(bool phase, GateVec&) { + // setToGlobalRef(); + // return size_t(this) + (phase ? 1 : 0); + // } + void merge(const string&, CirGate*, bool); + // void replace(CirGate*, bool); + void removeFanout(CirGate*) const; + + // Methods about circuit simulation + virtual void pSim() {} + void setPValue(const CirPValue& v) { _pValue = v; } + const CirPValue& getPValue() const { return _pValue; } + + // Methods about FRAIG + void setFECId(unsigned i) { _fecId = i; } + void resetFECId() { _fecId = UINT_MAX; } + bool isFEC() const { return (_fecId != UINT_MAX); } + unsigned getFECId() const { return _fecId; } + void setEqGate(CirGate* g, bool inv) { + CirGateV nv; + while ((nv = g->getEqGate()) != 0) { + g = nv.gate(); + inv ^= nv.isInv(); + } + _eqGate.set(g, inv); + } + void resetEqGate() { _eqGate = 0; } + const CirGateV& getEqGate() const { return _eqGate; } + void addSatVar(int v) const { _satVar.emplace_back(v); } + int getSatVar(const int& depth) const { + /*assert(_satVar.size() > depth);*/ + if (depth >= _satVar.size()) return 0; + return _satVar[depth]; + } + int getLastSatVar() const { + return _satVar[_satVar.size() - 1]; + } + void clearSatVar() const { + _satVar.clear(); + } + + // Printing functions + virtual void printGate() const = 0; + void reportGate() const; + void reportFanin(int level) const; + void reportFanout(int level) const; + + // Methods about _globalRef_s + bool isGlobalRef() const { return (_ref == _globalRef_s); } + bool isGlobalRef(unsigned diff) const { + return ((_ref + diff) == _globalRef_s); + } + void setToGlobalRef() const { _ref = _globalRef_s; } + void setToGlobalRef(unsigned diff) const { + _ref = unsigned(_globalRef_s - diff); + } + static void setGlobalRef() { _globalRef_s++; } + static void setGlobalRef(unsigned offset) { _globalRef_s += offset; } + + // friend ostream& operator << (ostream& os, const CirAigGate* g); private: - // Printing functions - void reportFaninRecur(int, int, bool) const; - void reportFanoutRecur(int, int, bool) const; + // Printing functions + void reportFaninRecur(int, int, bool) const; + void reportFanoutRecur(int, int, bool) const; protected: - unsigned _gid; // var ID - unsigned _lineNo; - unsigned _fecId; // _fecId/2 => FEC ID; _fecId&1 => phase - mutable unsigned _ref; - CirPValue _pValue; - CirGateV _eqGate; - Var _satVar; - - static unsigned _globalRef_s; - - // Protected methods about circuit optimization - // [Note] The original fanin will become invalid!! - virtual void replaceFanin(CirGate*, CirGate*, bool) {} + unsigned _gid; // var ID + unsigned _lineNo; + unsigned _fecId; // _fecId/2 => FEC ID; _fecId&1 => phase + mutable unsigned _ref; + CirPValue _pValue; + CirGateV _eqGate; + // Var _satVar; + mutable VarVec _satVar; + + static unsigned _globalRef_s; + + // Protected methods about circuit optimization + // [Note] The original fanin will become invalid!! + virtual void replaceFanin(CirGate*, CirGate*, bool) {} }; -class CirPiGate : public CirGate -{ +class CirPiGate : public CirGate { public: - CirPiGate(unsigned g, unsigned l): CirGate(g, l), _name(0) {} - ~CirPiGate() { if (_name) delete[]_name; } + CirPiGate(unsigned g, unsigned l) : CirGate(g, l), _name(0) {} + ~CirPiGate() { + if (_name) delete[] _name; + } - // Basic access methods - GateType getType() const { return PI_GATE; } - string getTypeStr() const { return "PI"; } - void setName(char *s) { _name = s; } - char* getName() const { return _name; } - bool isPi() const { return true; } + // Basic access methods + GateType getType() const { return PI_GATE; } + string getTypeStr() const { return "PI"; } + void setName(char* s) { _name = s; } + char* getName() const { return _name; } + bool isPi() const { return true; } - // Methods about circuit construction - void genDfsList(vector&); + // Methods about circuit construction + void genDfsList(vector&); - // Methods about circuit simulation - void setRandPPattern() { _pValue.rand(); } + // Methods about circuit simulation + void setRandPPattern() { _pValue.rand(); } - // Printing functions - void printGate() const; + // Printing functions + void printGate() const; private: - char *_name; + char* _name; }; -class CirPoGate : public CirGate -{ +class CirPoGate : public CirGate { public: - CirPoGate(unsigned g, unsigned l, size_t i = 0) - : CirGate(g, l), _in0(i), _name(0) {} - ~CirPoGate() { if (_name) delete[]_name; } - - // Basic access methods - GateType getType() const { return PO_GATE; } - string getTypeStr() const { return "PO"; } - CirGateV getIn0() const { return _in0; } - CirGate* getIn0Gate() const { return _in0.gate(); } - unsigned getNumFanins() const { return 1; } - void setName(char *s) { _name = s; } - char* getName() const { return _name; } - bool isPo() const { return true; } - void setIn0(size_t i) { _in0 = i; } - void setIn0(CirGate* faninGate, bool inv = false); - - // Methods about circuit construction - void genConnections(); - void genDfsList(vector&); - - // Methods about circuit simulation - void pSim() { - _pValue = _in0.isInv()? ~(_in0.gate()->getPValue()) - : _in0.gate()->getPValue(); - } - - // Methods about circuit optimization - CirGateV optimize(bool, GateList&); - - // Printing functions - void printGate() const; + CirPoGate(unsigned g, unsigned l, size_t i = 0) + : CirGate(g, l), _in0(i), _name(0) {} + ~CirPoGate() { + if (_name) delete[] _name; + } + + // Basic access methods + GateType getType() const { return PO_GATE; } + string getTypeStr() const { return "PO"; } + CirGateV getIn0() const { return _in0; } + CirGate* getIn0Gate() const { return _in0.gate(); } + unsigned getNumFanins() const { return 1; } + void setName(char* s) { _name = s; } + char* getName() const { return _name; } + bool isPo() const { return true; } + void setIn0(size_t i) { _in0 = i; } + void setIn0(CirGate* faninGate, bool inv = false); + + // Methods about circuit construction + void genDfsList(vector&); + + // Methods about circuit simulation + void pSim() { + _pValue = _in0.isInv() ? ~(_in0.gate()->getPValue()) + : _in0.gate()->getPValue(); + } + + // Methods about circuit optimization + // CirGateV optimize(bool, GateVec&); + + // Printing functions + void printGate() const; private: - CirGateV _in0; - char *_name; - - // Private methods about circuit optimization - // [Note] old must == _in0, DO NOT CHECK! - void replaceFanin(CirGate*, CirGate *n, bool inv) { - _in0.replace(n, inv); if (n->isUndef()) _in0.setFloat(); } + CirGateV _in0; + char* _name; + + // Private methods about circuit optimization + // [Note] old must == _in0, DO NOT CHECK! + void replaceFanin(CirGate*, CirGate* n, bool inv) { + _in0.replace(n, inv); + if (n->isUndef()) _in0.setFloat(); + } }; -class CirRoGate : public CirGate -{ +class CirRoGate : public CirGate { public: - CirRoGate(unsigned g, unsigned l, size_t i = 0) - : CirGate(g, l), _in0(i), _name(0) {} - ~CirRoGate() { if (_name) delete[]_name; } - - // Basic access methods - GateType getType() const { return RO_GATE; } - string getTypeStr() const { return "RO"; } - CirGateV getIn0() const { return _in0; } - CirGate* getIn0Gate() const { return _in0.gate(); } - unsigned getNumFanins() const { return 1; } - void setName(char *s) { _name = s; } - char* getName() const { return _name; } - bool isRo() const { return true; } - - // Methods about circuit construction - void genDfsList(vector&); - - // Methods about circuit simulation - void pSim() { - _pValue = _in0.isInv()? ~(_in0.gate()->getPValue()) - : _in0.gate()->getPValue(); - } - void zInitPPattern() { _pValue = 0; } // zero initiate the simulattion value - - // Printing functions - void printGate() const; + CirRoGate(unsigned g, unsigned l, size_t i = 0) + : CirGate(g, l), _in0(i), _name(0) {} + ~CirRoGate() { + if (_name) delete[] _name; + } + + // Basic access methods + GateType getType() const { return RO_GATE; } + string getTypeStr() const { return "RO"; } + CirGateV getIn0() const { return _in0; } + CirGate* getIn0Gate() const { return _in0.gate(); } + unsigned getNumFanins() const { return 1; } + void setName(char* s) { _name = s; } + char* getName() const { return _name; } + bool isRo() const { return true; } + void setIn0(size_t i) { _in0 = i; } + void setIn0(CirGate* faninGate, bool inv = false); + + // Methods about circuit construction + void genDfsList(vector&); + + // Methods about circuit simulation + void pSim() { + _pValue = _in0.isInv() ? ~(_in0.gate()->getPValue()) + : _in0.gate()->getPValue(); + } + void zInitPPattern() { _pValue = 0; } // zero initiate the simulattion value + + // Printing functions + void printGate() const; private: - CirGateV _in0; - char *_name; - - // Private methods about circuit optimization - // [Note] old must == _in0, DO NOT CHECK! - void replaceFanin(CirGate*, CirGate *n, bool inv) { - _in0.replace(n, inv); if (n->isUndef()) _in0.setFloat(); } + CirGateV _in0; + char* _name; + + // Private methods about circuit optimization + // [Note] old must == _in0, DO NOT CHECK! + void replaceFanin(CirGate*, CirGate* n, bool inv) { + _in0.replace(n, inv); + if (n->isUndef()) _in0.setFloat(); + } }; -class CirRiGate : public CirGate -{ +class CirRiGate : public CirGate { public: - CirRiGate(unsigned g, unsigned l, size_t i = 0) - : CirGate(g, l), _in0(i), _name(0) {} - ~CirRiGate() { if (_name) delete[]_name; } - - // Basic access methods - GateType getType() const { return RI_GATE; } - string getTypeStr() const { return "RI"; } - CirGateV getIn0() const { return _in0; } - CirGate* getIn0Gate() const { return _in0.gate(); } - unsigned getNumFanins() const { return 1; } - void setName(char *s) { _name = s; } - char* getName() const { return _name; } - bool isRi() const { return true; } - void setIn0(size_t i) { _in0 = i; } - void setIn0(CirGate* faninGate, bool inv = false); - - // Methods about circuit construction - void genConnections(); - void genDfsList(vector&); - - // Methods about circuit simulation - void pSim() { - _pValue = _in0.isInv()? ~(_in0.gate()->getPValue()) - : _in0.gate()->getPValue(); - } - - // Methods about circuit optimization - CirGateV optimize(bool, GateList&); - - // Printing functions - void printGate() const; + CirRiGate(unsigned g, unsigned l, size_t i = 0) + : CirGate(g, l), _in0(i), _name(0) {} + ~CirRiGate() { + if (_name) delete[] _name; + } + + // Basic access methods + GateType getType() const { return RI_GATE; } + string getTypeStr() const { return "RI"; } + CirGateV getIn0() const { return _in0; } + CirGate* getIn0Gate() const { return _in0.gate(); } + unsigned getNumFanins() const { return 1; } + void setName(char* s) { _name = s; } + char* getName() const { return _name; } + bool isRi() const { return true; } + void setIn0(size_t i) { _in0 = i; } + void setIn0(CirGate* faninGate, bool inv = false); + + // Methods about circuit construction + void genDfsList(vector&); + + // Methods about circuit simulation + void pSim() { + _pValue = _in0.isInv() ? ~(_in0.gate()->getPValue()) + : _in0.gate()->getPValue(); + } + + // Methods about circuit optimization + // CirGateV optimize(bool, GateVec&); + + // Printing functions + void printGate() const; private: - CirGateV _in0; - char *_name; - - // Private methods about circuit optimization - // [Note] old must == _in0, DO NOT CHECK! - void replaceFanin(CirGate*, CirGate *n, bool inv) { - _in0.replace(n, inv); if (n->isUndef()) _in0.setFloat(); } + CirGateV _in0; + char* _name; + + // Private methods about circuit optimization + // [Note] old must == _in0, DO NOT CHECK! + void replaceFanin(CirGate*, CirGate* n, bool inv) { + _in0.replace(n, inv); + if (n->isUndef()) _in0.setFloat(); + } }; -class CirAigGate : public CirGate -{ +class CirAigGate : public CirGate { public: - CirAigGate(unsigned g, unsigned l): CirGate(g, l) {} - CirGateV getIn0() const { return _in0; } - CirGateV getIn1() const { return _in1; } - CirGate* getIn0Gate() const { return _in0.gate(); } - CirGate* getIn1Gate() const { return _in1.gate(); } - unsigned getNumFanins() const { return 2; } - void setIn0(size_t i) { _in0 = i; } - void setIn1(size_t i) { _in1 = i; } - void setIn0(CirGate* faninGate, bool inv = false); - void setIn1(CirGate* faninGate, bool inv = false); - - // Basic access methods - GateType getType() const { return AIG_GATE; } - string getTypeStr() const { return "AIG"; } - bool isAig() const { return true; } - - // Methods about circuit construction - void genConnections(); - void genDfsList(vector&); - - // Methods about circuit optimization - CirGateV optimize(bool, GateList&); - - // Methods about circuit simulation - void pSim() { - _pValue = _in0.isInv()? ~(_in0.gate()->getPValue()) - : _in0.gate()->getPValue(); - _pValue &= _in1.isInv()? ~(_in1.gate()->getPValue()) - : _in1.gate()->getPValue(); - } - - // Printing functions - void printGate() const; + CirAigGate(unsigned g, unsigned l) : CirGate(g, l), _name(0) {} + ~CirAigGate() { + if (_name) delete[] _name; + } + CirGateV getIn0() const { return _in0; } + CirGateV getIn1() const { return _in1; } + CirGate* getIn0Gate() const { return _in0.gate(); } + CirGate* getIn1Gate() const { return _in1.gate(); } + unsigned getNumFanins() const { return 2; } + void setIn0(size_t i) { _in0 = i; } + void setIn1(size_t i) { _in1 = i; } + void setIn0(CirGate* faninGate, bool inv = false); + void setIn1(CirGate* faninGate, bool inv = false); + void setName(char* s) { _name = s; } + char* getName() const { return _name; } + + // Basic access methods + GateType getType() const { return AIG_GATE; } + string getTypeStr() const { return "AIG"; } + bool isAig() const { return true; } + + // Methods about circuit construction + // void genConnections(); + void genDfsList(vector&); + + // Methods about circuit optimization + // CirGateV optimize(bool, GateVec&); + + // Methods about circuit simulation + void pSim() { + _pValue = _in0.isInv() ? ~(_in0.gate()->getPValue()) + : _in0.gate()->getPValue(); + _pValue &= _in1.isInv() ? ~(_in1.gate()->getPValue()) + : _in1.gate()->getPValue(); + } + + // Printing functions + void printGate() const; private: - CirGateV _in0; - CirGateV _in1; - - // Private methods about circuit optimization - void replaceFanin(CirGate *o, CirGate *n, bool inv) { - if (o == _in0.gate()) { - _in0.replace(n, inv); if (n->isUndef()) _in0.setFloat(); } - else { - _in1.replace(n, inv); if (n->isUndef()) _in1.setFloat(); } - } + CirGateV _in0; + CirGateV _in1; + char* _name; + + // Private methods about circuit optimization + void replaceFanin(CirGate* o, CirGate* n, bool inv) { + if (o == _in0.gate()) { + _in0.replace(n, inv); + if (n->isUndef()) _in0.setFloat(); + } else { + _in1.replace(n, inv); + if (n->isUndef()) _in1.setFloat(); + } + } }; -class CirConstGate : public CirGate -{ +class CirConstGate : public CirGate { public: - CirConstGate(unsigned g): CirGate(g, 0) {} // _satVar = 0 - ~CirConstGate() {} + CirConstGate(unsigned g) : CirGate(g, 0) {} // _satVar = 0 + ~CirConstGate() {} - // Basic access methods - GateType getType() const { return CONST_GATE; } - string getTypeStr() const { return "CONST"; } - bool isConst() const { return true; } + // Basic access methods + GateType getType() const { return CONST_GATE; } + string getTypeStr() const { return "CONST"; } + bool isConst() const { return true; } - // Methods about circuit construction - void genDfsList(vector&); + // Methods about circuit construction + void genDfsList(vector&); - // Printing functions - void printGate() const; + // Printing functions + void printGate() const; private: - char *_name; + char* _name; }; -class CirUndefGate : public CirGate -{ +class CirUndefGate : public CirGate { public: - CirUndefGate(unsigned g): CirGate(g, 0) {} - ~CirUndefGate() {} + CirUndefGate(unsigned g) : CirGate(g, 0) {} + ~CirUndefGate() {} - // Basic access methods - GateType getType() const { return UNDEF_GATE; } - string getTypeStr() const { return "UNDEF"; } - bool isUndef() const { return true; } + // Basic access methods + GateType getType() const { return UNDEF_GATE; } + string getTypeStr() const { return "UNDEF"; } + bool isUndef() const { return true; } - // Methods about circuit construction + // Methods about circuit construction - // Printing functions - void printGate() const { - cerr << "CirUndefGate::printGate() is called!!" << endl; - exit(-1); - } + // Printing functions + void printGate() const { + cout << "CirUndefGate::printGate() is called!!" << endl; + exit(-1); + } private: }; -struct GateIdCmp -{ +struct GateIdCmp { public: - GateIdCmp() {} + GateIdCmp() {} - bool operator () (const CirGateV& v0, const CirGateV& v1) { - return (v0.gateId() < v1.gateId()); - } + bool operator()(const CirGateV& v0, const CirGateV& v1) { + return (v0.gateId() < v1.gateId()); + } }; -#endif // CIR_GATE_H +} // namespace cir +} // namespace gv diff --git a/src/cir/cirItf.cpp b/src/cir/cirItf.cpp new file mode 100644 index 00000000..06f057a6 --- /dev/null +++ b/src/cir/cirItf.cpp @@ -0,0 +1,119 @@ + +#include +#include + +#include "cirDef.h" +#include "cirGate.h" +#include "cirMgr.h" +#include "gvType.h" + +using gv::cir::CirMgr; + +/** + * @brief Parse the Gia from the ABC into the circuit of GV + * + * Define the interface functions for GV to parse the Gia of ABC into the Cir of GV. + * + */ +int parseRo(const int& idx, const int& gateId, const FileType& fileType) { return cirMgr->createRo(idx, gateId, fileType); } +void parseInput(const int& idx, const int& gateId) { cirMgr->createInput(idx, gateId); } +void parseOutput(const int& idx, const int& gateId, const int& in0Id, const int& inv, string poName) { cirMgr->createOutput(idx, gateId, in0Id, inv, poName); } +void parseRi(const int& idx, const int& gateId, const int& in0Id, const int& inv) { cirMgr->createRi(idx, gateId, in0Id, inv); } +void parseRiRo(const int& riGid, const int& roGid) { cirMgr->createRiRo(riGid, roGid); } +void parseAig(const int& gateId, const int& in0Id, const int& in0Inv, const int& in1Id, const int& in1Inv) { cirMgr->createAig(gateId, in0Id, in0Inv, in1Id, in1Inv); } +void parseConst0() { cirMgr->createConst0(); } +void parseConst1() { cirMgr->createConst1(); } +bool inputIsPi(const int& gateId) { return gateId <= cirMgr->getNumPIs(); } +void initCirMgr(const int& piNum, const int& poNum, const int& regNum, const int& totNum) { cirMgr->initCir(piNum, poNum, regNum, totNum); } +unsigned getNumPIs() { return cirMgr->getNumPIs(); } +unsigned getNumPOs() { return cirMgr->getNumPOs(); } +unsigned getNumLATCHs() { return cirMgr->getNumLATCHs(); } +unsigned getNumAIGs() { return cirMgr->getNumAIGs(); } +unsigned getAigIn0Gid(const unsigned& idx) { return cirMgr->getAig(idx)->getIn0Gate()->getGid(); } +unsigned getAigIn1Gid(const unsigned& idx) { return cirMgr->getAig(idx)->getIn1Gate()->getGid(); } +unsigned getPoIn0Gid(const unsigned& idx) { return cirMgr->getPo(idx)->getIn0Gate()->getGid(); } +unsigned getRiIn0Gid(const unsigned& idx) { return cirMgr->getRi(idx)->getIn0Gate()->getGid(); } +int getAigIn0Cp(const unsigned& idx) { return cirMgr->getAig(idx)->getIn0().isInv(); } +int getAigIn1Cp(const unsigned& idx) { return cirMgr->getAig(idx)->getIn1().isInv(); } +int getPoIn0Cp(const unsigned& idx) { return cirMgr->getPo(idx)->getIn0().isInv(); } +int getRiIn0Cp(const unsigned& idx) { return cirMgr->getRi(idx)->getIn0().isInv(); } +FileType getFileType() { return cirMgr->getFileType(); } + +void CirMgr::createInput(const int& idx, const int& gateId) { + assert(idx < _piList.size()); + CirPiGate* gate = new CirPiGate(gateId, 0); + _piList[idx] = gate; + _totGateList[gateId] = gate; +} + +void CirMgr::createOutput(const int& idx, const int& gateId, const int& in0Id, const int& inv, string poName) { + assert(idx < _poList.size()); + CirPoGate* gate = new CirPoGate(gateId, 0, in0Id); + char* n = new char[poName.size() + 1]; + strcpy(n, poName.c_str()); + gate->setName(n); + gate->setIn0(getGate(in0Id), inv); + _poList[idx] = gate; + _totGateList[gateId] = gate; +} + +int CirMgr::createRo(const int& idx, const int& gateId, const FileType& fileType) { + assert(idx < _roList.size()); + if (fileType == VERILOG) { + return _roList[idx]->getGid(); + } else if (fileType == AIGER) { + CirRoGate* gate = new CirRoGate(gateId, 0); + _roList[idx] = gate; + _totGateList[gateId] = gate; + } + return 0; +} + +void CirMgr::createRi(const int& idx, const int& gateId, const int& in0Id, const int& inv) { + // Redundant RI from abc (const1) + if (idx >= _riList.size()) return; + assert(idx < _riList.size()); + CirRiGate* gate = new CirRiGate(gateId, 0, in0Id); + string str = to_string(gateId) + "_ns"; + char* n = new char[str.size() + 1]; + strcpy(n, str.c_str()); + gate->setName(n); + gate->setIn0(getGate(in0Id), inv); + _riList[idx] = gate; + _totGateList[gateId] = gate; +} + +void CirMgr::createAig(const int& gateId, const int& in0Id, const int& in0Inv, const int& in1Id, const int& in1Inv) { + CirAigGate* gate = new CirAigGate(gateId, 0); + gate->setIn0(getGate(in0Id), in0Inv); + gate->setIn1(getGate(in1Id), in1Inv); + _totGateList[gateId] = gate; + _aigList.push_back(gate); +} + +void CirMgr::createRiRo(const int& riGid, const int& roGid) { + CirGate* riGate = getGate(riGid); + CirRoGate* roGate = static_cast(getGate(roGid)); + roGate->setIn0(riGate, false); +} + +void CirMgr::createConst0() { + // CONST0 Gate + _totGateList[0] = CirMgr::_const0; +} + +void CirMgr::createConst1() { + // CONST1 Gate + _const1 = new CirAigGate(getNumTots(), 0); + addTotGate(_const1); + _const1->setIn0(_const0, true); + _const1->setIn1(_const0, true); +} + +void CirMgr::initCir(const int& piNum, const int& poNum, const int& regNum, const int& totNum) { + _piList.resize(piNum); + _riList.resize(regNum); + _roList.resize(regNum); + _poList.resize(poNum); + _totGateList.resize(totNum); +} diff --git a/src/cir/cirMgr.cpp b/src/cir/cirMgr.cpp index 9d4cb04e..0ba070ee 100644 --- a/src/cir/cirMgr.cpp +++ b/src/cir/cirMgr.cpp @@ -3,727 +3,181 @@ PackageName [ cir ] Synopsis [ Define cir manager functions ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2008-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#include -#include -#include -#include -#include +#include "cirMgr.h" + #include +#include +#include #include -#include "cirMgr.h" + +#include "cirDef.h" #include "cirGate.h" +#include "fmt/core.h" +#include "gvType.h" #include "util.h" +#include "yosysMgr.h" using namespace std; +/*using namespace gv::cir;*/ // TODO: Implement memeber functions for class CirMgr /*******************************/ /* Global variable and enum */ /*******************************/ -CirMgr* cirMgr = 0; -CirGate* CirMgr::_const0 = new CirConstGate(0); - -enum CirParseError { - EXTRA_SPACE, - MISSING_SPACE, - ILLEGAL_WSPACE, - ILLEGAL_NUM, - ILLEGAL_IDENTIFIER, - ILLEGAL_SYMBOL_TYPE, - ILLEGAL_SYMBOL_NAME, - MISSING_NUM, - MISSING_IDENTIFIER, - MISSING_NEWLINE, - MISSING_DEF, - CANNOT_INVERTED, - MAX_LIT_ID, - REDEF_GATE, - REDEF_SYMBOLIC_NAME, - REDEF_CONST, - NUM_TOO_SMALL, - NUM_TOO_BIG, - - DUMMY_END -}; - -/**************************************/ -/* Static varaibles and functions */ -/**************************************/ -static unsigned lineNo = 0; // in printint, lineNo needs to ++ -static unsigned colNo = 0; // in printing, colNo needs to ++ -static char buf[1024]; -static string errMsg; -static int errInt; -static CirGate *errGate; - -static bool -parseError(CirParseError err) -{ - switch (err) { - case EXTRA_SPACE: - cerr << "[ERROR] Line " << lineNo+1 << ", Col " << colNo+1 - << ": Extra space character is detected!!" << endl; - break; - case MISSING_SPACE: - cerr << "[ERROR] Line " << lineNo+1 << ", Col " << colNo+1 - << ": Missing space character!!" << endl; - break; - case ILLEGAL_WSPACE: // for non-space white space character - cerr << "[ERROR] Line " << lineNo+1 << ", Col " << colNo+1 - << ": Illegal white space char(" << errInt - << ") is detected!!" << endl; - break; - case ILLEGAL_NUM: - cerr << "[ERROR] Line " << lineNo+1 << ": Illegal " - << errMsg << "!!" << endl; - break; - case ILLEGAL_IDENTIFIER: - cerr << "[ERROR] Line " << lineNo+1 << ": Illegal identifier \"" - << errMsg << "\"!!" << endl; - break; - case ILLEGAL_SYMBOL_TYPE: - cerr << "[ERROR] Line " << lineNo+1 << ", Col " << colNo+1 - << ": Illegal symbol type (" << errMsg << ")!!" << endl; - break; - case ILLEGAL_SYMBOL_NAME: - cerr << "[ERROR] Line " << lineNo+1 << ", Col " << colNo+1 - << ": Symbolic name contains un-printable char(" << errInt - << ")!!" << endl; - break; - case MISSING_NUM: - cerr << "[ERROR] Line " << lineNo+1 << ", Col " << colNo+1 - << ": Missing " << errMsg << "!!" << endl; - break; - case MISSING_IDENTIFIER: - cerr << "[ERROR] Line " << lineNo+1 << ": Missing \"" - << errMsg << "\"!!" << endl; - break; - case MISSING_NEWLINE: - cerr << "[ERROR] Line " << lineNo+1 << ", Col " << colNo+1 - << ": A new line is expected here!!" << endl; - break; - case MISSING_DEF: - cerr << "[ERROR] Line " << lineNo+1 << ": Missing " << errMsg - << " definition!!" << endl; - break; - case CANNOT_INVERTED: - cerr << "[ERROR] Line " << lineNo+1 << ", Col " << colNo+1 - << ": " << errMsg << " " << errInt << "(" << errInt/2 - << ") cannot be inverted!!" << endl; - break; - case MAX_LIT_ID: - cerr << "[ERROR] Line " << lineNo+1 << ", Col " << colNo+1 - << ": Literal \"" << errInt << "\" exceeds maximum valid ID!!" - << endl; - break; - case REDEF_GATE: - cerr << "[ERROR] Line " << lineNo+1 << ": Literal \"" << errInt - << "\" is redefined, previously defined as " - << errGate->getTypeStr() << " in line " << errGate->getLineNo() - << "!!" << endl; - break; - case REDEF_SYMBOLIC_NAME: - cerr << "[ERROR] Line " << lineNo+1 << ": Symbolic name for \"" - << errMsg << errInt << "\" is redefined!!" << endl; - break; - case REDEF_CONST: - cerr << "[ERROR] Line " << lineNo+1 << ", Col " << colNo+1 - << ": Cannot redefine constant (" << errInt << ")!!" << endl; - break; - case NUM_TOO_SMALL: - cerr << "[ERROR] Line " << lineNo+1 << ": " << errMsg - << " is too small (" << errInt << ")!!" << endl; - break; - case NUM_TOO_BIG: - cerr << "[ERROR] Line " << lineNo+1 << ": " << errMsg - << " is too big (" << errInt << ")!!" << endl; - break; - default: break; - } - return false; -} - -static void -getErrorToken(char *tmp) -{ - assert(!isspace(*tmp)); - char *end = tmp; - while ((*(++end) != 0) && !isspace(*end)); - *end = 0; - errMsg = tmp; -} - -// Read the number until space character is encountered. -// If any non-digit or non-space char is encountered, return false. -// In the end, colNo will point to the non-digit character. -static bool -getUint(unsigned& num, const string& numType) -{ - if (buf[colNo] == 0) { - errMsg = numType; return parseError(MISSING_NUM); } - assert(!isspace(buf[colNo])); - char *tmp = buf + colNo; - num = 0; - do { - if (!isdigit(buf[colNo])) { - getErrorToken(tmp); - errMsg = numType + "(" + errMsg + ")"; - return parseError(ILLEGAL_NUM); - } - num *= 10; - num += unsigned(buf[colNo] - '0'); - if (buf[++colNo] == 0 || isspace(buf[colNo])) break; - } while (!isspace(buf[colNo])); - return true; -} - -// colNo will be updated!! -// Check if tmp contains identifier. -// However, does not check if tmp contains extra char. -static bool checkIdentifier(const char* identifier) -{ - char *tmp = buf + colNo; - if (*tmp == 0) { - errMsg = identifier; return parseError(MISSING_IDENTIFIER); - } - for (int i = 0, len = strlen(identifier); i < len; ++i, ++colNo) - if (buf[colNo] == 0 || buf[colNo] != identifier[i]) { - getErrorToken(tmp); return parseError(ILLEGAL_IDENTIFIER); } - return true; -} - -// If leadSpace == true, the first char is a space. <== colNo will ++ -// The followed char cannot be any white space char. -// Make sure buf[colNo] != 0 (after the leading WS) -static bool checkWS(bool leadSpace) -{ - if (leadSpace) { - if (buf[colNo] == 0 || buf[colNo] != ' ') - return parseError(MISSING_SPACE); - ++colNo; - } - if (buf[colNo] == ' ') return parseError(EXTRA_SPACE); - if (isspace(buf[colNo])) { - errInt = int(buf[colNo]); return parseError(ILLEGAL_WSPACE); } - return true; -} - -/**************************************************************/ -/* class CirMgr member functions for circuit construction */ -/**************************************************************/ -bool -CirMgr::readCircuit(const string& fileName) -{ - ifstream cirin(fileName.c_str()); - if (!cirin) { - cerr << "Cannot open design \"" << fileName << "\"!!" << endl; - return false; - } - lineNo = 0; colNo = 0; - if (!parseHeader(cirin)) return false; - if (!parseInput(cirin)) return false; - if (!parseLatch(cirin)) return false; - if (!parseOutput(cirin)) return false; - if (!parseAig(cirin)) return false; - if (!parseSymbol(cirin)) return false; - if (!parseComment(cirin)) return false; - genConnections(); - - genDfsList(); - - checkFloatList(); - checkUnusedList(); - - return true; -} - -void -CirMgr::deleteCircuit() -{ - if (_totGateList) - for (unsigned i = 1, n = getNumTots(); i < n; ++i) - if (_totGateList[i]) delete _totGateList[i]; - if (_piList) { delete []_piList; _piList = 0; } - if (_poList) { delete []_poList; _poList = 0; } - if (_totGateList) { delete []_totGateList; _totGateList = 0; } - if (_fanoutInfo) { delete []_fanoutInfo; _fanoutInfo = 0; } - clearList(_undefList); - clearList(_floatList); - clearList(_unusedList); - clearList(_dfsList); -// delete _const0; -// _const0 = new CirConstGate(0); - if (!_fecGrps.empty()) - for (unsigned i = 0, n = _fecGrps.size(); i < n; ++i) - delete _fecGrps[i]; - clearList >(_fecGrps); - for (size_t i = 0, np = _fecVector.size(); i < np; ++i) - delete []_fecVector[i]; - clearList(_fecVector); - delete _simLog; - resetFlag(); -} - -bool -CirMgr::parseHeader(ifstream& cirin) -{ - assert (lineNo == 0 && colNo == 0); - cirin.getline(buf, 1024); - - // aag M I L O A - const int aagLength = 3; - if (!checkWS(false)) return false; - if (!checkIdentifier("aag")) return false; - - string portStr[TOT_PARSE_PORTS] = { "number of variables", "number of PIs", - "number of latches", "number of POs", "number of AIGs" }; - // Need to check 0; otherwise getErrorToken(buf) will seg fault - if (buf[aagLength] == 0) { - errMsg = portStr[VARS]; return parseError(MISSING_NUM); } - // Take care "aagkk", but not "aag3", nor "aag" - if (!isspace(buf[aagLength]) && !isdigit(buf[aagLength])) { - getErrorToken(buf); return parseError(ILLEGAL_IDENTIFIER); } - - colNo = aagLength; - for (int i = 0; i < TOT_PARSE_PORTS; ++i) { - if (buf[colNo] == 0) { - errMsg = portStr[i]; return parseError(MISSING_NUM); } - if (!checkWS(true)) return false; - if (!getUint(_numDecl[i], portStr[i])) return false; - } - if (buf[colNo] != 0) return parseError(MISSING_NEWLINE); - - // Check numbers - // M must >= I + L + A - if (_numDecl[VARS] < _numDecl[PI] + _numDecl[LATCH] + _numDecl[AIG]) { - errMsg = "Number of variables"; errInt = _numDecl[VARS]; - return parseError(NUM_TOO_SMALL); - } - // L must = 0 - // if (_numDecl[LATCH] != 0) { - // errMsg = "latches"; return parseError(ILLEGAL_NUM); - // } - - // Create lists - _piList = new CirPiGate*[_numDecl[PI]]; - _poList = new CirPoGate*[_numDecl[PO]]; - _riList = new CirRiGate*[_numDecl[LATCH]]; - _roList = new CirRoGate*[_numDecl[LATCH]]; - // +1 for const - unsigned numTots = getNumTots(); - _totGateList = new CirGate*[numTots]; - for (unsigned i = 0; i < numTots; ++i) - _totGateList[i] = 0; - _fanoutInfo = new GateList[numTots]; - - _totGateList[0] = _const0; - - return true; -} - -bool CirMgr::parseInput(ifstream& cirin) -{ - for (size_t i = 0, n = _numDecl[PI]; i < n; ++i) { - ++lineNo; colNo = 0; - cirin.getline(buf, 1024); - if (cirin.eof()) { errMsg = "PI"; return parseError(MISSING_DEF); } - if (!checkWS(false)) return false; - unsigned litId; - CirGate *gate = checkGate(litId, PI, "PI"); - if (!gate) return false; - _piList[i] = static_cast(gate); - _totGateList[litId/2] = gate; - if (buf[colNo] != 0) return parseError(MISSING_NEWLINE); - } - - return true; -} - -// parse latch funciton, written by Andrew -bool CirMgr::parseLatch(ifstream& cirin) -{ - cout << "parse latch" << endl; - size_t roId = _numDecl[VARS] + 1; - for (size_t i = 0, nRo = _numDecl[LATCH]; i < nRo; ++i, ++roId) { - ++lineNo; colNo = 0; - cirin.getline(buf, 1024); - if (cirin.eof()) { errMsg = "RO"; return parseError(MISSING_DEF); } - if (!checkWS(false)) return false; - unsigned litId; - CirGate *gate = checkGate(litId, LATCH, "LATCH"); - _roList[i] = static_cast(gate); - _totGateList[litId/2] = gate; - if (buf[colNo] != 0) return parseError(MISSING_NEWLINE); - } - - size_t riId = _numDecl[VARS] + 1; - for (size_t i = 0, nRi = _numDecl[LATCH]; i < nRi; ++i, ++riId) { - ++lineNo; colNo = 0; - cirin.getline(buf, 1024); - if (cirin.eof()) { errMsg = "RI"; return parseError(MISSING_DEF); } - if (!checkWS(false)) return false; - unsigned litId; - if (!checkId(litId, "RI")) return false; - CirGate *gate = new CirRiGate(roId, lineNo+1, litId); - _riList[i] = static_cast(gate); - _totGateList[riId] = gate; - if (buf[colNo] != 0) return parseError(MISSING_NEWLINE); - } - - return true; -} - -bool CirMgr::parseOutput(ifstream& cirin) -{ - size_t poId = _numDecl[VARS] + 1; - for (size_t i = 0, nPo = _numDecl[PO]; i < nPo; ++i, ++poId) { - // ++lineNo; colNo = 0; - // cirin.getline(buf, 1024); - // if (cirin.eof()) { errMsg = "PO"; return parseError(MISSING_DEF); } - // if (!checkWS(false)) return false; - unsigned litId; - // if (!checkId(litId, "PO")) return false; - CirGate *gate = new CirPoGate(poId, lineNo+1, litId); - _poList[i] = static_cast(gate); - _totGateList[poId] = gate; - // if (buf[colNo] != 0) return parseError(MISSING_NEWLINE); - } - - return true; -} - -bool CirMgr::parseAig(ifstream& cirin) -{ - for (size_t i = 0, n = _numDecl[AIG]; i < n; ++i) { - ++lineNo; colNo = 0; - cirin.getline(buf, 1024); - if (cirin.eof()) { errMsg = "AIG"; return parseError(MISSING_DEF); } - if (!checkWS(false)) return false; - unsigned litId; - CirGate *gate = checkGate(litId, AIG, "AIG gate"); - if (!gate) return false; - _totGateList[litId/2] = gate; - unsigned in[2]; - for (int j = 0; j < 2; ++j) { - if (!checkWS(true)) return false; - if (!checkId(in[j], "AIG input")) return false; - } - if (buf[colNo] != 0) return parseError(MISSING_NEWLINE); - // set _in0, _in1 as litId for now. Convert to gateId when connected - static_cast(gate)->setIn0(in[0]); - static_cast(gate)->setIn1(in[1]); - } - return true; -} - -bool CirMgr::parseSymbol(ifstream& cirin) -{ - while (1) { - // Read in next line!! - ++lineNo; colNo = 0; - cirin.getline(buf, 1024); - if (cirin.eof()) return true; - char type = buf[colNo]; - if (type == 'i' || type == 'l' || type == 'o') { - ++colNo; - if (!checkWS(false)) return false; - unsigned portId; - if (!getUint(portId, "symbol index")) return false; - if (buf[colNo] == 0) { - errMsg = "symbolic name"; return parseError(MISSING_IDENTIFIER); } - if (buf[colNo] == ' ') { - if (buf[++colNo] == 0) { - errMsg = "symbolic name"; - return parseError(MISSING_IDENTIFIER); - } - } - else - return parseError(MISSING_SPACE); - char *str = buf + colNo; - for (; buf[colNo] != 0; ++colNo) { - if (!isprint(buf[colNo])) { - errInt = int(buf[colNo]); - return parseError(ILLEGAL_SYMBOL_NAME); - } - } - if (type == 'i') { - if (portId >= _numDecl[PI]) { - errMsg = "PI index"; errInt = portId; - return parseError(NUM_TOO_BIG); - } - CirPiGate *pi = _piList[portId]; - if (pi->getName()) { - errMsg = "i"; errInt = portId; - return parseError(REDEF_SYMBOLIC_NAME); - } - char *n = new char[strlen(str)+1]; strcpy(n, str); - pi->setName(n); - } - else if (type == 'l') {// ... NOT supported yet (trying to support now XD) - assert(type == 'l'); - if (portId >= _numDecl[LATCH]) { - errMsg = "LATCH index"; errInt = portId; - return parseError(NUM_TOO_BIG); - } - CirRiGate *ri = _riList[portId]; - CirRoGate *ro = _roList[portId]; - if (ri->getName()) { - errMsg = "l"; errInt = portId; - return parseError(REDEF_SYMBOLIC_NAME); - } - if (ro->getName()) { - errMsg = "l"; errInt = portId; - return parseError(REDEF_SYMBOLIC_NAME); - } - char *n = new char[strlen(str)+1]; strcpy(n, str); - ri->setName(n); - ro->setName(n); - } - else { // if (type == 'o') - assert(type == 'o'); - if (portId >= _numDecl[PO]) { - errMsg = "PO index"; errInt = portId; - return parseError(NUM_TOO_BIG); - } - CirPoGate *po = _poList[portId]; - if (po->getName()) { - errMsg = "o"; errInt = portId; - return parseError(REDEF_SYMBOLIC_NAME); - } - char *n = new char[strlen(str)+1]; strcpy(n, str); - po->setName(n); - } - } - else if (type == 'c') return true; - else if (type == ' ') return parseError(EXTRA_SPACE); - else if (isspace(type)) { - errInt = int(type); return parseError(ILLEGAL_WSPACE); } - else { - errMsg.resize(1); errMsg[0] = type; - return parseError(ILLEGAL_SYMBOL_TYPE); - } - } - return true; -} - -bool CirMgr::parseComment(ifstream& cirin) -{ - // The first comment line should have been read - if (cirin.eof()) return true; - char type = buf[colNo]; - assert(type == 'c'); - if (buf[++colNo] != 0) return parseError(MISSING_NEWLINE); - - return true; -} - -bool -CirMgr::checkId(unsigned& litId, const string& err) -{ - unsigned oldColNo = colNo; - if (!getUint(litId, err + " literal ID")) return false; - if (litId/2 > _numDecl[VARS]) { - errInt = litId; colNo = oldColNo; return parseError(MAX_LIT_ID); - } - return true; -} - -// For PI and AIG and LATCH(Ro) gates only!! -CirGate* -CirMgr::checkGate(unsigned& litId, ParsePorts type, const string& err) -{ - unsigned oldColNo = colNo; - if (!checkId(litId, err)) return 0; - if (litId < 2) { errInt = litId; colNo = oldColNo; - parseError(REDEF_CONST); return 0; } - if (litId % 2 != 0) { - errMsg = err; errInt = litId; colNo = oldColNo; - parseError(CANNOT_INVERTED); return 0; - } - CirGate *gate = _totGateList[litId/2]; - if (gate != 0) { - errInt = litId; errGate = gate; colNo = oldColNo; - parseError(REDEF_GATE); return 0; - } - switch (type) { - case PI: gate = new CirPiGate(litId/2, lineNo+1); break; - case AIG: gate = new CirAigGate(litId/2, lineNo+1); break; - case LATCH: gate = new CirRoGate(litId/2, lineNo+1); break; - default: cerr << "Error: Unknown gate type (" << type << ")!!\n"; - exit(-1); - } - return gate; -} -// v is the litId to connect -// Create an CirUndefGate if getGate() return 0 -size_t -CirMgr::checkConnectedGate(size_t v) -{ - size_t ret; - CirGate *g = getGate(v/2); - if (!g) { - g = new CirUndefGate(v/2); - _totGateList[v/2] = g; - _undefList.push_back(v/2); - } - ret = size_t(g); - if (g->isUndef()) ret += CirGateV::AIG_FLT_FANIN; - ret += (v & CirGateV::AIG_NEG_FANIN); - return ret; +/*gv::cir::CirMgr* cirMgr = 0;*/ +/*gv::cir::CirGate* gv::cir::CirMgr::_const0 = new CirConstGate(0);*/ + +gv::cir::CirMgr* cirMgr = 0; +gv::cir::CirGate* gv::cir::CirMgr::_const0 = new CirConstGate(0); + +namespace gv { +namespace cir { + +bool CirMgr::readCircuitNew() { + map id2Name; + engine::ABCParams params; + strcpy(params.pFileName, _fileName.c_str()); + if (_fileType == AIGER) { + _ysyMgr->readAiger(_fileName); + _abcMgr->readAiger(params); + _abcMgr->initCir(_fileType); + _abcMgr->travPreprocess(); + _abcMgr->giaToCir(_fileType, id2Name); + genDfsList(); + } else if (_fileType == VERILOG) { + params.fTechMap = 1; + params.fVerbose = 0; + // _ysyMgr->setLogging(true); + _ysyMgr->readVerilog(_fileName); + _ysyMgr->createMapping(_fileName); + // _abcMgr->readSeqVerilog(params); + _abcMgr->readVerilogNew(params); + _abcMgr->buildAigName(id2Name); + _abcMgr->initCir(_fileType); + _abcMgr->travPreprocess(); + _abcMgr->giaToCir(_fileType, id2Name); + genDfsList(); + } + /* else if (_fileType == BLIF) {*/ + /* _ysyMgr->readBlif(_fileName);*/ + /*}*/ + return true; +} + +bool CirSeq::readCircuit() { + map id2Name; + engine::ABCParams params; + strcpy(params.pFileName, _fileName.c_str()); + if (_fileType == AIGER) { + _ysyMgr->readAiger(_fileName); + _abcMgr->readAiger(params); + } else if (_fileType == BLIF) { + _ysyMgr->readBlif(_fileName); + } else if (_fileType == VERILOG) { + params.fTechMap = 1; + params.fVerbose = 0; + // _ysyMgr->setLogging(true); + _ysyMgr->readVerilog(_fileName); + _ysyMgr->createMapping(_fileName); + // _abcMgr->readSeqVerilog(params); + _abcMgr->readVerilogNew(params); + _abcMgr->buildAigName(id2Name); + _abcMgr->initCir(_fileType); + _abcMgr->travPreprocess(); + _abcMgr->giaToCir(_fileType, id2Name); + genDfsList(); + } + return true; +} + +bool CirComb::readCircuit() { + // ABCParams params; + // strcpy(params.pFileName, _fileName.c_str()); + // _abcMgr->readCombVerilog(params); + _ysyMgr->readVerilog(_fileName); + fmt::print("REG NUM: {0}", _ysyMgr->getNumREGs()); + return true; +} + +void CirMgr::deleteCircuit() { + _piList.clear(); + _poList.clear(); + _roList.clear(); + _riList.clear(); + _aigList.clear(); + _dfsList.clear(); + _totGateList.clear(); + // clearList(_dfsList); + // clearList(_totGateList); + if (_fanoutInfo) { + delete[] _fanoutInfo; + _fanoutInfo = 0; + } + delete _abcMgr; + delete _ysyMgr; + // delete _const1; + // delete _const0; + // _const0 = new CirConstGate(0); +} + +void CirMgr::genDfsList() { + clearList(_dfsList); + CirGate::setGlobalRef(); + for (unsigned i = 0, n = getNumPOs(); i < n; ++i) + getPo(i)->genDfsList(_dfsList); + + for (unsigned i = 0, n = getNumLATCHs(); i < n; ++i) + getRi(i)->genDfsList(_dfsList); +} + +void CirPiGate::genDfsList(GateVec& gateList) { + setToGlobalRef(); + gateList.push_back(this); +} + +void CirRoGate::genDfsList(GateVec& gateList) { + setToGlobalRef(); + gateList.push_back(this); +} + +void CirPoGate::genDfsList(GateVec& gateList) { + setToGlobalRef(); + CirGate* g = _in0.gate(); + if (!g->isGlobalRef()) + g->genDfsList(gateList); + gateList.push_back(this); +} + +void CirRiGate::genDfsList(GateVec& gateList) { + setToGlobalRef(); + CirGate* g = _in0.gate(); + if (!g->isGlobalRef()) + g->genDfsList(gateList); + gateList.push_back(this); +} + +void CirAigGate::genDfsList(GateVec& gateList) { + setToGlobalRef(); + CirGate* g = _in0.gate(); + // cout << g->getGid()<isGlobalRef()) + g->genDfsList(gateList); + g = _in1.gate(); + // cout << g->getGid()<isGlobalRef()) + g->genDfsList(gateList); + gateList.push_back(this); +} + +void CirConstGate::genDfsList(GateVec& gateList) { + setToGlobalRef(); + gateList.push_back(this); } - -void -CirMgr::genConnections() -{ - for (unsigned i = 0, n = getNumTots(); i < n; ++i) { - CirGate *gate = _totGateList[i]; - if (gate) gate->genConnections(); - } -} - -void -CirPoGate::genConnections() -{ - // _in0 = cirMgr->checkConnectedGate(_in0()); - // cout << "_in0 = " << _in0 << endl; - // cirMgr->getFanouts(_in0.gateId()).push_back(this); -} - -void -CirRiGate::genConnections() -{ - _in0 = cirMgr->checkConnectedGate(_in0()); - // cirMgr->getFanouts(_in0.gateId()).push_back(this); -} - -void -CirAigGate::genConnections() -{ - // _in0 = cirMgr->checkConnectedGate(_in0()); - // cirMgr->getFanouts(_in0.gateId()).push_back(this); - // _in1 = cirMgr->checkConnectedGate(_in1()); - // cirMgr->getFanouts(_in1.gateId()).push_back(this); -} - -void -CirMgr::genDfsList() -{ - clearList(_dfsList); - CirGate::setGlobalRef(); - for (unsigned i = 0, n = getNumPOs(); i < n; ++i) - getPo(i)->genDfsList(_dfsList); -} - -void -CirPiGate::genDfsList(GateList& gateList) -{ - setToGlobalRef(); - gateList.push_back(this); -} - -void -CirRoGate::genDfsList(GateList& gateList) -{ - setToGlobalRef(); - gateList.push_back(this); -} - -void -CirPoGate::genDfsList(GateList& gateList) -{ - setToGlobalRef(); - CirGate* g = _in0.gate(); - if (!g->isGlobalRef()) - g->genDfsList(gateList); - gateList.push_back(this); -} - -void -CirRiGate::genDfsList(GateList& gateList) -{ - setToGlobalRef(); - CirGate* g = _in0.gate(); - if (!g->isGlobalRef()) - g->genDfsList(gateList); - gateList.push_back(this); -} - -void -CirAigGate::genDfsList(GateList& gateList) -{ - setToGlobalRef(); - CirGate* g = _in0.gate(); - if (!g->isGlobalRef()) - g->genDfsList(gateList); - g = _in1.gate(); - if (!g->isGlobalRef()) - g->genDfsList(gateList); - gateList.push_back(this); -} - -void -CirConstGate::genDfsList(GateList& gateList) -{ - setToGlobalRef(); - gateList.push_back(this); -} - -// Remove the entries that getGate() = NULL -void -CirMgr::updateUndefList() -{ - size_t i = 0; - for (size_t j = 0, n = _undefList.size(); j< n; ++j) { - if (!getGate(_undefList[j])) continue; // has been deleted - if (_fanoutInfo[_undefList[j]].empty()) { - deleteUndefGate(getGate(_undefList[j])); - continue; - } - if (i != j) _undefList[i] = _undefList[j]; - ++i; - } - if (i == 0) clearList(_undefList); - else _undefList.resize(i); -} - -void -CirMgr::checkFloatList() -{ - clearList(_floatList); - CirGate::setGlobalRef(); - for (size_t i = 0, n = _undefList.size(); i< n; ++i) { - const GateList& fanouts = _fanoutInfo[_undefList[i]]; - for (size_t j = 0, m = fanouts.size(); j < m; ++j) - if (!fanouts[j]->isGlobalRef()) { - fanouts[j]->setToGlobalRef(); - _floatList.push_back(fanouts[j]->getGid()); - } - } - sort(_floatList.begin(), _floatList.end()); -} - -void -CirMgr::checkUnusedList() -{ - clearList(_unusedList); - for (size_t i = 1, n = getNumTots(); i < n; ++i) - if (_fanoutInfo[i].empty() && _totGateList[i]) -// if (!_totGateList[i]->isPo() && !_totGateList[i]->isPi()) - if (!_totGateList[i]->isPo()) - _unusedList.push_back(i); -} - -CirGateV -CirMgr::litId2GateV(unsigned litId) const -{ - return size_t(litId2Gate(litId)) + litId%2; -} - /**********************************************************/ /* class CirMgr member functions for circuit printing */ /**********************************************************/ @@ -736,228 +190,125 @@ Circuit Statistics ------------------ Total 162 *********************/ -void -CirMgr::printSummary() const -{ - cout << endl; - cout << "Circuit Statistics" << endl - << "==================" << endl; - unsigned tot = 0; - tot += _numDecl[PI]; - cout << " " << setw(7) << left << "PI" - << setw(7) << right << _numDecl[PI] << endl; - tot += _numDecl[PO]; - cout << " " << setw(7) << left << "PO" - << setw(7) << right << _numDecl[PO] << endl; - tot += _numDecl[LATCH]; - cout << " " << setw(7) << left << "LATCH" - << setw(7) << right << _numDecl[LATCH] << endl; - tot += _numDecl[AIG]; - cout << " " << setw(7) << left << "AIG" - << setw(7) << right << _numDecl[AIG] << endl; - cout << "------------------" << endl; - cout << " Total " << setw(7) << right << tot << endl; -} - -void -CirMgr::printNetlist() const -{ - cout << endl; - for (unsigned i = 0, n = _dfsList.size(); i < n; ++i) { - cout << "[" << i << "] "; - _dfsList[i]->printGate(); - } -} - -void -CirMgr::printPIs() const -{ - cout << "PIs of the circuit:"; - for (unsigned i = 0, n = getNumPIs(); i < n; ++i) - cout << " " << getPi(i)->getGid(); - cout << endl; -} - -void -CirMgr::printPOs() const -{ - cout << "POs of the circuit:"; - for (unsigned i = 0, n = getNumPOs(); i < n; ++i) - cout << " " << getPo(i)->getGid(); - cout << endl; -} - -void -CirMgr::printFloatGates() const -{ - size_t fn = _floatList.size(); - if (fn) { - cout << "Gates with floating fanin(s):"; - for (size_t i = 0; i < fn; ++i) - cout << " " << _floatList[i]; - cout << endl; - } - size_t un = _unusedList.size(); - if (un) { - cout << "Gates defined but not used :"; - for (size_t i = 0; i < un; ++i) - cout << " " << _unusedList[i]; - cout << endl; - } -} - -void -CirMgr::printFECPairs() const -{ - struct ArrIdx { - unsigned _litId; - size_t _idx; - ArrIdx(unsigned l, size_t i): _litId(l), _idx(i) {} - bool operator < (const ArrIdx& i) const { return (_litId < i._litId); } - }; - vector fecOrder; - for (size_t i = 0, n = _fecGrps.size(); i < n; ++i) - fecOrder.push_back(ArrIdx((_fecGrps[i])->operator[](0), i)); - ::sort(fecOrder.begin(), fecOrder.end()); - for (size_t i = 0, n = fecOrder.size(); i < n; ++i) { - size_t idx = fecOrder[i]._idx; - IdList *ll = _fecGrps[idx]; - cout << "[" << i << "]"; - for (size_t j = 0, m = ll->size(); j < m; ++j) - cout << " " << litId2GateV((*ll)[j]); - cout << endl; - } -} - -void -CirMgr::writeAag(ostream& outfile) const -{ - size_t nAig = 0; - for (size_t i = 0, n = _dfsList.size(); i < n; ++i) - if (_dfsList[i]->isAig()) ++nAig; - outfile << "aag " << _numDecl[VARS] << " " << _numDecl[PI] << " " - << _numDecl[LATCH] << " " << _numDecl[PO] << " " - << nAig << endl; - for (size_t i = 0, n = _numDecl[PI]; i < n; ++i) - outfile << (getPi(i)->getGid()*2) << endl; - for (size_t i = 0, n = _numDecl[PO]; i < n; ++i) - outfile << getPo(i)->getIn0().litId() << endl; - for (size_t i = 0, n = _dfsList.size(); i < n; ++i) { - CirGate *g = _dfsList[i]; - if (!g->isAig()) continue; - outfile << g->getGid()*2 << " " << g->getIn0().litId() << " " - << g->getIn1().litId() << endl; - } - for (size_t i = 0, n = _numDecl[PI]; i < n; ++i) - if (getPi(i)->getName()) - outfile << "i" << i << " " << getPi(i)->getName() << endl; - for (size_t i = 0, n = _numDecl[PO]; i < n; ++i) - if (getPo(i)->getName()) - outfile << "o" << i << " " << getPo(i)->getName() << endl; - outfile << "c" << endl; - outfile << "AAG output by Chung-Yang (Ric) Huang" << endl; -} - -void -CirMgr::writeGate(ostream& outfile, CirGate *g) const -{ - GateList faninCone; - CirGate::setGlobalRef(); - g->genDfsList(faninCone); - - size_t nAig = 0, npi = 0; - unsigned maxId = 0; - for (size_t i = 0, n = faninCone.size(); i < n; ++i) { - if (faninCone[i]->isAig()) ++nAig; - else if (faninCone[i]->isPi()) ++npi; - if (faninCone[i]->getGid() > maxId) maxId = faninCone[i]->getGid(); - } - outfile << "aag " << maxId << " " << npi << " 0 1 " << nAig << endl; - for (size_t i = 0, n = _numDecl[PI]; i < n; ++i) - if (getPi(i)->isGlobalRef()) - outfile << (getPi(i)->getGid()*2) << endl; - outfile << g->getGid()*2 << endl; - for (size_t i = 0, n = faninCone.size(); i < n; ++i) { - CirGate *f = faninCone[i]; - if (!f->isAig()) continue; - outfile << f->getGid()*2 << " " << f->getIn0().litId() << " " - << f->getIn1().litId() << endl; - } - for (size_t i = 0, n = _numDecl[PI], j = 0; i < n; ++i) - if (getPi(i)->isGlobalRef() && getPi(i)->getName()) - outfile << "i" << j++ << " " << getPi(i)->getName() << endl; - outfile << "o0 " << g->getGid() << endl; - outfile << "c" << endl; - outfile << "Write gate (" << g->getGid() - << ") by Chung-Yang (Ric) Huang" << endl; -} - - -/**********************************************************/ -/* class CirMgr member functions for hidden commands */ -/**********************************************************/ -// After this command, cm1 and cm2 will be deleted!! -bool -CirMgr::createMiter(CirMgr *cm1, CirMgr *cm2) -{ - ofstream outfile("/tmp/miter.aag"); - size_t npi = cm1->_numDecl[PI]; - size_t npo = cm1->_numDecl[PO]; - size_t nVarO = cm1->_numDecl[VARS] + cm2->_numDecl[VARS] + 1; - size_t nVar = nVarO + 3*npo; - size_t nAig1 = 0, nAig2 = 0; - for (size_t i = 0, n = cm1->_dfsList.size(); i < n; ++i) - if (cm1->_dfsList[i]->isAig()) ++nAig1; - for (size_t i = 0, n = cm2->_dfsList.size(); i < n; ++i) - if (cm2->_dfsList[i]->isAig()) ++nAig2; - size_t nAig = nAig1 + nAig2 + 3*npo; - size_t vOffset = cm1->_numDecl[VARS] + 1; - outfile << "aag " << nVar << " " << npi << " 0 " << npo << " " - << nAig << endl; - for (size_t i = 0; i < npi; ++i) - outfile << (cm1->getPi(i)->getGid()*2) << endl; - for (size_t i = 0; i < npo; ++i) - outfile << (nVarO+3+i*3)*2 << endl; - for (size_t i = 0, n = cm1->_dfsList.size(); i < n; ++i) { - CirGate *g = cm1->_dfsList[i]; - if (!g->isAig()) continue; - outfile << g->getGid()*2 << " " << g->getIn0().litId() << " " - << g->getIn1().litId() << endl; - } - for (size_t i = 0, n = cm2->_dfsList.size(); i < n; ++i) { - CirGate *g = cm2->_dfsList[i]; - if (!g->isAig()) continue; - outfile << (g->getGid() + vOffset)*2; - if (g->getIn0Gate()->isAig()) - outfile << " " << (g->getIn0().litId() + vOffset*2) << " "; - else - outfile << " " << g->getIn0().litId() << " "; - if (g->getIn1Gate()->isAig()) - outfile << (g->getIn1().litId() + vOffset*2) << endl; - else - outfile << g->getIn1().litId() << endl; - } - for (size_t i = 0, j = nVarO + 1; i < npo; ++i, j += 3) { - unsigned po1 = cm1->getPo(i)->getIn0().litId(); - unsigned po2 = cm2->getPo(i)->getIn0Gate()->isAig()? - cm2->getPo(i)->getIn0().litId() + vOffset * 2: - cm2->getPo(i)->getIn0().litId(); - outfile << j*2 << " " << po1 << " " << po2 << endl; - outfile << (j+1)*2 << " " << (po1^0x1) << " " << (po2^0x1) << endl; - outfile << (j+2)*2 << " " << j*2+1 << " " << (j+1)*2+1 << endl; - } - for (size_t i = 0; i < npi; ++i) - if (cm1->getPi(i)->getName()) - outfile << "i" << i << " " << cm1->getPi(i)->getName() << endl; - for (size_t i = 0; i < npo; ++i) - if (cm1->getPo(i)->getName()) - outfile << "o" << i << " " << cm1->getPo(i)->getName() << endl; - outfile << "c" << endl; - outfile << "Miter output by Chung-Yang (Ric) Huang" << endl; - - outfile.close(); - - deleteCircuit(); - return readCircuit("/tmp/miter.aag"); -} - +void CirMgr::printSummary() const { + cout << endl; + cout << "Circuit Statistics" << endl + << "==================" << endl; + unsigned tot = _totGateList.size(); + unsigned sum = 0; + sum += _piList.size(); + cout << " " << setw(7) << left << "PI" + << setw(7) << right << _piList.size() << endl; + sum += _poList.size(); + cout << " " << setw(7) << left << "PO" + << setw(7) << right << _poList.size() << endl; + sum += _roList.size(); + cout << " " << setw(7) << left << "LATCH" + << setw(7) << right << _roList.size() << endl; + // tot += _numDecl[AIG]; + cout << " " << setw(7) << left << "AIG" + << setw(7) << right << tot - sum << endl; + cout << "------------------" << endl; + cout << " Total " << setw(7) << right << tot << endl; +} + +void CirMgr::printNetlist() const { + cout << endl; + for (unsigned i = 0, n = _dfsList.size(); i < n; ++i) { + // GateType type = _dfsList[i]->getType(); + // if (!(type == RO_GATE) && !(type == RI_GATE)) + // continue; + cout << "[" << i << "] "; + _dfsList[i]->printGate(); + } +} + +void CirMgr::printPIs() const { + cout << "PIs of the circuit:"; + for (unsigned i = 0, n = getNumPIs(); i < n; ++i) + cout << " " << getPi(i)->getGid(); + cout << endl; +} + +void CirMgr::printPOs() const { + cout << "POs of the circuit:"; + for (unsigned i = 0, n = getNumPOs(); i < n; ++i) + cout << " " << getPo(i)->getGid(); + cout << endl; +} + +void CirMgr::writeAag(ostream& outfile) const { + size_t nAig = 0; + for (size_t i = 0, n = _dfsList.size(); i < n; ++i) + if (_dfsList[i]->isAig()) ++nAig; + outfile << "aag " << _numDecl[VARS] + nAig << " " << _numDecl[PI] << " " + << _numDecl[LATCH] << " " << _numDecl[PO] << " " + << nAig << endl; + for (size_t i = 0, n = _numDecl[PI]; i < n; ++i) + outfile << (getPi(i)->getGid() * 2) << endl; + + // Update Latch for sequential circuit. + for (size_t i = 0, n = _numDecl[LATCH]; i < n; ++i) + outfile << getRo(i)->getGid() * 2 << " " << getRi(i)->getIn0().litId() << endl; + + for (size_t i = 0, n = _numDecl[PO]; i < n; ++i) + outfile << getPo(i)->getIn0().litId() << endl; + for (size_t i = 0, n = _dfsList.size(); i < n; ++i) { + CirGate* g = _dfsList[i]; + if (!g->isAig()) continue; + outfile << g->getGid() * 2 << " " << g->getIn0().litId() << " " + << g->getIn1().litId() << endl; + } + for (size_t i = 0, n = _numDecl[PI]; i < n; ++i) + if (getPi(i)->getName()) + outfile << "i" << i << " " << getPi(i)->getName() << endl; + for (size_t i = 0, n = _numDecl[PO]; i < n; ++i) + if (getPo(i)->getName()) + outfile << "o" << i << " " << getPo(i)->getName() << endl; + outfile << "c" << endl; + outfile << "AAG output by Chung-Yang (Ric) Huang" << endl; +} + +void CirMgr::writeBlif(const string& fileName) const { + _ysyMgr->writeBlif(fileName); +} + +void CirMgr::writeGate(ostream& outfile, CirGate* g) const { + GateVec faninCone; + CirGate::setGlobalRef(); + g->genDfsList(faninCone); + + size_t nAig = 0, npi = 0; + unsigned maxId = 0; + for (size_t i = 0, n = faninCone.size(); i < n; ++i) { + if (faninCone[i]->isAig()) ++nAig; + else if (faninCone[i]->isPi()) ++npi; + if (faninCone[i]->getGid() > maxId) maxId = faninCone[i]->getGid(); + } + outfile << "aag " << maxId << " " << npi << " 0 1 " << nAig << endl; + // for (size_t i = 0, n = _numDecl[PI]; i < n; ++i) + for (size_t i = 0, n = cirMgr->getNumPIs(); i < n; ++i) + if (getPi(i)->isGlobalRef()) + outfile << (getPi(i)->getGid() * 2) << endl; + outfile << g->getGid() * 2 << endl; + for (size_t i = 0, n = faninCone.size(); i < n; ++i) { + CirGate* f = faninCone[i]; + if (!f->isAig()) continue; + outfile << f->getGid() * 2 << " " << f->getIn0().litId() << " " + << f->getIn1().litId() << endl; + } + for (size_t i = 0, n = cirMgr->getNumPIs(), j = 0; i < n; ++i) + if (getPi(i)->isGlobalRef() && getPi(i)->getName()) + outfile << "i" << j++ << " " << getPi(i)->getName() << endl; + outfile << "o0 " << g->getGid() << endl; + outfile << "c" << endl; + outfile << "Write gate (" << g->getGid() + << ") by Chung-Yang (Ric) Huang" << endl; +} + +const bool CirMgr::readBlif(const string& fileName) const { + _ysyMgr->init(); + _ysyMgr->readBlif(fileName); +} +} // namespace cir +} // namespace gv diff --git a/src/cir/cirMgr.h b/src/cir/cirMgr.h index 7f4b21a2..4e3a3b27 100644 --- a/src/cir/cirMgr.h +++ b/src/cir/cirMgr.h @@ -1,173 +1,183 @@ /**************************************************************************** - FileName [ cirMgr.h ] - PackageName [ cir ] - Synopsis [ Define circuit manager ] - Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2008-present LaDs(III), GIEE, NTU, Taiwan ] +FileName [ cirMgr.h ] +PackageName [ cir ] +Synopsis [ Define circuit manager ] +Author [ Chung-Yang (Ric) Huang ] +Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#ifndef CIR_MGR_H -#define CIR_MGR_H +#pragma once -#include -#include -#include #include +#include +#include -using namespace std; +#include "abcMgr.h" +#include "yosysMgr.h" + +// using namespace std; // TODO: Feel free to define your own classes, variables, or functions. +#include "gvType.h" + +extern gv::cir::CirMgr* cirMgr; + +namespace gv { +namespace abc { +class AbcMgr; +} // namespace abc +} // namespace gv + +namespace gv { +namespace cir { -#include "cirDef.h" -#include "base/abc/abc.h" +class CirMgr { + friend class CirComb; + friend class CirSeq; + enum CirMgrFlag { NO_FEC = 0x1 }; + enum ParsePorts { VARS = 0, + PI, + LATCH, + PO, + AIG, + TOT_PARSE_PORTS }; -extern CirMgr *cirMgr; +public: + CirMgr() : _piList(0), _poList(0), _totGateList(0), _fanoutInfo(0), + _abcMgr(new gv::engine::AbcMgr()), _ysyMgr(new YosysMgr()), _fileName("") {} + + virtual ~CirMgr() { deleteCircuit(); } + + // Access functions + CirGate* operator[](unsigned gid) const { return _totGateList[gid]; } + // return '0' if "gid" corresponds to an undefined gate. + CirGate* getGate(unsigned gid) const { + if (gid >= getNumTots()) { + return 0; + } + return _totGateList[gid]; + } + + void setFileName(const string& f) { _fileName = f; } + void setFileType(const FileType& t) { _fileType = t; } + + unsigned getNumLATCHs() const { return _riList.size(); } + // virtual unsigned getNumLATCHs() const { return 0; } + unsigned getNumPIs() const { return _piList.size(); } + unsigned getNumPOs() const { return _poList.size(); } + unsigned getNumAIGs() const { return _aigList.size(); } + unsigned getNumTots() const { return _totGateList.size(); } + + CirRiGate* getRi(unsigned i) const { return _riList[i]; } + CirRoGate* getRo(unsigned i) const { return _roList[i]; } + // virtual CirRiGate* getRi(unsigned i) const { return 0; } + // virtual CirRoGate* getRo(unsigned i) const { return 0; } + CirPiGate* getPi(unsigned i) const { return _piList[i]; } + CirPoGate* getPo(unsigned i) const { return _poList[i]; } + CirAigGate* getAig(unsigned i) const { return _aigList[i]; } + GateVec& getFanouts(unsigned i) const { return _fanoutInfo[i]; } + string getFileName() const { return _fileName; } + FileType getFileType() const { return _fileType; } + + // Member functions about circuit construction + // virtual bool readCircuit(){}; + virtual bool readCircuit() { return false; }; + bool readCircuitNew(); + void deleteCircuit(); + void genConnections(); + void genDfsList(); + void updateUndefList(); + void checkFloatList(); + void checkUnusedList(); + size_t checkConnectedGate(size_t); + + // Member functins about circuit reporting + void printSummary() const; + void printNetlist() const; + void printPIs() const; + void printPOs() const; + void writeAag(ostream&) const; + void writeBlif(const string&) const; + void writeGate(ostream&, CirGate*) const; + + // Member functions about flags + // for hidden command + bool createMiter(CirMgr*, CirMgr*); + static CirGate* _const0; + // MODIFICATION FOR SOCV HOMEWORK + void initCir(const int&, const int&, const int&, const int&); + void buildBdd(CirGate*); + void buildNtkBdd(); + void addTotGate(CirGate* gate) { _totGateList.push_back(gate); }; + const bool readCirFromAbc(string, FileType); + const bool readBlif(const string&) const; + const bool setBddOrder(const bool&); + + CirGate* createNotGate(CirGate*); + CirGate* createAndGate(CirGate*, CirGate*); + CirGate* createOrGate(CirGate*, CirGate*); + CirGate* createXorGate(CirGate*, CirGate*); + CirGate* _const1; + + // Member functions for creating gate from the Gia object + void createInput(const int& idx, const int& gateId); + void createOutput(const int& idx, const int& gateId, const int& in0Id, const int& inv, string poName); + void createRi(const int& idx, const int& gateId, const int& in0Id, const int& inv); + int createRo(const int& idx, const int& gateId, const FileType& fileType); + void createRiRo(const int& riGid, const int& roGid); + void createAig(const int& gateId, const int& in0Id, const int& in0Inv, const int& in1Id, const int& in1Inv); + void createConst0(); + void createConst1(); + + // Reorder the gate id for the ABC pAig + void reorderGateId(IDMap& aigIdMap); + + // Engine Manager Pointer + YosysMgr* getYosysMgr() { return _ysyMgr; } + gv::engine::AbcMgr* getAbcMgr() { return _abcMgr; } + +private: + // unsigned _numDecl[TOT_PARSE_PORTS]; + unsigned _numDecl[TOT_GATE]; + PiVec _piList; + PoVec _poList; + RiVec _riList; + RoVec _roList; + AigVec _aigList; + GateVec _totGateList; + GateVec _dfsList; + GateVec* _fanoutInfo; + string _fileName; + FileType _fileType; + // Engine Managers + gv::engine::AbcMgr* _abcMgr; + YosysMgr* _ysyMgr; +}; - enum CirFileType - { - VERILOG, - AIGER - }; +class CirComb : public CirMgr { +public: + CirComb() : CirMgr() {} + ~CirComb() override {} + CirType getCirType() { return CirType::COMB; } + bool readCircuit() override; -class CirMgr -{ - enum CirMgrFlag { NO_FEC = 0x1 }; - enum ParsePorts { VARS = 0, PI, LATCH, PO, AIG, TOT_PARSE_PORTS }; +private: +}; +class CirSeq : public CirMgr { public: - CirMgr(): _flag(0), _piList(0), _poList(0), _totGateList(0), - _fanoutInfo(0), _simLog(0) { } - ~CirMgr() { deleteCircuit(); } - - // Access functions - CirGate* operator [](unsigned gid) const { return _totGateList[gid]; } - // return '0' if "gid" corresponds to an undefined gate. - CirGate* getGate(unsigned gid) const { - if (gid >= getNumTots()) { return 0; } return _totGateList[gid]; } - CirGate* litId2Gate(unsigned litId) const { return getGate(litId/2); } - CirGateV litId2GateV(unsigned litId) const; - bool isFlag(CirMgrFlag f) const { return _flag & f; } - void setFlag(CirMgrFlag f) const { _flag |= f; } - void unsetFlag(CirMgrFlag f) const { _flag &= ~f; } - void resetFlag() const { _flag = 0; } - unsigned getNumPIs() const { return _numDecl[PI]; } - unsigned getNumPOs() const { return _numDecl[PO]; } - unsigned getNumLATCHs() const { return _numDecl[LATCH]; } - unsigned getNumTots() const { return _numDecl[VARS] + _numDecl[PO] + 1; } - CirPiGate* getPi(unsigned i) const { return _piList[i]; } - CirPoGate* getPo(unsigned i) const { return _poList[i]; } - CirRiGate* getRi(unsigned i) const { return _riList[i]; } - CirRoGate* getRo(unsigned i) const { return _roList[i]; } - GateList& getFanouts(unsigned i) const { return _fanoutInfo[i]; } - - // Member functions about circuit construction - bool readCircuit(const string&); - void deleteCircuit(); - void genConnections(); - void genDfsList(); - void updateUndefList(); - void checkFloatList(); - void checkUnusedList(); - size_t checkConnectedGate(size_t); - - // Member functions about circuit optimization - void sweep(); - void optimize(); - bool checkAigOptimize(CirGate*, const CirGateV&, const CirGateV&, - CirGateV&) const; - void deleteAigGate(CirGate *); - void deleteUndefGate(CirGate *); - - // Member functions about simulation - void randomSim(); - void fileSim(ifstream&); - void setSimLog(ofstream *logFile) { _simLog = logFile; } - - // Member functions about fraig - void strash(); - IdList* getFECGrps(size_t i) const { return _fecGrps[i]; } - void printFEC() const; - void fraig(); - - // Member functions about circuit reporting - void printSummary() const; - void printNetlist() const; - void printPIs() const; - void printPOs() const; - void printFloatGates() const; - void printFECPairs() const; - void writeAag(ostream&) const; - void writeGate(ostream&, CirGate*) const; - - // Member functions about flags - - // for hidden command - bool createMiter(CirMgr*, CirMgr*); - - static CirGate *_const0; - // --- MODIFICATION FOR SoCV HW5 (START) --- - void readCirFromAbc(string fileName, CirFileType fileType); - void initCir(Gia_Man_t* pGia); - CirGate* createGate(unsigned id, GateType type); - const bool setBddOrder(const bool& file); - void buildNtkBdd(); - void buildBdd(const CirGate* gate); - // --- MODIFICATION FOR SoCV HW5 (END) --- + CirSeq() : CirMgr() {} + ~CirSeq() override {} + CirType getCirType() { return CirType::SEQ; } + CirRiGate* getRi(unsigned i) const { return _riList[i]; } + CirRoGate* getRo(unsigned i) const { return _roList[i]; } + bool readCircuit() override; + private: - unsigned _numDecl[TOT_PARSE_PORTS]; - mutable unsigned _flag; - PiArray _piList; - PoArray _poList; - RiArray _riList; - RoArray _roList; - // IDs in _undefList are NOT sorted!! - IdList _undefList; - // Make sure the IDs of the following lists are sorted!! - IdList _floatList; // gates with fanin(s) undefined - IdList _unusedList; // gates defined but not used - GateArray _totGateList; - GateList _dfsList; - GateList *_fanoutInfo; - vector _fecGrps; // store litId; FECHash - SimVector _fecVector; - ofstream *_simLog; - - // private member functions for circuit parsing - bool parseHeader(ifstream&); - bool parseInput(ifstream&); - bool parseLatch(ifstream&); - bool parseOutput(ifstream&); - bool parseAig(ifstream&); - bool parseSymbol(ifstream&); - bool parseComment(ifstream&); - bool checkId(unsigned&, const string&); - CirGate* checkGate(unsigned&, ParsePorts, const string&); - - // private member functions for circuit optimization - CirGateV constSimplify(CirGate *, const CirGateV&, const CirGateV&) const; - - // private member functions about simulation - void setRandPPattern() const; - void setPPattern(SimPattern const patterns) const; - unsigned gatherPatterns(ifstream&, SimPattern, size_t); - void pSim1Pattern() const; - void outputSimLog(size_t nPatterns = 64); - - // private member functions about FRAIG - bool simAndCheckFEC(); - bool initFEC(); - bool checkFEC(); - bool checkFECRecur(const IdList&, vector&); - void finalizeFEC(); - void simplifyFECGrps(); - void clearFECGrps(); - void initProofModel(SatSolver&, const GateList&); - bool satCheckConst(SatSolver&, CirGate *, bool, SimPattern); - bool satCheckFEC(SatSolver&, CirGate *, CirGate *, bool, SimPattern); - void getSatAssignment(SatSolver&, SimPattern) const; - void simplifyByEQ(); - void updateFECbySatPattern(SimPattern); + std::vector _riList; + std::vector _roList; }; -#endif // CIR_MGR_H +}; // namespace cir +}; // namespace gv diff --git a/src/cir/cirOpt.cpp b/src/cir/cirOpt.cpp deleted file mode 100644 index 7a0a460b..00000000 --- a/src/cir/cirOpt.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/**************************************************************************** - FileName [ cirSim.cpp ] - PackageName [ cir ] - Synopsis [ Define cir optimization functions ] - Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2008-present LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#include -#include "cirMgr.h" -#include "cirGate.h" -#include "util.h" - -using namespace std; - -// TODO: Please keep "CirMgr::sweep()" and "CirMgr::optimize()" for cir cmd. -// Feel free to define your own variables or functions - -/*******************************/ -/* Global variable and enum */ -/*******************************/ - -/**************************************/ -/* Static varaibles and functions */ -/**************************************/ - -/**************************************************/ -/* Public member functions about optimization */ -/**************************************************/ -// Remove unused gates -// DFS list should NOT be changed -// UNDEF, float and unused list may be changed -void -CirMgr::sweep() -{ - CirGate::setGlobalRef(2); // gate's ref +1 is TO BE DELETED - for (size_t i = 0, n = _dfsList.size(); i < n; ++i) - _dfsList[i]->setToGlobalRef(); - - // some PIs may become unused - // PI must be setToGlobalRef() so that they won't get removed - // [e.g] kk.aag (PI 1 <== not in the DFS list; fanin of an UNUSED gate 5) - for (unsigned i = 0, n = getNumPIs(); i < n; ++i) - getPi(i)->setToGlobalRef(); - _const0->setToGlobalRef(); - - // Some UNDEF gates are reachable from POs - // [e.g.] ha_bug.aag (gate 4) - for (size_t i = 0, n = _undefList.size(); i < n; ++i) { - const GateList &fanouts = getFanouts(_undefList[i]); - for (size_t j = 0, m = fanouts.size(); j < m; ++j) - if (fanouts[j]->isGlobalRef()) { - getGate(_undefList[i])->setToGlobalRef(); break; - } - } - - // The newly added unused gate will be kept (Note: only PI is possible) - for (size_t i = 1, n = getNumTots(); i < n; ++i) { - CirGate *g = getGate(i); - if (!g || g->isGlobalRef()) continue; - cout << "Sweeping: " << g->getTypeStr() << "(" << i - << ") removed...\n"; - if (g->isAig()) { - CirGate *fanin = g->getIn0Gate(); - if (fanin->isGlobalRef()) fanin->removeFanout(g); - fanin = g->getIn1Gate(); - if (fanin->isGlobalRef()) fanin->removeFanout(g); - // deleteAigGate(g); - g->setToGlobalRef(1); - } - else if (g->isUndef()) { deleteUndefGate(g); } - else { assert(0); } // Shouldn't happen!! - } - - for (size_t i = 1, n = getNumTots(); i < n; ++i) { - CirGate *g = getGate(i); - if (!g || !g->isGlobalRef(1)) continue; - assert(g->isAig()); - deleteAigGate(g); - } - - updateUndefList(); - checkFloatList(); - checkUnusedList(); -} - -// Recursively simplifying from POs; -// _dfsList needs to be reconstructed afterwards -// UNDEF gates may be delete if its fanout becomes empty... -// ==> need to update _undefList (e.g. flt_po.aag) -void -CirMgr::optimize() -{ - GateList deleteList; - CirGate::setGlobalRef(); - for (unsigned i = 0, n = getNumPOs(); i < n; ++i) - getPo(i)->optimize(false, deleteList); - - for (size_t i = 0, n = deleteList.size(); i < n; ++i) - deleteAigGate(deleteList[i]); - - genDfsList(); - updateUndefList(); - checkFloatList(); - checkUnusedList(); -} - -CirGateV -CirPoGate::optimize(bool phase, GateList& deleteList) -{ - setToGlobalRef(); - - CirGate *g0 = _in0.gate(); - if (!g0->isGlobalRef()) - return g0->optimize(_in0.isInv(), deleteList); - else return _in0; -} - -CirGateV -CirRiGate::optimize(bool phase, GateList& deleteList) -{ - setToGlobalRef(); - - CirGate *g0 = _in0.gate(); - if (!g0->isGlobalRef()) - return g0->optimize(_in0.isInv(), deleteList); - else return _in0; -} - -CirGateV -CirAigGate::optimize(bool phase, GateList& deleteList) -{ - setToGlobalRef(); - - CirGateV newIn0, newIn1; - CirGate *g0 = _in0.gate(); - CirGate *g1 = _in1.gate(); - if (!g0->isGlobalRef()) - newIn0 = g0->optimize(_in0.isInv(), deleteList); - else newIn0 = _in0; - if (!g1->isGlobalRef()) - newIn1 = g1->optimize(_in1.isInv(), deleteList); - else newIn1 = _in1; - - CirGateV newV; - if (cirMgr->checkAigOptimize(this, newIn0, newIn1, newV)) { - // newV.gate()->replace(this, newV.isInv()); - // Apply merge before removeFanout so that newV won't be UNUSED - newV.gate()->merge("Simplifying: ", this, newV.isInv()); - newV.gate()->removeFanout(this); - deleteList.push_back(this); - newV.setInv(phase); - return newV; - } - - // No simplification - return size_t(this) + (phase?1: 0); -} - -// return true if g can be simplified by fanins(in0, in1) -bool -CirMgr::checkAigOptimize(CirGate* g, const CirGateV& in0, - const CirGateV& in1, CirGateV& gn) const -{ - CirGate *g0 = in0.gate(), *g1 = in1.gate(); - if (g0 == g1) { - if (in0.isInv() ^ in1.isInv()) // a & !a = 0 - gn = constSimplify(g, size_t(_const0), in0); - else // a & a = a - gn = in0; - } - else if (g0->isConst()) - gn = constSimplify(g, in0, in1); - else if (g1->isConst()) - gn = constSimplify(g, in1, in0); - else return false; - return true; -} - -// DOES NOT update _dfsList!! -// Need to take care separately... -void -CirMgr::deleteAigGate(CirGate *g) -{ - assert(g->isAig()); - _totGateList[g->getGid()] = 0; - --(_numDecl[AIG]); - clearList(_fanoutInfo[g->getGid()]); - delete g; -} - -// DOES NOT update _dfsList and _undefList!! -// Need to take care separately... -void -CirMgr::deleteUndefGate(CirGate *g) -{ - assert(g->isUndef()); - _totGateList[g->getGid()] = 0; - clearList(_fanoutInfo[g->getGid()]); - delete g; -} - -// This will merge mg. -// All the fanouts of mg will be merged to this' fanouts. -// Whoever calls this funciton needs to handle if an UNDEF gate replaces -// some other gates ==> call cirMgr->checkFloatList() later -// [e.g] flt_po*.aag -void -CirGate::merge(const string& header, CirGate *mg, bool isInv) -{ - if (header.size()) { - cout << header << _gid << " merging " << (isInv?"!":"") - << mg->getGid() << "..." << endl; - } - GateList& fanouts = cirMgr->getFanouts(_gid); - GateList& mFanouts = cirMgr->getFanouts(mg->getGid()); - for (size_t i = 0, n = mFanouts.size(); i < n; ++i) - mFanouts[i]->replaceFanin(mg, this, isInv); - fanouts.insert(fanouts.end(), mFanouts.begin(), mFanouts.end()); - clearList(mFanouts); -} - -// This will replace 'g' -// We don't care if g has fanin to this -/* -void CirGate::replace(CirGate* g, bool inv) -{ - removeFanout(g); // in case this has fanout to g - merge("Simplifying: ", g, inv); -} -*/ - -// 1. Remove f from this' fanouts. -// 2. Remove this from f's fanins. -// However, since f is going to be deleted, -// we don't need to actually remove this from f's fanins. -// 3. We assume this must = f._in0 or f._in1 <== DO NOT CHECK!! -// [Note] The original fanin will become invalid!! -void -CirGate::removeFanout(CirGate* f) const -{ - GateList& fanouts = cirMgr->getFanouts(_gid); - removeData(fanouts, f); -} - -/***************************************************/ -/* Private member functions about optimization */ -/***************************************************/ -CirGateV -CirMgr::constSimplify(CirGate *g, const CirGateV& constV, - const CirGateV& otherV) const -{ - if (constV.isInv()) { // const 1 - constV.gate()->removeFanout(g); - return otherV; - } - else { // const 0 - otherV.gate()->removeFanout(g); - return size_t(_const0); - } -} - diff --git a/src/cir/cirSim.cpp b/src/cir/cirSim.cpp index f44ba952..b55f109e 100644 --- a/src/cir/cirSim.cpp +++ b/src/cir/cirSim.cpp @@ -3,362 +3,348 @@ // PackageName [ cir ] // Synopsis [ Define cir simulation functions ] // Author [ Chung-Yang (Ric) Huang ] -// Copyright [ Copyleft(c) 2008-present LaDs(III), GIEE, NTU, Taiwan ] +// Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] // ****************************************************************************/ -// #include -// #include -// #include -// #include -// #include -// #include "cirMgr.h" -// #include "cirGate.h" -// #include "util.h" +#ifndef CIR_SIM_CPP +#define CIR_SIM_CPP -// using namespace std; +#include +#include +#include +#include +#include -// // TODO: Keep "CirMgr::randimSim()" and "CirMgr::fileSim()" for cir cmd. -// // Feel free to define your own variables or functions +#include "cirDef.h" +#include "cirGate.h" +#include "cirMgr.h" +#include "util.h" -// static bool debug_g = false; +using namespace std; +using namespace gv::cir; -// /*******************************/ -// /* Global variable and enum */ -// /*******************************/ +// TODO: Keep "CirMgr::randimSim()" and "CirMgr::fileSim()" for cir cmd. +// Feel free to define your own variables or functions -// /**************************************/ -// /* Static varaibles and functions */ -// /**************************************/ -// static inline void checkFecHash(FECHash& fecHash, CirGate *g) -// { -// IdList *ll = 0; -// CirPValue pv = g->getPValue(); -// if (fecHash.check(pv, ll)) { -// ll->push_back(g->getGid() * 2); -// } -// else if (fecHash.check(~pv, ll)) { -// ll->push_back(g->getGid() *2 + 1); -// } -// else { -// ll = new IdList(1); -// (*ll)[0] = g->getGid() * 2; -// fecHash.forceInsert(pv, ll); -// } -// } +static bool debug_g = false; + +/*******************************/ +/* Global variable and enum */ +/*******************************/ + +/**************************************/ +/* Static varaibles and functions */ +/**************************************/ +static inline void checkFecHash(FECHash &fecHash, CirGate *g) { + IdList *ll = 0; + gv::cir::CirPValue pv = g->getPValue(); + // if (fecHash.check(pv, ll)) { + // ll->push_back(g->getGid() * 2); + // } + // else if (fecHash.check(~pv, ll)) { + // ll->push_back(g->getGid() *2 + 1); + // } + // else { + // ll = new IdList(1); + // (*ll)[0] = g->getGid() * 2; + // fecHash.forceInsert(pv, ll); + // } +} -// /************************************************/ -// /* Public member functions about Simulation */ -// /************************************************/ -// void -// CirMgr::randomSim() -// { -// size_t nSims = 0, nFails = 0; -// size_t MAX_FAILS = 3; // 3; -// unsigned nin = getNumPIs(); -// if (nin < 6) nin = 0; else nin -= 6; // 2^6 = 64 -// double m = MAX_FAILS; -// while (nin >>= 1) m *= 1.5; // 1.4; // 1.3; // 1.2; // 1.33; -// unsigned ntot = _dfsList.size(); -// while (ntot >>= 2) m *= 1.4; // 1.4; // 1.3; // 1.13; -// size_t nfv = _fecVector.size(); -// m = (m + nfv) / (nfv + 1); -// MAX_FAILS = unsigned(m); -// if (debug_g) -// cout << "MAX_FAILS = " << MAX_FAILS << endl; -// cout << "Total #FEC Group = " << _fecGrps.size() << flush; -// for (size_t i = 0; i < nfv; ++i) { -// setPPattern(_fecVector[i]); -// if (!simAndCheckFEC()) ++nFails; -// nSims += 64; -// if (_simLog) outputSimLog(); -// cout << char(13) << setw(30) << ' ' << char(13) -// << "Total #FEC Group = " << _fecGrps.size() << flush; -// } -// while (nFails < MAX_FAILS) { -// setRandPPattern(); -// if (!simAndCheckFEC()) ++nFails; -// nSims += 64; -// if (_simLog) outputSimLog(); -// cout << char(13) << setw(30) << ' ' << char(13) -// << "Total #FEC Group = " << _fecGrps.size() << flush; -// } -// finalizeFEC(); -// cout << char(13) << setw(30) << ' ' << char(13) << nSims -// << " patterns simulated." << endl; -// // _fecMgr.print(); +/************************************************/ +/* Public member functions about Simulation */ +/************************************************/ +// void CirMgr::randomSim() { +// size_t nSims = 0, nFails = 0; +// size_t MAX_FAILS = 3; // 3; +// unsigned nin = getNumPIs(); +// if (nin < 6) nin = 0; +// else nin -= 6; // 2^6 = 64 +// double m = MAX_FAILS; +// while (nin >>= 1) m *= 1.5; // 1.4; // 1.3; // 1.2; // 1.33; +// unsigned ntot = _dfsList.size(); +// while (ntot >>= 2) m *= 1.4; // 1.4; // 1.3; // 1.13; +// size_t nfv = _fecVector.size(); +// m = (m + nfv) / (nfv + 1); +// MAX_FAILS = unsigned(m); +// if (debug_g) +// cout << "MAX_FAILS = " << MAX_FAILS << endl; +// cout << "Total #FEC Group = " << _fecGrps.size() << flush; +// for (size_t i = 0; i < nfv; ++i) { +// setPPattern(_fecVector[i]); +// if (!simAndCheckFEC()) ++nFails; +// nSims += 64; +// if (_simLog) outputSimLog(); +// cout << char(13) << setw(30) << ' ' << char(13) +// << "Total #FEC Group = " << _fecGrps.size() << flush; +// } +// while (nFails < MAX_FAILS) { +// setRandPPattern(); +// if (!simAndCheckFEC()) ++nFails; +// nSims += 64; +// if (_simLog) outputSimLog(); +// cout << char(13) << setw(30) << ' ' << char(13) +// << "Total #FEC Group = " << _fecGrps.size() << flush; +// } +// finalizeFEC(); +// cout << char(13) << setw(30) << ' ' << char(13) << nSims +// << " patterns simulated." << endl; +// // _fecMgr.print(); // } -// void -// CirMgr::fileSim(ifstream& patternFile) -// { -// unsigned nSims = 0, nin = getNumPIs(); -// while (!patternFile.eof()) { -// size_t patterns[nin]; -// unsigned nPatterns = gatherPatterns(patternFile, patterns, nin); -// if (!nPatterns) break; -// setPPattern(patterns); -// simAndCheckFEC(); -// nSims += nPatterns; -// if (_simLog) outputSimLog(nPatterns); -// cout << char(13) << "Total #FEC Group = " << _fecGrps.size() << flush; -// } -// finalizeFEC(); -// cout << char(13) << nSims << " patterns simulated." << endl; +// void CirMgr::fileSim(ifstream &patternFile) { +// unsigned nSims = 0, nin = getNumPIs(); +// while (!patternFile.eof()) { +// size_t patterns[nin]; +// unsigned nPatterns = gatherPatterns(patternFile, patterns, nin); +// if (!nPatterns) break; +// setPPattern(patterns); +// simAndCheckFEC(); +// nSims += nPatterns; +// if (_simLog) outputSimLog(nPatterns); +// cout << char(13) << "Total #FEC Group = " << _fecGrps.size() << flush; +// } +// finalizeFEC(); +// cout << char(13) << nSims << " patterns simulated." << endl; // } // // return true if new FEC pairs are generated -// bool -// CirMgr::simAndCheckFEC() -// { -// pSim1Pattern(); -// if (isFlag(NO_FEC)) return false; -// if (_fecGrps.empty()) return initFEC(); -// else return checkFEC(); +// bool CirMgr::simAndCheckFEC() { +// pSim1Pattern(); +// if (isFlag(NO_FEC)) return false; +// if (_fecGrps.empty()) return initFEC(); +// else return checkFEC(); // } // // Make sure the circuit has been simulated!! -// bool -// CirMgr::initFEC() -// { -// FECHash fecHash; -// fecHash.init(getHashSize(_dfsList.size())); -// checkFecHash(fecHash, _const0); // make sure 0 is in HashMap -// for (size_t i = 0, n = _dfsList.size(); i < n; ++i) { -// CirGate *g = _dfsList[i]; -// if (g->isAig()) checkFecHash(fecHash, g); -// } +// bool CirMgr::initFEC() { +// FECHash fecHash; +// fecHash.init(getHashSize(_dfsList.size())); +// checkFecHash(fecHash, _const0); // make sure 0 is in HashMap +// for (size_t i = 0, n = _dfsList.size(); i < n; ++i) { +// CirGate *g = _dfsList[i]; +// if (g->isAig()) checkFecHash(fecHash, g); +// } -// // Collect valid FEC groups -// for (FECHash::iterator hi = fecHash.begin(); hi != fecHash.end(); ++hi) { -// IdList *ll = (*hi).second; -// if (ll->size() == 1) { delete ll; continue; } -// _fecGrps.push_back(ll); -// } -// if (_fecGrps.empty()) { setFlag(NO_FEC); return false; } -// return true; +// // Collect valid FEC groups +// for (FECHash::iterator hi = fecHash.begin(); hi != fecHash.end(); ++hi) { +// IdList *ll = (*hi).second; +// if (ll->size() == 1) { +// delete ll; +// continue; +// } +// _fecGrps.push_back(ll); +// } +// if (_fecGrps.empty()) { +// setFlag(NO_FEC); +// return false; +// } +// return true; // } // // return true if _fecGrps changes!! -// bool -// CirMgr::checkFEC() -// { -// vector newGrps; -// bool grpChange = false; -// for (size_t i = 0, n = _fecGrps.size(); i < n; ++i) { -// IdList *ll = _fecGrps[i]; -// grpChange |= checkFECRecur(*ll, newGrps); -// } -// _fecGrps.swap(newGrps); -// for (size_t i = 0, n = newGrps.size(); i < n; ++i) -// delete newGrps[i]; -// if (_fecGrps.empty()) setFlag(NO_FEC); -// return grpChange; +// bool CirMgr::checkFEC() { +// vector newGrps; +// bool grpChange = false; +// for (size_t i = 0, n = _fecGrps.size(); i < n; ++i) { +// IdList *ll = _fecGrps[i]; +// grpChange |= checkFECRecur(*ll, newGrps); +// } +// _fecGrps.swap(newGrps); +// for (size_t i = 0, n = newGrps.size(); i < n; ++i) +// delete newGrps[i]; +// if (_fecGrps.empty()) setFlag(NO_FEC); +// return grpChange; // } -// bool -// CirMgr::checkFECRecur(const IdList& ll, vector& newGrps) -// { -// FECHash fecHash; -// size_t n = ll.size(); // Note: n can be 0 -// fecHash.init(getHashSize(n)); -// for (size_t i = 0; i < n; ++i) { -// CirGate *g = litId2Gate(ll[i]); -// checkFecHash(fecHash, g); -// } +// bool CirMgr::checkFECRecur(const IdList &ll, vector &newGrps) { +// FECHash fecHash; +// size_t n = ll.size(); // Note: n can be 0 +// fecHash.init(getHashSize(n)); +// for (size_t i = 0; i < n; ++i) { +// CirGate *g = litId2Gate(ll[i]); +// checkFecHash(fecHash, g); +// } -// // Collect valid FEC groups -// size_t nNewGrps = 0; -// for (FECHash::iterator hi = fecHash.begin(); hi != fecHash.end(); ++hi) { -// IdList *nn = (*hi).second; -// if (nn->size() == 1) { delete nn; continue; } -// newGrps.push_back(nn); ++nNewGrps; -// } -// return (nNewGrps != 1); +// // Collect valid FEC groups +// size_t nNewGrps = 0; +// for (FECHash::iterator hi = fecHash.begin(); hi != fecHash.end(); ++hi) { +// IdList *nn = (*hi).second; +// if (nn->size() == 1) { +// delete nn; +// continue; +// } +// newGrps.push_back(nn); +// ++nNewGrps; +// } +// return (nNewGrps != 1); // } -// void -// CirMgr::finalizeFEC() -// { -// CirGate::setGlobalRef(); -// for (size_t i = 0, n = _fecGrps.size(); i < n; ++i) { -// IdList *ll = _fecGrps[i]; -// sort(ll->begin(), ll->end()); -// if ((*ll)[0] % 2 != 0) // isInv -// for (size_t j = 0, m = ll->size(); j < m; ++j) (*ll)[j] ^= 1; -// for (size_t j = 0, m = ll->size(); j < m; ++j) { -// CirGate *g = litId2Gate((*ll)[j]); -// g->setToGlobalRef(); -// g->setFECId(i*2 + (*ll)[j]%2); -// } -// } -// for (size_t i = 0, n = _dfsList.size(); i < n; ++i) { -// CirGate *g = _dfsList[i]; -// if (!g->isGlobalRef()) -// g->resetFECId(); -// } -// // Check _const0 as it is NOT in the DFS list -// if (!_const0->isGlobalRef()) -// _const0->resetFECId(); +// void CirMgr::finalizeFEC() { +// CirGate::setGlobalRef(); +// for (size_t i = 0, n = _fecGrps.size(); i < n; ++i) { +// IdList *ll = _fecGrps[i]; +// sort(ll->begin(), ll->end()); +// if ((*ll)[0] % 2 != 0) // isInv +// for (size_t j = 0, m = ll->size(); j < m; ++j) (*ll)[j] ^= 1; +// for (size_t j = 0, m = ll->size(); j < m; ++j) { +// CirGate *g = litId2Gate((*ll)[j]); +// g->setToGlobalRef(); +// g->setFECId(i * 2 + (*ll)[j] % 2); +// } +// } +// for (size_t i = 0, n = _dfsList.size(); i < n; ++i) { +// CirGate *g = _dfsList[i]; +// if (!g->isGlobalRef()) +// g->resetFECId(); +// } +// // Check _const0 as it is NOT in the DFS list +// if (!_const0->isGlobalRef()) +// _const0->resetFECId(); // } -// void -// CirMgr::simplifyFECGrps() -// { -// vector newGrps; -// for (size_t i = 0, n = _fecGrps.size(); i < n; ++i) { -// IdList *ll = _fecGrps[i]; -// size_t validGates = 0; -// for (size_t j = 0, m = ll->size(); j < m; ++j) -// if (litId2Gate((*ll)[j]) != 0) ++validGates; -// if (validGates > 1) { -// IdList *nn = new IdList(validGates); -// unsigned fecId = newGrps.size() * 2; -// for (size_t j = 0, k = 0, m = ll->size(); j < m; ++j) { -// CirGate *g = litId2Gate((*ll)[j]); -// if (g != 0) { -// (*nn)[k++] = (*ll)[j]; -// g->setFECId(fecId + ((*ll)[j] & 0x1)); +// void CirMgr::simplifyFECGrps() { +// vector newGrps; +// for (size_t i = 0, n = _fecGrps.size(); i < n; ++i) { +// IdList *ll = _fecGrps[i]; +// size_t validGates = 0; +// for (size_t j = 0, m = ll->size(); j < m; ++j) +// if (litId2Gate((*ll)[j]) != 0) ++validGates; +// if (validGates > 1) { +// IdList *nn = new IdList(validGates); +// unsigned fecId = newGrps.size() * 2; +// for (size_t j = 0, k = 0, m = ll->size(); j < m; ++j) { +// CirGate *g = litId2Gate((*ll)[j]); +// if (g != 0) { +// (*nn)[k++] = (*ll)[j]; +// g->setFECId(fecId + ((*ll)[j] & 0x1)); +// } // } -// } -// newGrps.push_back(nn); -// } -// else if (validGates == 1) -// for (size_t j = 0, m = ll->size(); j < m; ++j) { -// CirGate *g = litId2Gate((*ll)[j]); -// if (g != 0) g->resetFECId(); -// } -// } -// newGrps.swap(_fecGrps); -// for (size_t i = 0, n = newGrps.size(); i < n; ++i) delete newGrps[i]; +// newGrps.push_back(nn); +// } else if (validGates == 1) +// for (size_t j = 0, m = ll->size(); j < m; ++j) { +// CirGate *g = litId2Gate((*ll)[j]); +// if (g != 0) g->resetFECId(); +// } +// } +// newGrps.swap(_fecGrps); +// for (size_t i = 0, n = newGrps.size(); i < n; ++i) delete newGrps[i]; // } -// void -// CirMgr::clearFECGrps() -// { -// for (size_t i = 0, n = _fecGrps.size(); i < n; ++i) delete _fecGrps[i]; -// for (size_t i = 0, n = getNumTots(); i < n; ++i) -// if (_totGateList[i]) _totGateList[i]->resetFECId(); -// clearList(_fecGrps); +// void CirMgr::clearFECGrps() { +// for (size_t i = 0, n = _fecGrps.size(); i < n; ++i) delete _fecGrps[i]; +// for (size_t i = 0, n = getNumTots(); i < n; ++i) +// if (_totGateList[i]) _totGateList[i]->resetFECId(); +// clearList(_fecGrps); // } -// void -// CirMgr::printFEC() const -// { -// size_t n = _fecGrps.size(); -// cout << "Total #FEC Group = " << n << endl; -// for (size_t i = 0; i < n; ++i) { -// IdList *ll = _fecGrps[i]; -// cout << "[" << i << "] " << litId2Gate((*ll)[0])->getPValue() << endl; -// for (size_t j = 0, m = ll->size(); j < m; ++j) -// cout << litId2GateV((*ll)[j]) << endl; -// } +// void CirMgr::printFEC() const { +// size_t n = _fecGrps.size(); +// cout << "Total #FEC Group = " << n << endl; +// for (size_t i = 0; i < n; ++i) { +// IdList *ll = _fecGrps[i]; +// cout << "[" << i << "] " << litId2Gate((*ll)[0])->getPValue() << endl; +// for (size_t j = 0, m = ll->size(); j < m; ++j) +// cout << litId2GateV((*ll)[j]) << endl; +// } // } // /*************************************************/ // /* Private member functions about Simulation */ // /*************************************************/ -// void -// CirMgr::setRandPPattern() const -// { -// for (unsigned i = 0, n = getNumPIs(); i < n; ++i) -// _piList[i]->setRandPPattern(); +// void CirMgr::setRandPPattern() const { +// for (unsigned i = 0, n = getNumPIs(); i < n; ++i) +// _piList[i]->setRandPPattern(); // } -// void -// CirMgr::setPPattern(SimPattern const patterns) const -// { -// for (size_t i = 0, n = getNumPIs(); i < n; ++i) -// _piList[i]->setPValue(patterns[i]); +// void CirMgr::setPPattern(SimPattern const patterns) const { +// for (size_t i = 0, n = getNumPIs(); i < n; ++i) +// _piList[i]->setPValue(patterns[i]); // } // // return false if: // // (1) Pattern error ==> nPatterns will reset to 0 // // (2) EOF is encountered -// unsigned -// CirMgr::gatherPatterns -// (ifstream& patternFile, SimPattern const patterns, size_t nin) -// { -// unsigned nPatterns = 0; -// for (size_t i = 0; i < nin; ++i) patterns[i] = size_t(0); -// string str; -// while (nPatterns < 64) { -// patternFile >> str; -// if (patternFile.eof()) return nPatterns; -// if (nin != str.size()) { -// cerr << "\nError: Pattern(" << str << ") length(" << str.size() -// << ") does not match the number of inputs(" << nin -// << ") in a circuit!!" << endl; -// return 0; -// } -// for (size_t i = 0; i < nin; ++i) { -// if (str[i] == '1') -// patterns[i] += (size_t(1) << nPatterns); -// else if (str[i] != '0') { -// cerr << "\nError: Pattern(" << str << ") contains a non-0/1 " -// << "character(\'" << str[i] << "\')." << endl; +// unsigned CirMgr::gatherPatterns(ifstream &patternFile, SimPattern const patterns, size_t nin) { +// unsigned nPatterns = 0; +// for (size_t i = 0; i < nin; ++i) patterns[i] = size_t(0); +// string str; +// while (nPatterns < 64) { +// patternFile >> str; +// if (patternFile.eof()) return nPatterns; +// if (nin != str.size()) { +// cout << "\nError: Pattern(" << str << ") length(" << str.size() +// << ") does not match the number of inputs(" << nin +// << ") in a circuit!!" << endl; // return 0; -// } -// } -// ++nPatterns; -// } -// assert (nPatterns == 64); -// return nPatterns; +// } +// for (size_t i = 0; i < nin; ++i) { +// if (str[i] == '1') +// patterns[i] += (size_t(1) << nPatterns); +// else if (str[i] != '0') { +// cout << "\nError: Pattern(" << str << ") contains a non-0/1 " +// << "character(\'" << str[i] << "\')." << endl; +// return 0; +// } +// } +// ++nPatterns; +// } +// assert(nPatterns == 64); +// return nPatterns; // } -// void -// CirMgr::pSim1Pattern() const -// { -// for (unsigned i = 0, n = _dfsList.size(); i < n; ++i) -// _dfsList[i]->pSim(); +// void CirMgr::pSim1Pattern() const { +// for (unsigned i = 0, n = _dfsList.size(); i < n; ++i) { +// cout << _dfsList[i]->getTypeStr() << "\n"; +// if (_dfsList[i]->getTypeStr() == "RI") { +// cout << endl; +// } +// _dfsList[i]->pSim(); +// } // } -// void -// CirMgr::outputSimLog(size_t nPatterns) -// { -// assert(_simLog != 0); -// unsigned nin = getNumPIs(); -// unsigned nout = getNumPOs(); -// size_t patterns[nin], responses[nout]; -// for (unsigned i = 0; i < nin; ++i) -// patterns[i] = _piList[i]->getPValue()(); -// for (unsigned i = 0; i < nout; ++i) -// responses[i] = _poList[i]->getPValue()(); - -// assert(nPatterns <= 64); -// for (size_t i = 0; i < nPatterns; ++i) { -// for (unsigned j = 0; j < nin; ++j) { -// (*_simLog) << (patterns[j] & 0x1); -// patterns[j] >>= 1; -// } -// (*_simLog) << " "; -// for (unsigned j = 0; j < nout; ++j) { -// (*_simLog) << (responses[j] & 0x1); -// responses[j] >>= 1; -// } -// (*_simLog) << endl; -// } +// void CirMgr::outputSimLog(size_t nPatterns) { +// assert(_simLog != 0); +// unsigned nin = getNumPIs(); +// unsigned nout = getNumPOs(); +// size_t patterns[nin], responses[nout]; +// for (unsigned i = 0; i < nin; ++i) +// patterns[i] = _piList[i]->getPValue()(); +// for (unsigned i = 0; i < nout; ++i) +// responses[i] = _poList[i]->getPValue()(); + +// assert(nPatterns <= 64); +// for (size_t i = 0; i < nPatterns; ++i) { +// for (unsigned j = 0; j < nin; ++j) { +// (*_simLog) << (patterns[j] & 0x1); +// patterns[j] >>= 1; +// } +// (*_simLog) << " "; +// for (unsigned j = 0; j < nout; ++j) { +// (*_simLog) << (responses[j] & 0x1); +// responses[j] >>= 1; +// } +// (*_simLog) << endl; +// } // } -// void -// CirPValue::rand() -// { -// _pValue = size_t(0); -// for (int i = 0; i < 4; ++i) -// _pValue += size_t(rnGen(1<<16) << i*16); +// void CirPValue::rand() { +// _pValue = size_t(0); +// for (int i = 0; i < 4; ++i) +// _pValue += size_t(rnGen(1 << 16) << i * 16); // } -// static const char* pvBin[16] = { -// "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", -// "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" -// }; +// static const char *pvBin[16] = { +// "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", +// "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"}; -// ostream& operator << (ostream& os, const CirPValue& v) -// { -// const size_t nBinMinus1 = 15, binShift = nBinMinus1*4; -// os << pvBin[v._pValue >> binShift] << pvBin[v._pValue << 4 >> binShift]; -// for (size_t i = 2; i <= nBinMinus1; i += 2) -// os << '_' << pvBin[v._pValue << (i*4) >> binShift] -// << pvBin[v._pValue << ((i+1)*4) >> binShift]; -// return os; +// ostream &operator<<(ostream &os, const CirPValue &v) { +// const size_t nBinMinus1 = 15, binShift = nBinMinus1 * 4; +// os << pvBin[v._pValue >> binShift] << pvBin[v._pValue << 4 >> binShift]; +// for (size_t i = 2; i <= nBinMinus1; i += 2) +// os << '_' << pvBin[v._pValue << (i * 4) >> binShift] +// << pvBin[v._pValue << ((i + 1) * 4) >> binShift]; +// return os; // } +#endif diff --git a/src/cmd/.depend.mak b/src/cmd/.depend.mak deleted file mode 100644 index fc75d675..00000000 --- a/src/cmd/.depend.mak +++ /dev/null @@ -1,5 +0,0 @@ -gvCmdComm.o: gvCmdComm.cpp gvCmdComm.h gvCmdMgr.h ../../include/gvMsg.h \ - ../../include/gvUsage.h ../../include/gvMsg.h ../../include/gvIntType.h \ - ../../include/util.h ../../include/rnGen.h ../../include/myUsage.h -gvCmdMgr.o: gvCmdMgr.cpp gvCmdMgr.h ../../include/gvMsg.h \ - ../../include/util.h ../../include/rnGen.h ../../include/myUsage.h diff --git a/src/cmd/.extheader.mak b/src/cmd/.extheader.mak deleted file mode 100644 index 61bd2bab..00000000 --- a/src/cmd/.extheader.mak +++ /dev/null @@ -1,7 +0,0 @@ -cmd.d: ../../include/gvCmdComm.h ../../include/gvCmdMgr.h -../../include/gvCmdComm.h: gvCmdComm.h - @rm -f ../../include/gvCmdComm.h - @ln -fs ../src/cmd/gvCmdComm.h ../../include/gvCmdComm.h -../../include/gvCmdMgr.h: gvCmdMgr.h - @rm -f ../../include/gvCmdMgr.h - @ln -fs ../src/cmd/gvCmdMgr.h ../../include/gvCmdMgr.h diff --git a/src/cmd/Makefile b/src/cmd/Makefile deleted file mode 100644 index 6221b58b..00000000 --- a/src/cmd/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -PKGFLAG = $(DEBUG_FLAG) -EXTHDRS = gvCmdComm.h gvCmdMgr.h - -include ../Makefile.in -include ../Makefile.lib \ No newline at end of file diff --git a/src/cmd/cmdCharDef.h b/src/cmd/cmdCharDef.h index 3d117d8a..2d2f83bb 100644 --- a/src/cmd/cmdCharDef.h +++ b/src/cmd/cmdCharDef.h @@ -3,47 +3,45 @@ PackageName [ cmd ] Synopsis [ enum for keyboard mapping ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2007-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#ifndef CMD_CHAR_DEF_H -#define CMD_CHAR_DEF_H +#pragma once #include // TO define common TA settings // Don't change these #defines -#define TA_LINE_BEGIN_KEY 1 -#define TA_LINE_END_KEY 5 -#define TA_INPUT_END_KEY 4 -#define TA_TAB_KEY int('\t') -#define TA_NEWLINE_KEY int('\n') -#define TA_ESC_KEY 27 -#define TA_BACK_SPACE_KEY 127 -#define TA_ARROW_KEY_FLAG (1 << 8) -#define TA_ARROW_KEY_INT 91 -#define TA_ARROW_UP_KEY (65 + TA_ARROW_KEY_FLAG) -#define TA_ARROW_DOWN_KEY (66 + TA_ARROW_KEY_FLAG) -#define TA_ARROW_RIGHT_KEY (67 + TA_ARROW_KEY_FLAG) -#define TA_ARROW_LEFT_KEY (68 + TA_ARROW_KEY_FLAG) -#define TA_ARROW_KEY_BEGIN TA_ARROW_UP_KEY -#define TA_ARROW_KEY_END TA_ARROW_LEFT_KEY -#define TA_MOD_KEY_FLAG (1 << 9) -#define TA_MOD_KEY_INT 91 -#define TA_HOME_KEY (49 + TA_MOD_KEY_FLAG) -#define TA_INSERT_KEY (50 + TA_MOD_KEY_FLAG) -#define TA_DELETE_KEY (51 + TA_MOD_KEY_FLAG) -#define TA_END_KEY (52 + TA_MOD_KEY_FLAG) -#define TA_PG_UP_KEY (53 + TA_MOD_KEY_FLAG) -#define TA_PG_DOWN_KEY (54 + TA_MOD_KEY_FLAG) -#define TA_MOD_KEY_BEGIN TA_HOME_KEY -#define TA_MOD_KEY_END TA_PG_DOWN_KEY -#define TA_MOD_KEY_DUMMY 126 -#define TA_UNDEFINED_KEY INT_MAX -#define TA_BEEP_CHAR 7 -#define TA_BACK_SPACE_CHAR 8 +#define TA_LINE_BEGIN_KEY 1 +#define TA_LINE_END_KEY 5 +#define TA_INPUT_END_KEY 4 +#define TA_TAB_KEY int('\t') +#define TA_NEWLINE_KEY int('\n') +#define TA_ESC_KEY 27 +#define TA_BACK_SPACE_KEY 127 +#define TA_ARROW_KEY_FLAG (1 << 8) +#define TA_ARROW_KEY_INT 91 +#define TA_ARROW_UP_KEY (65 + TA_ARROW_KEY_FLAG) +#define TA_ARROW_DOWN_KEY (66 + TA_ARROW_KEY_FLAG) +#define TA_ARROW_RIGHT_KEY (67 + TA_ARROW_KEY_FLAG) +#define TA_ARROW_LEFT_KEY (68 + TA_ARROW_KEY_FLAG) +#define TA_ARROW_KEY_BEGIN TA_ARROW_UP_KEY +#define TA_ARROW_KEY_END TA_ARROW_LEFT_KEY +#define TA_MOD_KEY_FLAG (1 << 9) +#define TA_MOD_KEY_INT 91 +#define TA_HOME_KEY (49 + TA_MOD_KEY_FLAG) +#define TA_INSERT_KEY (50 + TA_MOD_KEY_FLAG) +#define TA_DELETE_KEY (51 + TA_MOD_KEY_FLAG) +#define TA_END_KEY (52 + TA_MOD_KEY_FLAG) +#define TA_PG_UP_KEY (53 + TA_MOD_KEY_FLAG) +#define TA_PG_DOWN_KEY (54 + TA_MOD_KEY_FLAG) +#define TA_MOD_KEY_BEGIN TA_HOME_KEY +#define TA_MOD_KEY_END TA_PG_DOWN_KEY +#define TA_MOD_KEY_DUMMY 126 +#define TA_UNDEFINED_KEY INT_MAX +#define TA_BEEP_CHAR 7 +#define TA_BACK_SPACE_CHAR 8 - -#ifndef TA_KB_SETTING +#pragma once // For HW 3, this part is NOT used by default, so you don't need to modify it. // Change this part only if you want to customize it for your own keyboard // mapping. Remember to undefine "TA_KB_SETTING" in src/Makefile.in. @@ -52,71 +50,70 @@ // // Make sure you DO NOT define TA_KB_SETTING in your Makefile // -enum ParseChar -{ - // Simple keys: one code for one key press - // -- The following should be platform-independent - LINE_BEGIN_KEY = 1, // ctrl-a - LINE_END_KEY = 5, // ctrl-e - INPUT_END_KEY = 4, // ctrl-d - TAB_KEY = int('\t'), // tab('\t') or Ctrl-i - NEWLINE_KEY = int('\n'), // enter('\n') or ctrl-m - ESC_KEY = 27, // Not printable; used for combo keys +enum ParseChar { + // Simple keys: one code for one key press + // -- The following should be platform-independent + LINE_BEGIN_KEY = 1, // ctrl-a + LINE_END_KEY = 5, // ctrl-e + INPUT_END_KEY = 4, // ctrl-d + TAB_KEY = int('\t'), // tab('\t') or Ctrl-i + NEWLINE_KEY = int('\n'), // enter('\n') or ctrl-m + ESC_KEY = 27, // Not printable; used for combo keys + + // -- The following simple/combo keys are platform-dependent + // You should test to check the returned codes of these key presses + // -- Use "testAsc.cpp" to test + // + // [FLAG bit for combo keys] + // -- Added to the returned ParseChar of combo keys + // -- i.e. The returned ParseChar will be "ComboKeyEnum + FLAG bit" + // -- This is to avoid the collision with the ASCII codes of regular keys + // -- Feel free to add/remove/modify on your own + // + // [Intermediate keys for combo keys] + // -- Intermediate keys are the common parts of combo keys + // + BACK_SPACE_KEY = 127, - // -- The following simple/combo keys are platform-dependent - // You should test to check the returned codes of these key presses - // -- Use "testAsc.cpp" to test - // - // [FLAG bit for combo keys] - // -- Added to the returned ParseChar of combo keys - // -- i.e. The returned ParseChar will be "ComboKeyEnum + FLAG bit" - // -- This is to avoid the collision with the ASCII codes of regular keys - // -- Feel free to add/remove/modify on your own - // - // [Intermediate keys for combo keys] - // -- Intermediate keys are the common parts of combo keys - // - BACK_SPACE_KEY = 127, - - // - // -- Arrow keys: 27 -> 91 -> {UP=65, DOWN=66, RIGHT=67, LEFT=68} - ARROW_KEY_FLAG = 1 << 8, - ARROW_KEY_INT = 91, - ARROW_UP_KEY = 65 + ARROW_KEY_FLAG, - ARROW_DOWN_KEY = 66 + ARROW_KEY_FLAG, - ARROW_RIGHT_KEY = 67 + ARROW_KEY_FLAG, - ARROW_LEFT_KEY = 68 + ARROW_KEY_FLAG, - ARROW_KEY_BEGIN = ARROW_UP_KEY, - ARROW_KEY_END = ARROW_LEFT_KEY, + // + // -- Arrow keys: 27 -> 91 -> {UP=65, DOWN=66, RIGHT=67, LEFT=68} + ARROW_KEY_FLAG = 1 << 8, + ARROW_KEY_INT = 91, + ARROW_UP_KEY = 65 + ARROW_KEY_FLAG, + ARROW_DOWN_KEY = 66 + ARROW_KEY_FLAG, + ARROW_RIGHT_KEY = 67 + ARROW_KEY_FLAG, + ARROW_LEFT_KEY = 68 + ARROW_KEY_FLAG, + ARROW_KEY_BEGIN = ARROW_UP_KEY, + ARROW_KEY_END = ARROW_LEFT_KEY, - // - // -- MOD keys: 27 -> 91 -> {49-54} -> 126 - // MOD_KEY = { INSERT, DELETE, HOME, END, PgUp, PgDown } - // - MOD_KEY_FLAG = 1 << 9, - MOD_KEY_INT = 91, - HOME_KEY = 49 + MOD_KEY_FLAG, - INSERT_KEY = 50 + MOD_KEY_FLAG, - DELETE_KEY = 51 + MOD_KEY_FLAG, - END_KEY = 52 + MOD_KEY_FLAG, - PG_UP_KEY = 53 + MOD_KEY_FLAG, - PG_DOWN_KEY = 54 + MOD_KEY_FLAG, - MOD_KEY_BEGIN = HOME_KEY, - MOD_KEY_END = PG_DOWN_KEY, - MOD_KEY_DUMMY = 126, + // + // -- MOD keys: 27 -> 91 -> {49-54} -> 126 + // MOD_KEY = { INSERT, DELETE, HOME, END, PgUp, PgDown } + // + MOD_KEY_FLAG = 1 << 9, + MOD_KEY_INT = 91, + HOME_KEY = 49 + MOD_KEY_FLAG, + INSERT_KEY = 50 + MOD_KEY_FLAG, + DELETE_KEY = 51 + MOD_KEY_FLAG, + END_KEY = 52 + MOD_KEY_FLAG, + PG_UP_KEY = 53 + MOD_KEY_FLAG, + PG_DOWN_KEY = 54 + MOD_KEY_FLAG, + MOD_KEY_BEGIN = HOME_KEY, + MOD_KEY_END = PG_DOWN_KEY, + MOD_KEY_DUMMY = 126, - // - // [For undefined keys] - UNDEFINED_KEY = INT_MAX, + // + // [For undefined keys] + UNDEFINED_KEY = INT_MAX, - // For output only, you don't need to modify this part - BEEP_CHAR = 7, - BACK_SPACE_CHAR = 8, + // For output only, you don't need to modify this part + BEEP_CHAR = 7, + BACK_SPACE_CHAR = 8, - // dummy end - PARSE_CHAR_END + // dummy end + PARSE_CHAR_END }; -#else // TA_KB_SETTING is defined +#else // TA_KB_SETTING is defined // DO NOT CHANGE THIS PART... // DO NOT CHANGE THIS PART... // @@ -124,70 +121,67 @@ enum ParseChar // // TA will use "make -DTA_KB_SETTING" to test your program // -enum ParseChar -{ - // Simple keys: one code for one key press - // -- The following should be platform-independent - LINE_BEGIN_KEY = TA_LINE_BEGIN_KEY, // ctrl-a - LINE_END_KEY = TA_LINE_END_KEY, // ctrl-e - INPUT_END_KEY = TA_INPUT_END_KEY, // ctrl-d - TAB_KEY = TA_TAB_KEY, // tab('\t') or Ctrl-i - NEWLINE_KEY = TA_NEWLINE_KEY, // enter('\n') or ctrl-m - ESC_KEY = TA_ESC_KEY, // Not printable; used for combo keys +enum ParseChar { + // Simple keys: one code for one key press + // -- The following should be platform-independent + LINE_BEGIN_KEY = TA_LINE_BEGIN_KEY, // ctrl-a + LINE_END_KEY = TA_LINE_END_KEY, // ctrl-e + INPUT_END_KEY = TA_INPUT_END_KEY, // ctrl-d + TAB_KEY = TA_TAB_KEY, // tab('\t') or Ctrl-i + NEWLINE_KEY = TA_NEWLINE_KEY, // enter('\n') or ctrl-m + ESC_KEY = TA_ESC_KEY, // Not printable; used for combo keys - // -- The following simple/combo keys are platform-dependent - // You should test to check the returned codes of these key presses - // -- Use "testAsc.cpp" to test - // - // [FLAG bit for combo keys] - // -- Added to the returned ParseChar of combo keys - // -- i.e. The returned ParseChar will be "ComboKeyEnum + FLAG bit" - // -- This is to avoid the collision with the ASCII codes of regular keys - // -- Feel free to add/remove/modify on your own - // - // [Intermediate keys for combo keys] - // -- Intermediate keys are the common parts of combo keys - // - BACK_SPACE_KEY = TA_BACK_SPACE_KEY, - - // - // -- Arrow keys: 27 -> 91 -> {UP=65, DOWN=66, RIGHT=67, LEFT=68} - ARROW_KEY_FLAG = TA_ARROW_KEY_FLAG, - ARROW_KEY_INT = TA_ARROW_KEY_INT, - ARROW_UP_KEY = TA_ARROW_UP_KEY, - ARROW_DOWN_KEY = TA_ARROW_DOWN_KEY, - ARROW_RIGHT_KEY = TA_ARROW_RIGHT_KEY, - ARROW_LEFT_KEY = TA_ARROW_LEFT_KEY, - ARROW_KEY_BEGIN = TA_ARROW_KEY_BEGIN, - ARROW_KEY_END = TA_ARROW_KEY_END, + // -- The following simple/combo keys are platform-dependent + // You should test to check the returned codes of these key presses + // -- Use "testAsc.cpp" to test + // + // [FLAG bit for combo keys] + // -- Added to the returned ParseChar of combo keys + // -- i.e. The returned ParseChar will be "ComboKeyEnum + FLAG bit" + // -- This is to avoid the collision with the ASCII codes of regular keys + // -- Feel free to add/remove/modify on your own + // + // [Intermediate keys for combo keys] + // -- Intermediate keys are the common parts of combo keys + // + BACK_SPACE_KEY = TA_BACK_SPACE_KEY, - // - // -- MOD keys: 27 -> 91 -> {49-54} -> 126 - // MOD_KEY = { INSERT, DELETE, HOME, END, PgUp, PgDown } - // - MOD_KEY_FLAG = TA_MOD_KEY_FLAG, - MOD_KEY_INT = TA_MOD_KEY_INT, - HOME_KEY = TA_HOME_KEY, - INSERT_KEY = TA_INSERT_KEY, - DELETE_KEY = TA_DELETE_KEY, - END_KEY = TA_END_KEY, - PG_UP_KEY = TA_PG_UP_KEY, - PG_DOWN_KEY = TA_PG_DOWN_KEY, - MOD_KEY_BEGIN = TA_MOD_KEY_BEGIN, - MOD_KEY_END = TA_MOD_KEY_END, - MOD_KEY_DUMMY = TA_MOD_KEY_DUMMY, + // + // -- Arrow keys: 27 -> 91 -> {UP=65, DOWN=66, RIGHT=67, LEFT=68} + ARROW_KEY_FLAG = TA_ARROW_KEY_FLAG, + ARROW_KEY_INT = TA_ARROW_KEY_INT, + ARROW_UP_KEY = TA_ARROW_UP_KEY, + ARROW_DOWN_KEY = TA_ARROW_DOWN_KEY, + ARROW_RIGHT_KEY = TA_ARROW_RIGHT_KEY, + ARROW_LEFT_KEY = TA_ARROW_LEFT_KEY, + ARROW_KEY_BEGIN = TA_ARROW_KEY_BEGIN, + ARROW_KEY_END = TA_ARROW_KEY_END, - // - // [For undefined keys] - UNDEFINED_KEY = TA_UNDEFINED_KEY, + // + // -- MOD keys: 27 -> 91 -> {49-54} -> 126 + // MOD_KEY = { INSERT, DELETE, HOME, END, PgUp, PgDown } + // + MOD_KEY_FLAG = TA_MOD_KEY_FLAG, + MOD_KEY_INT = TA_MOD_KEY_INT, + HOME_KEY = TA_HOME_KEY, + INSERT_KEY = TA_INSERT_KEY, + DELETE_KEY = TA_DELETE_KEY, + END_KEY = TA_END_KEY, + PG_UP_KEY = TA_PG_UP_KEY, + PG_DOWN_KEY = TA_PG_DOWN_KEY, + MOD_KEY_BEGIN = TA_MOD_KEY_BEGIN, + MOD_KEY_END = TA_MOD_KEY_END, + MOD_KEY_DUMMY = TA_MOD_KEY_DUMMY, - // For output only, you don't need to modify this part - BEEP_CHAR = TA_BEEP_CHAR, - BACK_SPACE_CHAR = TA_BACK_SPACE_CHAR, + // + // [For undefined keys] + UNDEFINED_KEY = TA_UNDEFINED_KEY, - // dummy end - PARSE_CHAR_END -}; -#endif // TA_KB_SETTING + // For output only, you don't need to modify this part + BEEP_CHAR = TA_BEEP_CHAR, + BACK_SPACE_CHAR = TA_BACK_SPACE_CHAR, -#endif // CMD_CHAR_DEF_H + // dummy end + PARSE_CHAR_END +}; + // TA_KB_SETTING diff --git a/src/cmd/cmdParser.h b/src/cmd/cmdParser.h index e9c2933e..1a2f9fce 100644 --- a/src/cmd/cmdParser.h +++ b/src/cmd/cmdParser.h @@ -3,22 +3,20 @@ PackageName [ cmd ] Synopsis [ Define class CmdParser ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2007-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#ifndef CMD_PARSER_H -#define CMD_PARSER_H +#pragma once -#include #include -#include -#include +#include #include #include +#include +#include #include "cmdCharDef.h" // #include "gvCmdMgr.h" - using namespace std; //---------------------------------------------------------------------- @@ -28,159 +26,147 @@ using namespace std; class CmdExec; class CmdParser; - //---------------------------------------------------------------------- // External declaration //---------------------------------------------------------------------- extern CmdParser* cmdMgr; - //---------------------------------------------------------------------- // command execution status //---------------------------------------------------------------------- -enum CmdExecStatus -{ - GV_CMD_EXEC_DONE = 0, - GV_CMD_EXEC_ERROR = 1, - GV_CMD_EXEC_QUIT = 2, - GV_CMD_EXEC_NOP = 3, - - // dummy - GV_CMD_EXEC_TOT +enum CmdExecStatus { + GV_CMD_EXEC_DONE = 0, + GV_CMD_EXEC_ERROR = 1, + GV_CMD_EXEC_QUIT = 2, + GV_CMD_EXEC_NOP = 3, + + // dummy + GV_CMD_EXEC_TOT }; -enum CmdOptionError -{ - GV_CMD_OPT_MISSING = 0, - GV_CMD_OPT_EXTRA = 1, - GV_CMD_OPT_ILLEGAL = 2, - GV_CMD_OPT_FOPEN_FAIL = 3, +enum CmdOptionError { + GV_CMD_OPT_MISSING = 0, + GV_CMD_OPT_EXTRA = 1, + GV_CMD_OPT_ILLEGAL = 2, + GV_CMD_OPT_FOPEN_FAIL = 3, - // dummy - GV_CMD_OPT_ERROR_TOT + // dummy + GV_CMD_OPT_ERROR_TOT }; - //---------------------------------------------------------------------- // Base class : CmdExec //---------------------------------------------------------------------- -class CmdExec -{ +class CmdExec { public: - CmdExec() {} - virtual ~CmdExec() {} + CmdExec() {} + virtual ~CmdExec() {} - virtual CmdExecStatus exec(const string&) = 0; - virtual void usage(ostream&) const = 0; - virtual void help() const = 0; + virtual CmdExecStatus exec(const string&) = 0; + virtual void usage(ostream&) const = 0; + virtual void help() const = 0; - void setOptCmd(const string& str) { _optCmd = str; } - bool checkOptCmd(const string& check) const; // Removed for TODO... - const string& getOptCmd() const { return _optCmd; } + void setOptCmd(const string& str) { _optCmd = str; } + bool checkOptCmd(const string& check) const; // Removed for TODO... + const string& getOptCmd() const { return _optCmd; } protected: - bool lexSingleOption(const string&, string&, bool optional = true) const; - bool lexOptions(const string&, vector&, size_t nOpts = 0) const; - CmdExecStatus errorOption(CmdOptionError err, const string& opt) const; + bool lexSingleOption(const string&, string&, bool optional = true) const; + bool lexOptions(const string&, vector&, size_t nOpts = 0) const; + CmdExecStatus errorOption(CmdOptionError err, const string& opt) const; private: - string _optCmd; + string _optCmd; }; -#define CmdClass(T) \ -class T: public CmdExec \ -{ \ -public: \ - T() {} \ - ~T() {} \ - CmdExecStatus exec(const string& option); \ - void usage(ostream& os) const; \ - void help() const; \ -} - +#define CmdClass(T) \ + class T : public CmdExec { \ + public: \ + T() {} \ + ~T() {} \ + CmdExecStatus exec(const string& option); \ + void usage(ostream& os) const; \ + void help() const; \ + } //---------------------------------------------------------------------- // Base class : CmdParser //---------------------------------------------------------------------- -class CmdParser -{ -#define READ_BUF_SIZE 65536 -#define PG_OFFSET 10 +class CmdParser { +#define READ_BUF_SIZE 65536 +#define PG_OFFSET 10 -typedef map CmdMap; -typedef pair CmdRegPair; + typedef map CmdMap; + typedef pair CmdRegPair; public: - CmdParser(const string& p) : _prompt(p), _dofile(0), - _readBufPtr(_readBuf), _readBufEnd(_readBuf), - _historyIdx(0), _tabPressCount(0), _tempCmdStored(false) {} - virtual ~CmdParser() {} + CmdParser(const string& p) : _prompt(p), _dofile(0), + _readBufPtr(_readBuf), _readBufEnd(_readBuf), + _historyIdx(0), _tabPressCount(0), _tempCmdStored(false) {} + virtual ~CmdParser() {} - bool openDofile(const string& dof); - void closeDofile(); + bool openDofile(const string& dof); + void closeDofile(); - bool regCmd(const string&, unsigned, CmdExec*); - CmdExecStatus execOneCmd(); - void printHelps() const; + bool regCmd(const string&, unsigned, CmdExec*); + CmdExecStatus execOneCmd(); + void printHelps() const; - // public helper functions - void printHistory(int nPrint = -1) const; - CmdExec* getCmd(string); + // public helper functions + void printHistory(int nPrint = -1) const; + CmdExec* getCmd(string); private: - // Private member functions - void resetBufAndPrintPrompt() { + // Private member functions + void resetBufAndPrintPrompt() { _readBufPtr = _readBufEnd = _readBuf; - *_readBufPtr = 0; - _tabPressCount = 0; + *_readBufPtr = 0; + _tabPressCount = 0; printPrompt(); - } - ParseChar getChar(istream&) const; - bool readCmd(istream&); - CmdExec* parseCmd(string&); - void listCmd(const string&); - bool listCmdDir(const string&); // Removed for TODO... - void printPrompt() const { cout << _prompt; } - bool pushDofile(); // Removed for TODO's - bool popDofile(); // Removed for TODO's - - // Helper functions - bool moveBufPtr(char* const); - bool deleteChar(); - void insertChar(char, int = 1); - void deleteLine(); - void reprintCmd(); - void moveToHistory(int index); - bool addHistory(); - void retrieveHistory(); - #ifdef TA_KB_SETTING - void taTestOnly() {} - #endif - - // Data members - const string _prompt; // command prompt - ifstream* _dofile; // for command script - char _readBuf[READ_BUF_SIZE];// save the current line input - // be consistent as shown on the screen - char* _readBufPtr; // point to the cursor position - // also be the insert and delete point - char* _readBufEnd; // end of string position of _readBuf - // make sure *_readBufEnd = 0 - vector _history; // oldest:_history[0],latest:_hist.back() - int _historyIdx; // (1) Position to insert history string - // i.e. _historyIdx = _history.size() - // (2) When up/down/pgUp/pgDn is pressed, - // position to history to retrieve - size_t _tabPressCount; // The number of tab pressed - bool _tempCmdStored; // When up/pgUp is pressed, current line - // will be stored in _history and - // _tempCmdStored will be true. - // Reset to false when new command added - CmdMap _cmdMap; // map from string to command - stack _dofileStack; // For recursive dofile calling + } + ParseChar getChar(istream&) const; + bool readCmd(istream&); + CmdExec* parseCmd(string&); + void listCmd(const string&); + bool listCmdDir(const string&); // Removed for TODO... + void printPrompt() const { cout << _prompt; } + bool pushDofile(); // Removed for TODO's + bool popDofile(); // Removed for TODO's + + // Helper functions + bool moveBufPtr(char* const); + bool deleteChar(); + void insertChar(char, int = 1); + void deleteLine(); + void reprintCmd(); + void moveToHistory(int index); + bool addHistory(); + void retrieveHistory(); +#ifdef TA_KB_SETTING + void taTestOnly() {} + + + // Data members + const string _prompt; // command prompt + ifstream* _dofile; // for command script + char _readBuf[READ_BUF_SIZE]; // save the current line input + // be consistent as shown on the screen + char* _readBufPtr; // point to the cursor position + // also be the insert and delete point + char* _readBufEnd; // end of string position of _readBuf + // make sure *_readBufEnd = 0 + vector _history; // oldest:_history[0],latest:_hist.back() + int _historyIdx; // (1) Position to insert history string + // i.e. _historyIdx = _history.size() + // (2) When up/down/pgUp/pgDn is pressed, + // position to history to retrieve + size_t _tabPressCount; // The number of tab pressed + bool _tempCmdStored; // When up/pgUp is pressed, current line + // will be stored in _history and + // _tempCmdStored will be true. + // Reset to false when new command added + CmdMap _cmdMap; // map from string to command + stack _dofileStack; // For recursive dofile calling }; - - -#endif // CMD_PARSER_H diff --git a/src/cmd/gvCmdComm.cpp b/src/cmd/gvCmdComm.cpp index de7b781e..156d03ee 100644 --- a/src/cmd/gvCmdComm.cpp +++ b/src/cmd/gvCmdComm.cpp @@ -1,19 +1,18 @@ -#ifndef GV_CMD_COMM_C -#define GV_CMD_COMM_C #include "gvCmdComm.h" + +#include + #include "gvMsg.h" -#include "gvUsage.h" #include "util.h" -#include -bool -GVinitCommonCmd() { + +bool initCommonCmd() { return (gvCmdMgr->regCmd("DOfile", 2, new GVDofileCmd) && gvCmdMgr->regCmd("HELp", 3, new GVHelpCmd) && gvCmdMgr->regCmd("HIStory", 3, new GVHistoryCmd) && - gvCmdMgr->regCmd("USAGE", 5, new GVUsageCmd) && gvCmdMgr->regCmd("Quit", 1, new GVQuitCmd)); + /*gvCmdMgr->regCmd("USAGE", 5, new GVUsageCmd) &&*/ } //---------------------------------------------------------------------- @@ -25,7 +24,7 @@ GVHelpCmd::exec(const string& option) { vector options; GVCmdExec::lexOptions(option, options); - bool verbose = false, revealed = false; + bool verbose = false, revealed = false; string cmd = ""; size_t n = options.size(); @@ -51,16 +50,16 @@ GVHelpCmd::exec(const string& option) { } } - if (revealed) gvCmdMgr->printHelps(true); // Print All Commands - else if (!cmd.size()) gvCmdMgr->printHelps(); // Print Commands + if (revealed) gvCmdMgr->printHelps(true); // Print All Commands + else if (!cmd.size()) gvCmdMgr->printHelps(); // Print Commands else { GVCmdExec* e = gvCmdMgr->getCmd(cmd); if (e) { e->usage(verbose); return GV_CMD_EXEC_DONE; - } // if exact match + } // if exact match GVCmdExecSubSet list = gvCmdMgr->getCmdListFromPart(cmd); - if (list.size()) { // if partial match + if (list.size()) { // if partial match GVCmdExecSubSet::iterator it = list.begin(); if (verbose) for (; it != list.end(); ++it) (*it)->usage(); @@ -72,22 +71,20 @@ GVHelpCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -GVHelpCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: HELp [<(string cmd) [-Verbose]>]" << endl; +void GVHelpCmd::usage(const bool& verbose) const { + cout << "Usage: HELp [<(string cmd) [-Verbose]>]" << endl; if (verbose) { - gvMsg(GV_MSG_IFO) + cout << "Param: (string cmd): The (partial) name of the command." << endl; - gvMsg(GV_MSG_IFO) << " -Verbose : Print usage in more detail." - << endl; + cout << " -Verbose : Print usage in more detail." + << endl; } } -void -GVHelpCmd::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "HELp: " - << "Print this help message." << endl; +void GVHelpCmd::help() const { + cout << setw(20) << left << "HELp: " + << "Print this help message." << endl; } //---------------------------------------------------------------------- @@ -106,7 +103,7 @@ GVQuitCmd::exec(const string& option) { else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); } - gvMsg(GV_MSG_IFO) << "Are you sure to quit (Yes/No)? [No] "; + cout << "Are you sure to quit (Yes/No)? [No] "; char str[1024]; cin.getline(str, 1024); string ss = string(str); @@ -118,19 +115,17 @@ GVQuitCmd::exec(const string& option) { else return GV_CMD_EXEC_DONE; } -void -GVQuitCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: Quit [-Force]" << endl; +void GVQuitCmd::usage(const bool& verbose) const { + cout << "Usage: Quit [-Force]" << endl; if (verbose) { - gvMsg(GV_MSG_IFO) << "Param: -Force: Quit the program forcedly." - << endl; + cout << "Param: -Force: Quit the program forcedly." + << endl; } } -void -GVQuitCmd::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "Quit: " - << "Quit the execution." << endl; +void GVQuitCmd::help() const { + cout << setw(20) << left << "Quit: " + << "Quit the execution." << endl; } //---------------------------------------------------------------------- @@ -151,20 +146,18 @@ GVHistoryCmd::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -GVHistoryCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: HIStory [(int nPrint)]" << endl; +void GVHistoryCmd::usage(const bool& verbose) const { + cout << "Usage: HIStory [(int nPrint)]" << endl; if (verbose) { - gvMsg(GV_MSG_IFO) << "Param: (int nPrint): The number of the latest " - "commands to be printed. (default = MAX)" - << endl; + cout << "Param: (int nPrint): The number of the latest " + "commands to be printed. (default = MAX)" + << endl; } } -void -GVHistoryCmd::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "HIStory: " - << "Print command history." << endl; +void GVHistoryCmd::help() const { + cout << setw(20) << left << "HIStory: " + << "Print command history." << endl; } //---------------------------------------------------------------------- @@ -188,69 +181,64 @@ GVDofileCmd ::exec(const string& option) { return GV_CMD_EXEC_DONE; } -void -GVDofileCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: DOfile <(string fileName)>" << endl; +void GVDofileCmd ::usage(const bool& verbose) const { + cout << "Usage: DOfile <(string fileName)>" << endl; if (verbose) { - gvMsg(GV_MSG_IFO) + cout << "Param: (string fileName): The file name of the script." << endl; } } -void -GVDofileCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "DOfile: " - << "Execute the commands in the dofile." << endl; +void GVDofileCmd ::help() const { + cout << setw(20) << left << "DOfile: " + << "Execute the commands in the dofile." << endl; } //---------------------------------------------------------------------- // USAGE [-Time-only | -Memory-only] [-RESET] //---------------------------------------------------------------------- -GVCmdExecStatus -GVUsageCmd ::exec(const string& option) { - vector options; - GVCmdExec::lexOptions(option, options); - - bool timeOnly = false, memoryOnly = false, reset = false; - - size_t n = options.size(); - for (size_t i = 0; i < n; ++i) { - const string& token = options[i]; - if (myStrNCmp("-Time-only", token, 2) == 0) { - if (timeOnly || memoryOnly) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - else timeOnly = true; - } else if (myStrNCmp("-Memory-only", token, 2) == 0) { - if (timeOnly || memoryOnly) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - else memoryOnly = true; - } else if (myStrNCmp("-RESET", token, 6) == 0) { - if (reset) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - else reset = true; - } else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); - } - - gvUsage.report(!memoryOnly, !timeOnly); - if (reset) gvUsage.reset(); - return GV_CMD_EXEC_DONE; -} - -void -GVUsageCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: USAGE [-Time-only | -Memory-only]" << endl; - if (verbose) { - gvMsg(GV_MSG_IFO) - << "Param: -Time-only : Disable memory usage reporting." << endl; - gvMsg(GV_MSG_IFO) - << " -Memory-only: Disable time usage reporting." << endl; - } -} - -void -GVUsageCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "USAGE: " - << "Report resource usage." << endl; -} +/*GVCmdExecStatus*/ +/*GVUsageCmd ::exec(const string& option) {*/ +/* vector options;*/ +/* GVCmdExec::lexOptions(option, options);*/ +/**/ +/* bool timeOnly = false, memoryOnly = false, reset = false;*/ +/**/ +/* size_t n = options.size();*/ +/* for (size_t i = 0; i < n; ++i) {*/ +/* const string& token = options[i];*/ +/* if (myStrNCmp("-Time-only", token, 2) == 0) {*/ +/* if (timeOnly || memoryOnly)*/ +/* return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token);*/ +/* else timeOnly = true;*/ +/* } else if (myStrNCmp("-Memory-only", token, 2) == 0) {*/ +/* if (timeOnly || memoryOnly)*/ +/* return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token);*/ +/* else memoryOnly = true;*/ +/* } else if (myStrNCmp("-RESET", token, 6) == 0) {*/ +/* if (reset) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token);*/ +/* else reset = true;*/ +/* } else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token);*/ +/* }*/ +/**/ +/* gvUsage.report(!memoryOnly, !timeOnly);*/ +/* if (reset) gvUsage.reset();*/ +/* return GV_CMD_EXEC_DONE;*/ +/*}*/ +/**/ +/*void GVUsageCmd ::usage(const bool& verbose) const {*/ +/* cout << "Usage: USAGE [-Time-only | -Memory-only]" << endl;*/ +/* if (verbose) {*/ +/* cout*/ +/* << "Param: -Time-only : Disable memory usage reporting." << endl;*/ +/* cout*/ +/* << " -Memory-only: Disable time usage reporting." << endl;*/ +/* }*/ +/*}*/ +/**/ +/*void GVUsageCmd ::help() const {*/ +/* cout << setw(20) << left << "USAGE: "*/ +/* << "Report resource usage." << endl;*/ +/*}*/ -#endif \ No newline at end of file diff --git a/src/cmd/gvCmdComm.h b/src/cmd/gvCmdComm.h index 2384eb8f..a4413a3c 100644 --- a/src/cmd/gvCmdComm.h +++ b/src/cmd/gvCmdComm.h @@ -1,5 +1,4 @@ -#ifndef GV_CMD_COMM_H -#define GV_CMD_COMM_H +#pragma once #include "gvCmdMgr.h" @@ -11,4 +10,3 @@ GV_COMMAND(GVUsageCmd, GV_CMD_TYPE_COMMON); GV_COMMAND(GVLogFileCmd, GV_CMD_TYPE_COMMON); -#endif \ No newline at end of file diff --git a/src/cmd/gvCmdMgr.cpp b/src/cmd/gvCmdMgr.cpp index 402363b2..3101d8ba 100644 --- a/src/cmd/gvCmdMgr.cpp +++ b/src/cmd/gvCmdMgr.cpp @@ -1,27 +1,30 @@ #ifndef GV_CMD_MGR_C #define GV_CMD_MGR_C +#include "gvCmdMgr.h" + #include #include #include #include -#include "gvCmdMgr.h" #include "gvMsg.h" +#include "gvType.h" #include "util.h" -extern "C" -{ +extern "C" { #include #include } +extern GVCmdExecStatus appCmdHandlerItf(); +extern ModType getMode(); + /* -------------------------------------------------- *\ * Class GVCmdMgr Implementations \* -------------------------------------------------- */ -bool -GVCmdExec::operator<(const GVCmdExec& rhs) const { +bool GVCmdExec::operator<(const GVCmdExec& rhs) const { string lstr, rstr; for (size_t idx = 0; idx < _cmdLen; ++idx) { if (idx != 0) lstr.append(" "); @@ -36,8 +39,7 @@ GVCmdExec::operator<(const GVCmdExec& rhs) const { return (lstr < rstr); } -void -GVCmdExec::lexOptions(const string& option, vector& tokens) const { +void GVCmdExec::lexOptions(const string& option, vector& tokens) const { string token; size_t n = myStrGetTok(option, token); while (token.size()) { @@ -46,57 +48,53 @@ GVCmdExec::lexOptions(const string& option, vector& tokens) const { } } -bool -GVCmdExec::lexSingleOption -(const string& option, string& token, bool optional) const -{ - size_t n = myStrGetTok(option, token); - if (!optional) { - if (token.size() == 0) { - errorOption(GV_CMD_OPT_MISSING, ""); - return false; - } - } - if (n != string::npos) { - errorOption(GV_CMD_OPT_EXTRA, option.substr(n)); - return false; - } - return true; +bool GVCmdExec::lexSingleOption(const string& option, string& token, bool optional) const { + size_t n = myStrGetTok(option, token); + if (!optional) { + if (token.size() == 0) { + errorOption(GV_CMD_OPT_MISSING, ""); + return false; + } + } + if (n != string::npos) { + errorOption(GV_CMD_OPT_EXTRA, option.substr(n)); + return false; + } + return true; } GVCmdExecStatus GVCmdExec::errorOption(GVCmdOptionError err, const string& opt) const { switch (err) { - case GV_CMD_OPT_MISSING: - if (opt.size()) - gvMsg(GV_MSG_ERR) << "Missing option \"" << opt << "\" !!" << endl; - else - gvMsg(GV_MSG_ERR) << "Missing option" - << "!!" << endl; - break; - case GV_CMD_OPT_EXTRA: - gvMsg(GV_MSG_ERR) << "Extra option \"" << opt << "\" !!" << endl; - break; - case GV_CMD_OPT_ILLEGAL: - gvMsg(GV_MSG_ERR) << "Illegal option \"" << opt << "\" !!" << endl; - break; - case GV_CMD_OPT_FOPEN_FAIL: - gvMsg(GV_MSG_ERR) << "Error: cannot open file \"" << opt << "\" !!" - << endl; - break; - default: - gvMsg(GV_MSG_ERR) << "Unknown option error type \"" << err << "\" !!" - << endl; - break; + case GV_CMD_OPT_MISSING: + if (opt.size()) + gvMsg(GV_MSG_ERR) << "Missing option \"" << opt << "\" !!" << endl; + else + gvMsg(GV_MSG_ERR) << "Missing option" + << "!!" << endl; + break; + case GV_CMD_OPT_EXTRA: + gvMsg(GV_MSG_ERR) << "Extra option \"" << opt << "\" !!" << endl; + break; + case GV_CMD_OPT_ILLEGAL: + gvMsg(GV_MSG_ERR) << "Illegal option \"" << opt << "\" !!" << endl; + break; + case GV_CMD_OPT_FOPEN_FAIL: + gvMsg(GV_MSG_ERR) << "Error: cannot open file \"" << opt << "\" !!" + << endl; + break; + default: + gvMsg(GV_MSG_ERR) << "Unknown option error type \"" << err << "\" !!" + << endl; + break; } return GV_CMD_EXEC_ERROR; } -bool -GVCmdExec::checkCmd(const string& check) const { - unsigned len = this->getCmdLen(); - bool result = false; - size_t space = 0, nxt_space; +bool GVCmdExec::checkCmd(const string& check) const { + unsigned len = this->getCmdLen(); + bool result = false; + size_t space = 0, nxt_space; for (unsigned word = 1; word <= len; ++word) { nxt_space = check.find(' ', space + 1); @@ -104,7 +102,7 @@ GVCmdExec::checkCmd(const string& check) const { for (unsigned i = space + 1; i <= nxt_space; ++i) { string checkMand = check.substr(space, i - space); - string checkOpt = check.substr(i, nxt_space - space - i); + string checkOpt = check.substr(i, nxt_space - space - i); if (checkMandCmd(checkMand, word) && (checkOpt.empty() || checkOptCmd(checkOpt, word))) { @@ -115,21 +113,20 @@ GVCmdExec::checkCmd(const string& check) const { if (result == false) return false; result = false; - space = nxt_space + 1; + space = nxt_space + 1; } return true; } -bool -GVCmdExec::checkCmd(const string& check, size_t idx) const { +bool GVCmdExec::checkCmd(const string& check, size_t idx) const { if (idx >= this->getCmdLen()) return false; bool result = false; for (unsigned i = 1, n = check.size(); i <= n; ++i) { string checkMand = check.substr(0, i); - string checkOpt = check.substr(i, n + 1 - i); + string checkOpt = check.substr(i, n + 1 - i); if (checkMandCmd(checkMand, idx) && (checkOpt.empty() || checkOptCmd(checkOpt, idx))) { @@ -140,8 +137,7 @@ GVCmdExec::checkCmd(const string& check, size_t idx) const { return result; } -bool -GVCmdExec::checkMandCmd(const string& check, size_t idx) const { +bool GVCmdExec::checkMandCmd(const string& check, size_t idx) const { if (check.size() != _mandCmd[idx - 1].size()) return false; for (unsigned i = 0, n = _mandCmd[idx - 1].size(); i < n; ++i) { if (!check[i]) return true; @@ -152,8 +148,7 @@ GVCmdExec::checkMandCmd(const string& check, size_t idx) const { return true; } -bool -GVCmdExec::checkOptCmd(const string& check, size_t idx) const { +bool GVCmdExec::checkOptCmd(const string& check, size_t idx) const { if (check.size() > _optCmd[idx - 1].size()) return false; for (unsigned i = 0, n = _optCmd[idx - 1].size(); i < n; ++i) { if (!check[i]) return true; @@ -177,8 +172,7 @@ GVCmdMgr::~GVCmdMgr() { if (_dofile.is_open()) _dofile.close(); } -bool -GVCmdMgr::regCmd(const string& cmd, unsigned nCmp, GVCmdExec* e) { +bool GVCmdMgr::regCmd(const string& cmd, unsigned nCmp, GVCmdExec* e) { assert(e); assert(cmd.size()); assert(nCmp); @@ -195,20 +189,19 @@ GVCmdMgr::regCmd(const string& cmd, unsigned nCmp, GVCmdExec* e) { e->setMandCmd(str.substr(0, nCmp)); e->setOptCmd(str.substr(nCmp)); - GVCmdExecSet::iterator it = _cmdLib.find(e->getGVCmdType()); - GVCmdExecSubSet* cmdSet = 0; + GVCmdExecSet::iterator it = _cmdLib.find(e->getGVCmdType()); + GVCmdExecSubSet* cmdSet = 0; if (it == _cmdLib.end()) { cmdSet = new GVCmdExecSubSet(); _cmdLib.insert(make_pair(e->getGVCmdType(), cmdSet)); - } else cmdSet = it->second; + } else + cmdSet = it->second; cmdSet->insert(e); return true; } -bool -GVCmdMgr::regCmd(const string& cmd, unsigned nCmp1, unsigned nCmp2, - GVCmdExec* e) { +bool GVCmdMgr::regCmd(const string& cmd, unsigned nCmp1, unsigned nCmp2, GVCmdExec* e) { assert(e); assert(cmd.size()); assert(nCmp1); @@ -236,33 +229,48 @@ GVCmdMgr::regCmd(const string& cmd, unsigned nCmp1, unsigned nCmp2, e->setMandCmd(str2.substr(0, nCmp2)); e->setOptCmd(str2.substr(nCmp2)); - GVCmdExecSet::iterator it = _cmdLib.find(e->getGVCmdType()); - GVCmdExecSubSet* cmdSet = 0; + GVCmdExecSet::iterator it = _cmdLib.find(e->getGVCmdType()); + GVCmdExecSubSet* cmdSet = 0; if (it == _cmdLib.end()) { cmdSet = new GVCmdExecSubSet(); _cmdLib.insert(make_pair(e->getGVCmdType(), cmdSet)); - } else cmdSet = it->second; + } else + cmdSet = it->second; cmdSet->insert(e); return true; } GVCmdExecStatus GVCmdMgr::execOneCmd() { + // Ridirect Commands to Application Command Handler + if (getMode() == MOD_TYPE_APP) { + appCmdHandlerItf(); + return GV_CMD_EXEC_DONE; + } + // Read User Command Input - string str = ""; - char* execCmd = new char[1024]; + string str = ""; + char* execCmd = new char[1024]; if (_dofile.is_open()) { getline(_dofile, str); strcpy(execCmd, str.c_str()); - cout << getPrompt() << execCmd << endl; + // Detect dofile comment(#) and blank command + if (str.substr(0, 2) != "//" && str.size() > 0) + cout << getPrompt() << execCmd << endl; + else + return GV_CMD_EXEC_COMMENT; if (_dofile.eof()) closeDofile(); - } else execCmd = readline(getPrompt().c_str()); + } else + execCmd = readline(getPrompt().c_str()); assert(execCmd); + // Detect dofile comment(#) for debugging + // if (str.substr(0, 2) == "//") return GV_CMD_EXEC_NOP; + if (addHistory(execCmd)) { add_history(_history.back().c_str()); - string option = ""; - GVCmdExec* e = parseCmd(option); + string option = ""; + GVCmdExec* e = parseCmd(option); // Check command types if (e) { GVCmdType cmdType = e->getGVCmdType(); @@ -278,10 +286,10 @@ GVCmdMgr::execOneCmd() { } } } - if (e) return e->exec(option); } delete[] execCmd; + return GV_CMD_EXEC_NOP; } @@ -292,7 +300,7 @@ GVCmdMgr::parseCmd(string& option) { assert(str[0] != 0 && str[0] != ' '); GVCmdExec* e = 0; - string cmd; + string cmd; // normalize: keep only one space between two words unsigned delCount = 0; @@ -335,7 +343,8 @@ GVCmdMgr::parseCmd(string& option) { if ((_cmd == "ls") || (_cmd == "vi") || (_cmd == "vim") || (_cmd == "echo") || (_cmd == "cat") || (_cmd == "clear")) system(str.c_str()); - else gvMsg(GV_MSG_ERR) << "Illegal command!! (" << str << ")" << endl; + else + gvMsg(GV_MSG_ERR) << "Illegal command!! (" << str << ")" << endl; } else if (idx != string::npos) { size_t opt = str.find_first_not_of(' ', idx); if (opt != string::npos) option = str.substr(opt); @@ -354,7 +363,7 @@ GVCmdMgr::getCmd(const string& cmd) const { if (cmd[i] == ' ') ++spCount; GVCmdExecSet::const_iterator it; - GVCmdExecSubSet::iterator is; + GVCmdExecSubSet::iterator is; for (it = _cmdLib.begin(); it != _cmdLib.end(); ++it) { for (is = it->second->begin(); is != it->second->end(); ++is) { if (((*is)->getCmdLen() == spCount + 1) && (*is)->checkCmd(cmd)) { @@ -377,7 +386,7 @@ GVCmdMgr::getCmdListFromPart(const string& cmd) const { if (cmd[i] == ' ') ++spCount; GVCmdExecSet::const_iterator it; - GVCmdExecSubSet::iterator is; + GVCmdExecSubSet::iterator is; for (it = _cmdLib.begin(); it != _cmdLib.end(); ++it) { if (it->first != GV_CMD_TYPE_REVEALED) { for (is = it->second->begin(); is != it->second->end(); ++is) { @@ -397,37 +406,34 @@ GVCmdMgr::getCmdListFromPart(const string& cmd) const { return result; } -void -GVCmdMgr::printHelps(bool revealed) const { +void GVCmdMgr::printHelps(bool revealed) const { GVCmdExecSet::const_iterator it; - GVCmdExecSubSet::iterator is; - gvMsg(GV_MSG_IFO) << endl; + GVCmdExecSubSet::iterator is; + cout << endl; for (it = _cmdLib.begin(); it != _cmdLib.end(); ++it) { if ((revealed) ^ (it->first != GV_CMD_TYPE_REVEALED)) { - gvMsg(GV_MSG_IFO) << "========== " << GVCmdTypeString[it->first] - << " Commands : ==========" << endl; + cout << "========== " << GVCmdTypeString[it->first] + << " Commands : ==========" << endl; for (is = it->second->begin(); is != it->second->end(); ++is) (*is)->help(); - gvMsg(GV_MSG_IFO) << endl; + cout << endl; } } } -void -GVCmdMgr::printHistory(int nPrint) const { +void GVCmdMgr::printHistory(int nPrint) const { int historySize = _history.size(); if (historySize == 0) { - gvMsg(GV_MSG_IFO) << "Empty command history!!" << endl; + cout << "Empty command history!!" << endl; return; } if ((nPrint < 0) || (nPrint > historySize)) nPrint = historySize; assert(historySize >= nPrint); for (int i = historySize - nPrint; i < historySize; ++i) - gvMsg(GV_MSG_IFO) << " " << i << ": " << _history[i] << endl; + cout << " " << i << ": " << _history[i] << endl; } -bool -GVCmdMgr::addHistory(char* cmd) { +bool GVCmdMgr::addHistory(char* cmd) { // remove ' ' at the end char* tmp = &(cmd[strlen(cmd) - 1]); while ((tmp >= cmd) && (*tmp == ' ')) *(tmp--) = 0; diff --git a/src/cmd/gvCmdMgr.h b/src/cmd/gvCmdMgr.h index c7e57039..68e3affb 100644 --- a/src/cmd/gvCmdMgr.h +++ b/src/cmd/gvCmdMgr.h @@ -1,5 +1,4 @@ -#ifndef GV_CMD_MGR_H -#define GV_CMD_MGR_H +#pragma once #include #include @@ -18,140 +17,153 @@ extern GVCmdMgr* gvCmdMgr; // Command Categories to String const string GVCmdTypeString[] = {"Revealed", "Common", "Verify", "Simulate", "Network", - "Abc", "Mode", "Bdd", "Prove", "Itp"}; + "Abc", "Yosys", "Mode", "Bdd", "Prove", "Itp", "APP", "EXP"}; // Command Categories Enum -enum GVCmdType -{ +enum GVCmdType { // Revealed command - GV_CMD_TYPE_REVEALED = 0, - GV_CMD_TYPE_COMMON = 1, - GV_CMD_TYPE_VERIFY = 2, - GV_CMD_TYPE_SIMULATE = 3, - GV_CMD_TYPE_NETWORK = 4, - GV_CMD_TYPE_ABC = 5, - GV_CMD_TYPE_MOD = 6, - GV_CMD_TYPE_BDD = 7, - GV_CMD_TYPE_PROVE = 8, - GV_CMD_TYPE_ITP = 9, + GV_CMD_TYPE_REVEALED = 0, + GV_CMD_TYPE_COMMON = 1, + GV_CMD_TYPE_VERIFY = 2, + GV_CMD_TYPE_SIMULATE = 3, + GV_CMD_TYPE_NETWORK = 4, + GV_CMD_TYPE_ABC = 5, + GV_CMD_TYPE_YOSYS = 6, + GV_CMD_TYPE_MOD = 7, + GV_CMD_TYPE_BDD = 8, + GV_CMD_TYPE_PROVE = 9, + GV_CMD_TYPE_ITP = 10, + GV_CMD_TYPE_APP = 11, + GV_CMD_TYPE_EXPERIMENT = 12, }; -enum GVCmdExecStatus -{ - GV_CMD_EXEC_DONE = 0, - GV_CMD_EXEC_ERROR = 1, - GV_CMD_EXEC_QUIT = 2, - GV_CMD_EXEC_NOP = 3, +enum GVCmdExecStatus { + GV_CMD_EXEC_DONE = 0, + GV_CMD_EXEC_ERROR = 1, + GV_CMD_EXEC_QUIT = 2, + GV_CMD_EXEC_NOP = 3, + GV_CMD_EXEC_COMMENT = 4, }; -enum GVCmdOptionError -{ +enum GVCmdOptionError { GV_CMD_OPT_MISSING = 0, GV_CMD_OPT_EXTRA = 1, GV_CMD_OPT_ILLEGAL = 2, GV_CMD_OPT_FOPEN_FAIL = 3, }; -const unordered_set _setupMode{GV_CMD_TYPE_REVEALED, GV_CMD_TYPE_COMMON, GV_CMD_TYPE_NETWORK, - GV_CMD_TYPE_ABC, GV_CMD_TYPE_MOD, GV_CMD_TYPE_BDD}; - -const unordered_set _vrfMode{GV_CMD_TYPE_VERIFY, GV_CMD_TYPE_SIMULATE, GV_CMD_TYPE_COMMON, - GV_CMD_TYPE_MOD, GV_CMD_TYPE_PROVE, GV_CMD_TYPE_ITP}; - -#define GV_COMMAND(cmd, type) \ - class cmd : public GVCmdExec \ - { \ - public: \ - cmd() : GVCmdExec(type) {} \ - ~cmd() {} \ - GVCmdExecStatus exec(const string&); \ - void usage(const bool& = false) const; \ - void help() const; \ +const unordered_set _setupMode{ + GV_CMD_TYPE_REVEALED, + GV_CMD_TYPE_COMMON, + GV_CMD_TYPE_NETWORK, + GV_CMD_TYPE_ABC, + GV_CMD_TYPE_MOD, + GV_CMD_TYPE_BDD, + GV_CMD_TYPE_YOSYS, + GV_CMD_TYPE_EXPERIMENT, + GV_CMD_TYPE_SIMULATE}; + +const unordered_set _vrfMode{ + GV_CMD_TYPE_VERIFY, + GV_CMD_TYPE_SIMULATE, + GV_CMD_TYPE_COMMON, + GV_CMD_TYPE_MOD, + GV_CMD_TYPE_PROVE, + GV_CMD_TYPE_ITP, + GV_CMD_TYPE_EXPERIMENT}; + +#define GV_COMMAND(cmd, type) \ + class cmd : public GVCmdExec { \ + public: \ + cmd() : GVCmdExec(type) {} \ + ~cmd() {} \ + GVCmdExecStatus exec(const string&); \ + void usage(const bool& = false) const; \ + void help() const; \ }; -class GVCmdExec -{ - public: - GVCmdExec(GVCmdType t) : _cmdType(t) {} - virtual ~GVCmdExec() {} - virtual GVCmdExecStatus exec(const string&) = 0; - virtual void usage(const bool& = false) const = 0; - virtual void help() const = 0; - - inline GVCmdType getGVCmdType() const { return _cmdType; }; - inline void setCmdLen(unsigned n) { _cmdLen = n; } - inline unsigned getCmdLen() const { return _cmdLen; } - inline void setMandCmd(const string& str) { _mandCmd.push_back(str); } - inline const string& getMandCmd(size_t idx) const { return _mandCmd[idx]; } - inline void setOptCmd(const string& str) { _optCmd.push_back(str); } - inline const string& getOptCmd(size_t idx) const { return _optCmd[idx]; } - bool checkCmd(const string&) const; - bool checkCmd(const string&, size_t) const; - bool checkMandCmd(const string&, size_t) const; - bool checkOptCmd(const string&, size_t) const; - - bool operator<(const GVCmdExec&) const; - - protected: - void lexOptions(const string&, vector&) const; - bool lexSingleOption(const string&, string&, bool optional = true) const; - GVCmdExecStatus errorOption(GVCmdOptionError err, const string& opt) const; - - private: - GVCmdType _cmdType; - unsigned _cmdLen; - vector _mandCmd; - vector _optCmd; +class GVCmdExec { +public: + GVCmdExec(GVCmdType t) : _cmdType(t) {} + virtual ~GVCmdExec() {} + virtual GVCmdExecStatus exec(const string&) = 0; + virtual void usage(const bool& = false) const = 0; + virtual void help() const = 0; + + inline GVCmdType getGVCmdType() const { return _cmdType; }; + inline void setCmdLen(unsigned n) { _cmdLen = n; } + inline unsigned getCmdLen() const { return _cmdLen; } + inline void setMandCmd(const string& str) { _mandCmd.push_back(str); } + inline void setOptCmd(const string& str) { _optCmd.push_back(str); } + inline const string& getMandCmd(size_t idx) const { return _mandCmd[idx]; } + inline const string& getOptCmd(size_t idx) const { return _optCmd[idx]; } + bool checkCmd(const string&) const; + bool checkCmd(const string&, size_t) const; + bool checkMandCmd(const string&, size_t) const; + bool checkOptCmd(const string&, size_t) const; + + bool operator<(const GVCmdExec&) const; + +protected: + void lexOptions(const string&, vector&) const; + bool lexSingleOption(const string&, string&, bool optional = true) const; + GVCmdExecStatus errorOption(GVCmdOptionError err, const string& opt) const; + +private: + GVCmdType _cmdType; + unsigned _cmdLen; + vector _mandCmd; + vector _optCmd; }; struct GVCmdCompare { - bool operator()(const GVCmdExec* a, const GVCmdExec* b) const { return (*a < *b); } + bool operator()(const GVCmdExec* a, const GVCmdExec* b) const { return (*a < *b); } }; -typedef set GVCmdExecSubSet; +typedef set GVCmdExecSubSet; typedef map GVCmdExecSet; -class GVCmdMgr -{ +class GVCmdMgr { #define READ_BUF_SIZE 65536 #define PG_OFFSET 10 - public: - GVCmdMgr(const string&); - ~GVCmdMgr(); - GVCmdExec* getCmd(const string&) const; - GVCmdExecSubSet getCmdListFromPart(const string&) const; - bool regCmd(const string&, unsigned, GVCmdExec*); - bool regCmd(const string&, unsigned, unsigned, GVCmdExec*); - - GVCmdExecStatus execOneCmd(); - - void printHelps(bool = false) const; - void printHistory(int = -1) const; - - bool openDofile(const string& dof) { - _dofile.open(dof.c_str()); - return _dofile.is_open(); - } - void closeDofile() { - _dofile.close(); - _dofile.clear(); - } - - inline const string& getPrompt() const { return _prompt; } - inline void updateModPrompt(const string newPromt) { _modPrompt = newPromt; } - inline void setPrompt() { _prompt = _modPrompt + "> "; } - - private: - // Command Helper Functions - bool addHistory(char*); - GVCmdExec* parseCmd(string&); - // Command Data members - const string _defaultPrompt; // Default Command Prompt - string _modPrompt; // Current Command Prompt - string _prompt; // Current Command Prompt - ifstream _dofile; // For Script Parsing - GVCmdExecSet _cmdLib; - vector _history; +public: + GVCmdMgr(const string&); + virtual ~GVCmdMgr(); + GVCmdExec* getCmd(const string&) const; + GVCmdExecSubSet getCmdListFromPart(const string&) const; + bool regCmd(const string&, unsigned, GVCmdExec*); + bool regCmd(const string&, unsigned, unsigned, GVCmdExec*); + + GVCmdExecStatus execOneCmd(); + + // Command Helper Functions + bool addHistory(char*); + virtual GVCmdExec* parseCmd(string&); + + void printHelps(bool = false) const; + void printHistory(int = -1) const; + + bool openDofile(const string& dof) { + _dofile.open(dof.c_str()); + return _dofile.is_open(); + } + void closeDofile() { + _dofile.close(); + _dofile.clear(); + } + + inline ifstream& getDofile() { return _dofile; } + inline vector& getHistory() { return _history; } + inline const string& getPrompt() const { return _prompt; } + inline void updateModPrompt(const string newPromt) { _modPrompt = newPromt; } + inline void setPrompt() { _prompt = _modPrompt + "> "; } + +private: + // Command Data members + const string _defaultPrompt; // Default Command Prompt + string _modPrompt; // Current Command Prompt + string _prompt; // Current Command Prompt + ifstream _dofile; // For Script Parsing + GVCmdExecSet _cmdLib; + vector _history; }; - -#endif \ No newline at end of file diff --git a/src/eng/abcc b/src/eng/abcc deleted file mode 120000 index 36aa79f2..00000000 --- a/src/eng/abcc +++ /dev/null @@ -1 +0,0 @@ -../../engine/abc/gv_src \ No newline at end of file diff --git a/src/eng/boolector b/src/eng/boolector deleted file mode 120000 index b29828ff..00000000 --- a/src/eng/boolector +++ /dev/null @@ -1 +0,0 @@ -../../engine/boolector/gv_src_boolector \ No newline at end of file diff --git a/src/eng/btor2parser b/src/eng/btor2parser deleted file mode 120000 index 3877ead7..00000000 --- a/src/eng/btor2parser +++ /dev/null @@ -1 +0,0 @@ -../../engine/boolector/gv_src_btor2parser \ No newline at end of file diff --git a/src/eng/lgl b/src/eng/lgl deleted file mode 120000 index b50ef7c4..00000000 --- a/src/eng/lgl +++ /dev/null @@ -1 +0,0 @@ -../../engine/boolector/gv_src_lgl \ No newline at end of file diff --git a/src/eng/yosys b/src/eng/yosys deleted file mode 120000 index 5eeaead6..00000000 --- a/src/eng/yosys +++ /dev/null @@ -1 +0,0 @@ -../../engine/yosys/gv_src \ No newline at end of file diff --git a/src/exp/expCmd.cpp b/src/exp/expCmd.cpp new file mode 100644 index 00000000..2fdb7c60 --- /dev/null +++ b/src/exp/expCmd.cpp @@ -0,0 +1,34 @@ +#ifndef GV_SIM_CMD_C +#define GV_SIM_CMD_C + +#include "expCmd.h" + +#include + +#include "gvMsg.h" +#include "iostream" + +bool initExpCmd() { + return (gvCmdMgr->regCmd("EXPeriment", 3, new ExpCmd)); +} + + +//---------------------------------------------------------------------- +// EXPeriment +//---------------------------------------------------------------------- +GVCmdExecStatus ExpCmd::exec(const string& option) { + //! Place your experimental functions and commands here + + return GV_CMD_EXEC_DONE; +} + +void ExpCmd::usage(const bool& verbose) const { + gvMsg(GV_MSG_IFO) << "Usage: Experiment " << endl; +} + +void ExpCmd::help() const { + gvMsg(GV_MSG_IFO) << setw(20) << std::left << "EXPeriment: " + << "Command for the testing of the experimental functions." << endl; +} + +#endif diff --git a/src/exp/expCmd.h b/src/exp/expCmd.h new file mode 100644 index 00000000..f6b173c7 --- /dev/null +++ b/src/exp/expCmd.h @@ -0,0 +1,8 @@ +#pragma once + + +#include "gvCmdMgr.h" + +GV_COMMAND(ExpCmd, GV_CMD_TYPE_EXPERIMENT); + + diff --git a/src/ext/CMakeLists.txt b/src/ext/CMakeLists.txt new file mode 100644 index 00000000..da4f775b --- /dev/null +++ b/src/ext/CMakeLists.txt @@ -0,0 +1,24 @@ +# project(YOSYS_EXTENSION) + +# Collect all source files +file(GLOB MY_SOURCES "./*.cc") + +# Make the plugin library with the .so suffix +set(CMAKE_SHARED_LIBRARY_SUFFIX ".so") + +# Compile each .cc file into a .so file +foreach(source_file ${MY_SOURCES}) + # Extract the file name (without path and extension) + get_filename_component(name ${source_file} NAME_WE) + # Compile each .cc file into a .so file + add_library(${name} SHARED ${source_file}) + set_property(TARGET ${name} PROPERTY POSITION_INDEPENDENT_CODE ON) + target_include_directories(${name} PRIVATE ${YOSYS_DIR}) + if(APPLE) + target_link_options(${name} PRIVATE "-dynamic" "-undefined" "dynamic_lookup") + else() + target_link_options(${name} PRIVATE "-rdynamic") + endif() + target_compile_definitions(${name} PRIVATE _YOSYS_) + add_dependencies(${name} engine-yosys) +endforeach() diff --git a/src/ext/Makefile b/src/ext/Makefile deleted file mode 100644 index 8ccf3eb4..00000000 --- a/src/ext/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -CSRCS = $(wildcard *.cc) -CSOBJS = $(addsuffix .so, $(basename $(CSRCS))) -CDEPS = $(addsuffix .d, $(basename $(CSRCS))) - -YOSYSCONF = ../../yosys-config -I../../include --build -YOSYSCONF = ../../yosys-config --exec --cxx --cxxflags -I../../include --ldflags -o - -all: $(CSOBJS) - -%.so: %.cc - @echo "Compiling extension $@" - @echo "$(YOSYSCONF) $@ $< " - $(YOSYSCONF) $@ -shared $< --ldlibs - -clean: - @rm -f $(CSOBJS) - -.SILENT: - -.PHONY: all clean - - - - diff --git a/src/ext/sim.cc b/src/ext/sim.cc index 4d67f499..6a750d1f 100644 --- a/src/ext/sim.cc +++ b/src/ext/sim.cc @@ -1,344 +1,354 @@ #include -#include #include #include #include -#include #include + +#include +#include #include USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct randomSim : public Pass { - randomSim() : Pass("random_sim", "") {} - void help() override { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" randomSim [options]\n"); - log("\n"); - log("Warning : you sould run read_verilog & hierarchy -top first\n"); - log("Run random simulation on the given verilog file\n"); - log("\n"); - log(" <-input>\n"); - log(" The name of the verilog file you want to simulate\n"); - log(" <-top>\n"); - log(" The top module name of the verilog file you want to simulate\n"); - log(" [-clk]\n"); - log(" The clock name of the verilog file you want to simulate\n"); - log(" Default to be \"clk\"\n"); - log(" [-reset]\n"); - log(" The reset name of the verilog file you want to simulate\n"); - log(" Default to be \"reset\"\n"); - log(" reset when reset = 1\n"); - log(" [-reset_n]\n"); - log(" The reset_n name of the verilog file you want to simulate\n"); - log(" Default to be \"reset_n\"\n"); - log(" reset when reset_n = 0\n"); - log(" Only one of reset and reset_n should be set\n"); - log(" [-output]\n"); - log(" The name of output file which contains the simulation result\n"); - log(" [-v]\n"); - log(" verbose print the result of simulation on the command line\n"); - } - void execute(std::vector args, Design* design) override { - int sim_cycle = 20, property = -1; - size_t argidx, num_inputs = 0; - bool reset_set = false, property_set = false; - bool reset_n_set = false; - bool clk_set = false; - bool verbose = false, verilog_file_name_set = false; - bool output_file_set = false, top_module_name_set = false, stimulus = false; - bool vcd_file_set = false; - std::string reset_name = "reset"; - std::string reset_n_name = "reset_n"; - std::string clk_name = "clk"; - std::string output_file_name = "sim.txt"; - std::string verilog_file_name; - std::string top_module_name; - std::string stimulus_file_name; - std::string vcd_file_name; + randomSim() : Pass("random_sim", "") {} + void help() override { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" randomSim [options]\n"); + log("\n"); + log("Warning : you sould run read_verilog & hierarchy -top first\n"); + log("Run random simulation on the given verilog file\n"); + log("\n"); + log(" <-input>\n"); + log(" The name of the verilog file you want to simulate\n"); + log(" <-top>\n"); + log(" The top module name of the verilog file you want to simulate\n"); + log(" [-clk]\n"); + log(" The clock name of the verilog file you want to simulate\n"); + log(" Default to be \"clk\"\n"); + log(" [-reset]\n"); + log(" The reset name of the verilog file you want to simulate\n"); + log(" Default to be \"reset\"\n"); + log(" reset when reset = 1\n"); + log(" [-reset_n]\n"); + log(" The reset_n name of the verilog file you want to simulate\n"); + log(" Default to be \"reset_n\"\n"); + log(" reset when reset_n = 0\n"); + log(" Only one of reset and reset_n should be set\n"); + log(" [-output]\n"); + log(" The name of output file which contains the simulation result\n"); + log(" [-v]\n"); + log(" verbose print the result of simulation on the command line\n"); + } + void execute(std::vector args, Design* design) override { + int sim_cycle = 20, property = -1; + size_t argidx, num_inputs = 0; + bool reset_set = false, property_set = false; + bool reset_n_set = false; + bool clk_set = false; + bool verbose = false, verilog_file_name_set = false; + bool output_file_set = false, top_module_name_set = false, stimulus = false; + bool vcd_file_set = false; + std::string reset_name = "reset"; + std::string reset_n_name = "reset_n"; + std::string clk_name = "clk"; + std::string output_file_name = "sim.txt"; + std::string verilog_file_name; + std::string top_module_name; + std::string stimulus_file_name; + std::string vcd_file_name; - for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-sim_cycle" && argidx + 1 < args.size()) { - sim_cycle = atoi(args[++argidx].c_str()); - continue; - } - if (args[argidx] == "-reset" && argidx + 1 < args.size()) { - reset_name = args[++argidx]; - reset_set = true; - continue; - } - if (args[argidx] == "-reset_n" && argidx + 1 < args.size() && reset_set == false) { - reset_n_name = args[++argidx]; - reset_n_set = true; - continue; - } - if (args[argidx] == "-clk" && argidx + 1 < args.size()) { - clk_name = args[++argidx]; - clk_set = true; - continue; - } - if (args[argidx] == "-v") { - verbose = true; - continue; - } - if (args[argidx] == "-file" && argidx + 1 < args.size()) { - stimulus_file_name = args[++argidx]; - stimulus = true; - // log("innnnnnnnnnnnnn %s\n", stimulus_file_name.c_str()); - continue; - } - if (args[argidx] == "-output" && argidx + 1 < args.size()) { - output_file_set = true; - output_file_name = args[++argidx]; - continue; - } - if (args[argidx] == "-top" && argidx + 1 < args.size()) { - top_module_name = args[++argidx]; - top_module_name_set = true; - continue; - } - if (args[argidx] == "-input" && argidx + 1 < args.size()) { - verilog_file_name = args[++argidx]; - verilog_file_name_set = true; - continue; - } - if (args[argidx] == "-vcd" && argidx + 1 < args.size()) { - vcd_file_name = args[++argidx]; - vcd_file_set = true; - continue; - } - if (args[argidx] == "-safe" && argidx + 1 < args.size()) { - property = stoi(args[++argidx]); - property_set = true; - continue; - } - break; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-sim_cycle" && argidx + 1 < args.size()) { + sim_cycle = atoi(args[++argidx].c_str()); + continue; } - for (auto wire : design->top_module()->wires()) { - if (wire->port_input && strcmp(wire->name.c_str(), ("\\" + reset_n_name).c_str()) && - strcmp(wire->name.c_str(), ("\\" + reset_name).c_str()) && - strcmp(wire->name.c_str(), ("\\" + clk_name).c_str())) // check the wire is not rst or clk - ++num_inputs; + if (args[argidx] == "-reset" && argidx + 1 < args.size()) { + reset_name = args[++argidx]; + reset_set = true; + continue; } - std::string command = - "yosys -p \"read_verilog " + verilog_file_name + "; hierarchy -top " + top_module_name + "; write_cxxrtl .sim.cpp;\""; - run_command(command); - std::string wire_name; - std::string module_name; - std::ofstream ofs; - ofs.open(".sim_main.cpp"); - ofs << "#include \n"; - ofs << "#include \n"; - ofs << "#include \n"; - ofs << "#include \n"; - ofs << "#include \n"; - ofs << "#include \n"; - ofs << "#include \n"; - module_name = log_id(design->top_module()->name); - ofs << "#include \".sim.cpp\"\n"; - ofs << "using namespace std;\n"; - ofs << " int main()\n"; - ofs << "{\n"; - ofs << "srand(time(NULL));"; - ofs << "unsigned random_value = 0;\n"; - ofs << "unsigned upper_bound = 0;\n"; - - ofs << "char buffer[100];\n"; - if (stimulus) { - ofs << "vector> stimulus_signal;\n"; - ofs << "vector stimulus_cycle;\n"; - ofs << " std::ifstream ifs;\n"; - ofs << " ifs.open(\""; - ofs << stimulus_file_name; - ofs << "\");\n"; - ofs << " for(size_t i = 0; i < "; - ofs << sim_cycle; - ofs << "; ++i)\n"; - ofs << " {\n"; - ofs << " stimulus_cycle.clear();\n"; - ofs << " for(size_t j = 0; j < "; - ofs << num_inputs; - ofs << "; ++j)\n"; - ofs << " {\n"; - ofs << " ifs >> buffer;\n"; - ofs << " stimulus_cycle.push_back(std::stoi(std::string(buffer)));\n"; - ofs << " }\n"; - ofs << " stimulus_signal.push_back(stimulus_cycle);\n"; - ofs << " }\n"; - ofs << " ifs.close();\n"; + if (args[argidx] == "-reset_n" && argidx + 1 < args.size() && reset_set == false) { + reset_n_name = args[++argidx]; + reset_n_set = true; + continue; + } + if (args[argidx] == "-clk" && argidx + 1 < args.size()) { + clk_name = args[++argidx]; + clk_set = true; + continue; + } + if (args[argidx] == "-v") { + verbose = true; + continue; + } + if (args[argidx] == "-file" && argidx + 1 < args.size()) { + stimulus_file_name = args[++argidx]; + stimulus = true; + // log("innnnnnnnnnnnnn %s\n", stimulus_file_name.c_str()); + continue; + } + if (args[argidx] == "-output" && argidx + 1 < args.size()) { + output_file_set = true; + output_file_name = args[++argidx]; + continue; } - if (output_file_set) { - ofs << "ofstream ofs;\n"; - ofs << "ofs.open(\"" << output_file_name << "\");\n"; + if (args[argidx] == "-top" && argidx + 1 < args.size()) { + top_module_name = args[++argidx]; + top_module_name_set = true; + continue; } - ofs << " cxxrtl_design::p_" + module_name + " top;\n"; - // For VCD file. - if (vcd_file_set) { - ofs << "cxxrtl::debug_items all_debug_items;\n"; - ofs << "top.debug_info(all_debug_items);\n"; - ofs << "cxxrtl::vcd_writer vcd;\n"; - ofs << "vcd.timescale(1, \"us\");\n"; - ofs << "vcd.add_without_memories(all_debug_items);\n"; - ofs << "std::ofstream waves(\"" + vcd_file_name + "\");\n"; - ofs << "vcd.sample(0);\n"; + if (args[argidx] == "-input" && argidx + 1 < args.size()) { + verilog_file_name = args[++argidx]; + verilog_file_name_set = true; + continue; } + if (args[argidx] == "-vcd" && argidx + 1 < args.size()) { + vcd_file_name = args[++argidx]; + vcd_file_set = true; + continue; + } + if (args[argidx] == "-safe" && argidx + 1 < args.size()) { + property = stoi(args[++argidx]); + property_set = true; + continue; + } + break; + } + for (auto wire : design->top_module()->wires()) { + if (wire->port_input && strcmp(wire->name.c_str(), ("\\" + reset_n_name).c_str()) && + strcmp(wire->name.c_str(), ("\\" + reset_name).c_str()) && + strcmp(wire->name.c_str(), ("\\" + clk_name).c_str())) // check the wire is not rst or clk + ++num_inputs; + } + std::string command = + "yosys -qp \"read_verilog " + verilog_file_name + "; hierarchy -top " + top_module_name + "; write_cxxrtl .sim.cpp;\""; + run_command(command); + std::string wire_name; + std::string module_name; + std::ofstream ofs; + ofs.open(".sim_main.cpp"); + ofs << "#include \n"; + ofs << "#include \n"; + ofs << "#include \n"; + ofs << "#include \n"; + ofs << "#include \n"; + ofs << "#include \n"; + ofs << "#include \n"; + module_name = log_id(design->top_module()->name); + ofs << "#include \".sim.cpp\"\n"; + ofs << "using namespace std;\n"; + ofs << " int main()\n"; + ofs << "{\n"; + ofs << "srand(time(NULL));"; + ofs << "unsigned random_value = 0;\n"; + ofs << "unsigned upper_bound = 0;\n"; - ofs << "top.step();\n"; - ofs << "for(int cycle=0;cycle<" << sim_cycle << ";++cycle){\n"; - ofs << "top.p_" << clk_name << ".set(false);\n"; - ofs << "top.step();\n"; + ofs << "char buffer[100];\n"; + if (stimulus) { + ofs << "vector> stimulus_signal;\n"; + ofs << "vector stimulus_cycle;\n"; + ofs << " std::ifstream ifs;\n"; + ofs << " ifs.open(\""; + ofs << stimulus_file_name; + ofs << "\");\n"; + ofs << " for(size_t i = 0; i < "; + ofs << sim_cycle; + ofs << "; ++i)\n"; + ofs << " {\n"; + ofs << " stimulus_cycle.clear();\n"; + ofs << " for(size_t j = 0; j < "; + ofs << num_inputs; + ofs << "; ++j)\n"; + ofs << " {\n"; + ofs << " ifs >> buffer;\n"; + ofs << " stimulus_cycle.push_back(std::stoi(std::string(buffer)));\n"; + ofs << " }\n"; + ofs << " stimulus_signal.push_back(stimulus_cycle);\n"; + ofs << " }\n"; + ofs << " ifs.close();\n"; + } + if (output_file_set) { + ofs << "ofstream ofs;\n"; + ofs << "ofs.open(\"" << output_file_name << "\");\n"; + } + ofs << " cxxrtl_design::p_" + module_name + " top;\n"; + // For VCD file. + if (vcd_file_set) { + ofs << "cxxrtl::debug_items all_debug_items;\n"; + ofs << "top.debug_info(all_debug_items);\n"; + ofs << "cxxrtl::vcd_writer vcd;\n"; + ofs << "vcd.timescale(1, \"us\");\n"; + ofs << "vcd.add_without_memories(all_debug_items);\n"; + ofs << "std::ofstream waves(\"" + vcd_file_name + "\");\n"; + ofs << "vcd.sample(0);\n"; + } - // For VCD file. - if (vcd_file_set) ofs << "vcd.sample(cycle*2 + 0);\n"; + ofs << "top.step();\n"; + ofs << "for(int cycle=0;cycle<" << sim_cycle << ";++cycle){\n"; + ofs << "top.p_" << clk_name << ".set(false);\n"; + ofs << "top.step();\n"; - if (reset_set || reset_n_set) { - ofs << "if(cycle == 0)\n"; - if (reset_set) { - ofs << " top.p_" << reset_name << ".set(true);\n"; - ofs << "else\n"; - ofs << " top.p_" << reset_name << ".set(false);\n"; - } - if (reset_n_set) { - ofs << " top.p_" << reset_name << ".set(false);\n"; - ofs << "else\n"; - ofs << " top.p_" << reset_name << ".set(true);\n"; - } + // For VCD file. + if (vcd_file_set) ofs << "vcd.sample(cycle*2 + 0);\n"; + + if (reset_set || reset_n_set) { + ofs << "if(cycle == 0)\n"; + if (reset_set) { + ofs << " top.p_" << reset_name << ".set(true);\n"; + ofs << "else\n"; + ofs << " top.p_" << reset_name << ".set(false);\n"; + } + if (reset_n_set) { + ofs << " top.p_" << reset_n_name << ".set(false);\n"; + ofs << "else\n"; + ofs << " top.p_" << reset_n_name << ".set(true);\n"; } + } - ofs << "if(cycle > 0)\n"; - ofs << "{\n"; - ofs << "size_t idx = 0;\n"; - for (auto wire : design->top_module()->wires()) { - wire_name = wire->name.str().substr(1, strlen(wire->name.c_str()) - 1); + ofs << "if(cycle > 0)\n"; + ofs << "{\n"; + ofs << "size_t idx = 0;\n"; + for (auto wire : design->top_module()->wires()) { + wire_name = wire->name.str().substr(1, strlen(wire->name.c_str()) - 1); - // replace '_' with '+' - while (wire_name.find("_") != -1) { - wire_name.replace(wire_name.find("_"), 1, "+"); - // log("1111111111 wire_name = %s\n", wire_name.c_str()); - } + // replace '_' with '+' + while (wire_name.find("_") != -1) { + wire_name.replace(wire_name.find("_"), 1, "+"); + // log("1111111111 wire_name = %s\n", wire_name.c_str()); + } - // replace '+' with '__' - while (wire_name.find("+") != -1) { - wire_name.replace(wire_name.find("+"), 1, "__"); - // log("222222222222 wire_name = %s\n", wire_name.c_str()); - } + // replace '+' with '__' + while (wire_name.find("+") != -1) { + wire_name.replace(wire_name.find("+"), 1, "__"); + // log("222222222222 wire_name = %s\n", wire_name.c_str()); + } - // if(wire_name.find("_") != -1) - // wire_name.replace(wire_name.find("_"), 1, "__"); - if (wire->port_input && strcmp(wire->name.c_str(), ("\\" + reset_n_name).c_str()) && - strcmp(wire->name.c_str(), ("\\" + reset_name).c_str()) && - strcmp(wire->name.c_str(), ("\\" + clk_name).c_str())) // check the wire is not rst or clk + // if(wire_name.find("_") != -1) + // wire_name.replace(wire_name.find("_"), 1, "__"); + if (wire->port_input && strcmp(wire->name.c_str(), ("\\" + reset_n_name).c_str()) && + strcmp(wire->name.c_str(), ("\\" + reset_name).c_str()) && + strcmp(wire->name.c_str(), ("\\" + clk_name).c_str())) // check the wire is not rst or clk + { + if (!stimulus) // if no stimulus is given, we generate a random one { - if (!stimulus) // if no stimulus is given, we generate a random one - { + // (1) If there's a large-bits wire (e.g. 256-bits memory) that exceed "unsigned range (0 ~ 65535)", + // please slice it to smaller wires, otherwise will cause error in Yosys + // (2) Also, if assigns a wrong size value to wires (e.g. assign "pow(2, 2)" to "256-bits memory"), it will violate Yosys assertion + // TODO: preprocess the large-bits wire with ".slice()" and ".concat()" to assign value + if (wire->width > 16) { + log_error("There's a large-bits wire that exceed \"unsigned range (0 ~ 65535)\", please slice it to smaller wires all within 16 bits\n"); + } else { + // randomly assign value ofs << "upper_bound = pow(2, " << wire->width << ");\n"; ofs << "random_value = rand() % upper_bound;\n"; ofs << "top.p_" << wire_name << ".set(random_value)" << ";\n"; - } else { - ofs << "top.p_" << wire_name << ".set(stimulus_signal[cycle][idx])" - << ";\n"; - ofs << "++idx;\n"; } - - // log("str len = %d\n", wire_name); + } else { + ofs << "top.p_" << wire_name << ".set(stimulus_signal[cycle][idx])" + << ";\n"; + ofs << "++idx;\n"; } + + // log("str len = %d\n", wire_name); } - ofs << "}\n"; + } + ofs << "}\n"; - ofs << "top.p_" << clk_name << ".set(true);\n"; - ofs << "top.step();\n"; - // For VCD file. - if (vcd_file_set) ofs << "vcd.sample(cycle*2 + 1);\n"; - for (auto wire : design->top_module()->wires()) { - wire_name = wire->name.str().substr(1, strlen(wire->name.c_str()) - 1); - string wire_name_long = wire_name; - // replace '_' with '+' - while (wire_name_long.find("_") != -1) { - wire_name_long.replace(wire_name_long.find("_"), 1, "+"); - } + ofs << "top.p_" << clk_name << ".set(true);\n"; + ofs << "top.step();\n"; + // For VCD file. + if (vcd_file_set) ofs << "vcd.sample(cycle*2 + 1);\n"; + for (auto wire : design->top_module()->wires()) { + wire_name = wire->name.str().substr(1, strlen(wire->name.c_str()) - 1); + string wire_name_long = wire_name; + // replace '_' with '+' + while (wire_name_long.find("_") != -1) { + wire_name_long.replace(wire_name_long.find("_"), 1, "+"); + } - // replace '+' with '__' - while (wire_name_long.find("+") != -1) { - wire_name_long.replace(wire_name_long.find("+"), 1, "__"); - } + // replace '+' with '__' + while (wire_name_long.find("+") != -1) { + wire_name_long.replace(wire_name_long.find("+"), 1, "__"); + } + // char *wire_name; + if (wire->port_output) { + // strncpy(wire_name, &wire->name.c_str()[1], strlen(wire->name.c_str()) - 1); + // log("width = %d", wire->width); + // log("output name = %s\n", wire->name.str().substr(1,strlen(wire->name.c_str()) - 1)); + ofs << "uint32_t " << wire_name << " = top.p_" << wire_name_long << ".get();" + << "\n"; + // log("str len = %d\n", wire_name); + } + } + // For VCD file. + if (vcd_file_set) { + ofs << "waves << vcd.buffer;\n"; + ofs << "vcd.buffer.clear();\n"; + } + if (verbose) { + ofs << "cout << \"==========================================\\n\";\n"; + ofs << "cout << \"= cycle \"" + << " << cycle + 1 " + << "<< \"\\n\";\n"; + ofs << "cout << \"==========================================\\n\";\n"; + for (auto wire : design->top_module()->wires()) { + std::string wire_name = wire->name.str().substr(1, strlen(wire->name.c_str()) - 1); // char *wire_name; if (wire->port_output) { - // strncpy(wire_name, &wire->name.c_str()[1], strlen(wire->name.c_str()) - 1); - // log("width = %d", wire->width); - // log("output name = %s\n", wire->name.str().substr(1,strlen(wire->name.c_str()) - 1)); - ofs << "uint32_t " << wire_name << " = top.p_" << wire_name_long << ".get();" - << "\n"; - // log("str len = %d\n", wire_name); + ofs << "cout << \"" << wire_name << "= \"" + << " << " << wire_name << " << \"\\n\"" + << ";\n"; } } - // For VCD file. - if (vcd_file_set) { - ofs << "waves << vcd.buffer;\n"; - ofs << "vcd.buffer.clear();\n"; - } - if (verbose) { - ofs << "cout << \"==========================================\\n\";\n"; - ofs << "cout << \"= cycle \"" - << " << cycle + 1 " - << "<< \"\\n\";\n"; - ofs << "cout << \"==========================================\\n\";\n"; - for (auto wire : design->top_module()->wires()) { - std::string wire_name = wire->name.str().substr(1, strlen(wire->name.c_str()) - 1); - // char *wire_name; - if (wire->port_output) { - ofs << "cout << \"" << wire_name << "= \"" - << " << " << wire_name << " << \"\\n\"" - << ";\n"; - } - } - ofs << "cout << endl;"; - } + ofs << "cout << endl;"; + } - size_t idx = 0; - if (property_set) { - for (auto wire : design->top_module()->wires()) { - if (wire->port_output) { - if (idx == property) { - std::string wire_name = wire->name.str().substr(1, strlen(wire->name.c_str()) - 1); - ofs << "if(" + wire_name + " == 1)\n"; - ofs << "{\n"; - ofs << "cout << \"property unsafe!!!\" << endl;\n"; - ofs << "break;\n"; - ofs << "}\n"; - } - idx++; + size_t idx = 0; + if (property_set) { + for (auto wire : design->top_module()->wires()) { + if (wire->port_output) { + if (idx == property) { + std::string wire_name = wire->name.str().substr(1, strlen(wire->name.c_str()) - 1); + ofs << "if(" + wire_name + " == 1)\n"; + ofs << "{\n"; + ofs << "cout << \"property unsafe!!!\" << endl;\n"; + ofs << "break;\n"; + ofs << "}\n"; } + idx++; } } + } - if (output_file_set) { - ofs << "ofs << \"==========================================\\n\";\n"; - ofs << "ofs << \"= cycle \"" - << " << cycle + 1 " - << "<< \"\\n\";\n"; - ofs << "ofs << \"==========================================\\n\";\n"; - for (auto wire : design->top_module()->wires()) { - std::string wire_name = wire->name.str().substr(1, strlen(wire->name.c_str()) - 1); - // char *wire_name; - if (wire->port_output) { - ofs << "ofs << \"" << wire_name << "= \"" - << " << " << wire_name << " << \"\\n\"" - << ";\n"; - } + if (output_file_set) { + ofs << "ofs << \"==========================================\\n\";\n"; + ofs << "ofs << \"= cycle \"" + << " << cycle + 1 " + << "<< \"\\n\";\n"; + ofs << "ofs << \"==========================================\\n\";\n"; + for (auto wire : design->top_module()->wires()) { + std::string wire_name = wire->name.str().substr(1, strlen(wire->name.c_str()) - 1); + // char *wire_name; + if (wire->port_output) { + ofs << "ofs << \"" << wire_name << "= \"" + << " << " << wire_name << " << \"\\n\"" + << ";\n"; } } - - ofs << "}\n"; - if (output_file_set) ofs << "ofs.close();\n"; - ofs << "}\n"; - ofs << "\n"; - ofs.close(); - run_command(" g++ -g -O3 -std=c++14 -I `yosys-config --datdir`/include .sim_main.cpp -o .tb "); - run_command(" ./.tb "); } + + ofs << "}\n"; + if (output_file_set) ofs << "ofs.close();\n"; + ofs << "}\n"; + ofs << "\n"; + ofs.close(); + run_command(" g++ -g -O3 -std=c++14 -I `yosys-config --datdir`/include .sim_main.cpp -o .tb "); + run_command(" ./.tb "); + } } randomSim; PRIVATE_NAMESPACE_END diff --git a/src/ext/sim.so b/src/ext/sim.so deleted file mode 100755 index 89343984..00000000 Binary files a/src/ext/sim.so and /dev/null differ diff --git a/src/itp/.depend.mak b/src/itp/.depend.mak deleted file mode 100644 index 5224f0a4..00000000 --- a/src/itp/.depend.mak +++ /dev/null @@ -1,108 +0,0 @@ -gvSatMgr.o: gvSatMgr.cpp gvSatMgr.h ../../include/gvNtk.h \ - ../../include/gvAbcMgr.h ../../include/base/abc/abc.h \ - ../../include/misc/vec/vec.h ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/abc/abc.h \ - ../../include/base/main/abcapis.h ../../include/base/cmd/cmd.h \ - ../../include/base/io/ioAbc.h ../../include/misc/util/utilNam.h \ - ../../include/base/main/mainInt.h ../../include/base/main/main.h \ - ../../include/misc/tim/tim.h ../../include/map/if/if.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/util/utilTruth.h \ - ../../include/opt/dau/dau.h ../../include/misc/vec/vecHash.h \ - ../../include/aig/aig/aig.h ../../include/proof/ssw/ssw.h \ - ../../include/proof/fra/fra.h ../../include/opt/dar/dar.h \ - ../../include/sat/bsat/satSolver.h ../../include/sat/bsat/satVec.h \ - ../../include/sat/bsat/satClause.h ../../include/misc/util/utilDouble.h \ - ../../include/aig/ioa/ioa.h ../../include/gvAbcNtk.h \ - ../../include/kernel/sigtools.h ../../include/kernel/yosys.h \ - /usr/include/tcl8.6/tcl.h /usr/include/tcl8.6/tclDecls.h \ - /usr/include/tcl8.6/tclPlatDecls.h ../../include/kernel/hashlib.h \ - ../../include/kernel/log.h ../../include/kernel/rtlil.h \ - ../../include/kernel/constids.inc ../../include/kernel/register.h \ - ../../include/kernel/utils.h ../../include/kernel/yosys.h gvSat.h \ - SolverV.h ProofV.h SolverTypesV.h GlobalV.h FileV.h VarOrderV.h HeapV.h \ - gvBitVec.h ../../include/gvIntType.h reader.h ../../include/gvMsg.h -FileV.o: FileV.cpp FileV.h GlobalV.h -reader.o: reader.cpp reader.h -gvSat.o: gvSat.cpp gvSat.h SolverV.h ProofV.h SolverTypesV.h GlobalV.h \ - FileV.h VarOrderV.h HeapV.h gvBitVec.h ../../include/gvIntType.h \ - ../../include/gvNtk.h ../../include/gvAbcMgr.h \ - ../../include/base/abc/abc.h ../../include/misc/vec/vec.h \ - ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/abc/abc.h \ - ../../include/base/main/abcapis.h ../../include/base/cmd/cmd.h \ - ../../include/base/io/ioAbc.h ../../include/misc/util/utilNam.h \ - ../../include/base/main/mainInt.h ../../include/base/main/main.h \ - ../../include/misc/tim/tim.h ../../include/map/if/if.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/util/utilTruth.h \ - ../../include/opt/dau/dau.h ../../include/misc/vec/vecHash.h \ - ../../include/aig/aig/aig.h ../../include/proof/ssw/ssw.h \ - ../../include/proof/fra/fra.h ../../include/opt/dar/dar.h \ - ../../include/sat/bsat/satSolver.h ../../include/sat/bsat/satVec.h \ - ../../include/sat/bsat/satClause.h ../../include/misc/util/utilDouble.h \ - ../../include/aig/ioa/ioa.h ../../include/gvAbcNtk.h \ - ../../include/kernel/sigtools.h ../../include/kernel/yosys.h \ - /usr/include/tcl8.6/tcl.h /usr/include/tcl8.6/tclDecls.h \ - /usr/include/tcl8.6/tclPlatDecls.h ../../include/kernel/hashlib.h \ - ../../include/kernel/log.h ../../include/kernel/rtlil.h \ - ../../include/kernel/constids.inc ../../include/kernel/register.h \ - ../../include/kernel/utils.h ../../include/kernel/yosys.h -gvSatCmd.o: gvSatCmd.cpp gvSatCmd.h ../../include/gvCmdMgr.h \ - ../../include/gvMsg.h gvSatMgr.h ../../include/gvNtk.h \ - ../../include/gvAbcMgr.h ../../include/base/abc/abc.h \ - ../../include/misc/vec/vec.h ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/abc/abc.h \ - ../../include/base/main/abcapis.h ../../include/base/cmd/cmd.h \ - ../../include/base/io/ioAbc.h ../../include/misc/util/utilNam.h \ - ../../include/base/main/mainInt.h ../../include/base/main/main.h \ - ../../include/misc/tim/tim.h ../../include/map/if/if.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/util/utilTruth.h \ - ../../include/opt/dau/dau.h ../../include/misc/vec/vecHash.h \ - ../../include/aig/aig/aig.h ../../include/proof/ssw/ssw.h \ - ../../include/proof/fra/fra.h ../../include/opt/dar/dar.h \ - ../../include/sat/bsat/satSolver.h ../../include/sat/bsat/satVec.h \ - ../../include/sat/bsat/satClause.h ../../include/misc/util/utilDouble.h \ - ../../include/aig/ioa/ioa.h ../../include/gvAbcNtk.h \ - ../../include/kernel/sigtools.h ../../include/kernel/yosys.h \ - /usr/include/tcl8.6/tcl.h /usr/include/tcl8.6/tclDecls.h \ - /usr/include/tcl8.6/tclPlatDecls.h ../../include/kernel/hashlib.h \ - ../../include/kernel/log.h ../../include/kernel/rtlil.h \ - ../../include/kernel/constids.inc ../../include/kernel/register.h \ - ../../include/kernel/utils.h ../../include/kernel/yosys.h gvSat.h \ - SolverV.h ProofV.h SolverTypesV.h GlobalV.h FileV.h VarOrderV.h HeapV.h \ - gvBitVec.h ../../include/gvIntType.h reader.h ../../include/util.h \ - ../../include/rnGen.h ../../include/myUsage.h -gvBitVec.o: gvBitVec.cpp gvBitVec.h ../../include/gvIntType.h \ - ../../include/gmpxx.h ../../include/gmp.h -ProofV.o: ProofV.cpp ProofV.h SolverTypesV.h GlobalV.h FileV.h SortV.h -SolverV.o: SolverV.cpp SolverV.h ProofV.h SolverTypesV.h GlobalV.h \ - FileV.h VarOrderV.h HeapV.h SortV.h diff --git a/src/itp/.extheader.mak b/src/itp/.extheader.mak deleted file mode 100644 index 45cf6833..00000000 --- a/src/itp/.extheader.mak +++ /dev/null @@ -1,13 +0,0 @@ -itp.d: ../../include/gvSat.h ../../include/gvSatMgr.h ../../include/gvSatCmd.h ../../include/VarOrderV.h -../../include/gvSat.h: gvSat.h - @rm -f ../../include/gvSat.h - @ln -fs ../src/itp/gvSat.h ../../include/gvSat.h -../../include/gvSatMgr.h: gvSatMgr.h - @rm -f ../../include/gvSatMgr.h - @ln -fs ../src/itp/gvSatMgr.h ../../include/gvSatMgr.h -../../include/gvSatCmd.h: gvSatCmd.h - @rm -f ../../include/gvSatCmd.h - @ln -fs ../src/itp/gvSatCmd.h ../../include/gvSatCmd.h -../../include/VarOrderV.h: VarOrderV.h - @rm -f ../../include/VarOrderV.h - @ln -fs ../src/itp/VarOrderV.h ../../include/VarOrderV.h diff --git a/src/itp/.map.txt b/src/itp/.map.txt deleted file mode 100644 index ed313d68..00000000 --- a/src/itp/.map.txt +++ /dev/null @@ -1,12 +0,0 @@ -input 0 0 i -input 1 0 clk -output 0 0 z0 -output 1 0 z1 -output 2 0 z2 -output 3 0 z3 -latch 0 0 x -latch 1 0 y -latch 2 0 prev_i -latch 3 0 counter -latch 4 1 counter -latch 5 2 counter diff --git a/src/itp/HeapV.h b/src/itp/HeapV.h deleted file mode 100644 index cddf6693..00000000 --- a/src/itp/HeapV.h +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************************[Heap.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Heap_h -#define Heap_h - - -//================================================================================================= - - -static inline int left (int i) { return i+i; } -static inline int right (int i) { return i+i + 1; } -static inline int parent(int i) { return i >> 1; } - -template -class Heap { - public: - C comp; - vec heap; // heap of ints - vec indices; // int -> index in heap - - inline void percolateUp(int i) - { - int x = heap[i]; - while (parent(i) != 0 && comp(x,heap[parent(i)])){ - heap[i] = heap[parent(i)]; - indices[heap[i]] = i; - i = parent(i); - } - heap [i] = x; - indices[x] = i; - } - - inline void percolateDown(int i) - { - int x = heap[i]; - while (left(i) < heap.size()){ - int child = right(i) < heap.size() && comp(heap[right(i)],heap[left(i)]) ? right(i) : left(i); - if (!comp(heap[child],x)) break; - heap[i] = heap[child]; - indices[heap[i]] = i; - i = child; - } - heap [i] = x; - indices[x] = i; - } - - bool ok(int n) { return n >= 0 && n < (int)indices.size(); } - - public: - Heap(C c) : comp(c) { heap.push(-1); } - - void setBounds (int size) { assert(size >= 0); indices.growTo(size,0); } - bool inHeap (int n) { assert(ok(n)); return indices[n] != 0; } - void increase (int n) { assert(ok(n)); assert(inHeap(n)); percolateUp(indices[n]); } - bool empty () { return heap.size() == 1; } - - void insert(int n) { - assert(ok(n)); - indices[n] = heap.size(); - heap.push(n); - percolateUp(indices[n]); } - - int getmin() { - int r = heap[1]; - heap[1] = heap.last(); - indices[heap[1]] = 1; - indices[r] = 0; - heap.pop(); - if (heap.size() > 1) - percolateDown(1); - return r; } - - bool heapProperty() { - return heapProperty(1); } - - bool heapProperty(int i) { - return (size_t)i >= heap.size() - || ((parent(i) == 0 || !comp(heap[i],heap[parent(i)])) && heapProperty(left(i)) && heapProperty(right(i))); } -}; - - -//================================================================================================= -#endif diff --git a/src/itp/Makefile b/src/itp/Makefile deleted file mode 100644 index 5c4d3b69..00000000 --- a/src/itp/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -PKGFLAG = -EXTHDRS = gvSat.h gvSatMgr.h gvSatCmd.h VarOrderV.h - -include ../Makefile.in -include ../Makefile.lib diff --git a/src/itp/SortV.h b/src/itp/SortV.h deleted file mode 100644 index e4191cc7..00000000 --- a/src/itp/SortV.h +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************************************[Sort.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Sort_h -#define Sort_h - - -//================================================================================================= - - -template -struct LessThan_default { - bool operator () (T x, T y) { return x < y; } -}; - - -//================================================================================================= - - -template -void selectionSort(T* array, int size, LessThan lt) -{ - int i, j, best_i; - T tmp; - - for (i = 0; i < size-1; i++){ - best_i = i; - for (j = i+1; j < size; j++){ - if (lt(array[j], array[best_i])) - best_i = j; - } - tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp; - } -} -template static inline void selectionSort(T* array, int size) { - selectionSort(array, size, LessThan_default()); } - - -template -void sort(T* array, int size, LessThan lt, double& seed) -{ - if (size <= 15) - selectionSort(array, size, lt); - - else{ - T pivot = array[irand(seed, size)]; - T tmp; - int i = -1; - int j = size; - - for(;;){ - do i++; while(lt(array[i], pivot)); - do j--; while(lt(pivot, array[j])); - - if (i >= j) break; - - tmp = array[i]; array[i] = array[j]; array[j] = tmp; - } - - sort(array , i , lt, seed); - sort(&array[i], size-i, lt, seed); - } -} -template void sort(T* array, int size, LessThan lt) { - double seed = 91648253; sort(array, size, lt, seed); } -template static inline void sort(T* array, int size) { - sort(array, size, LessThan_default()); } - - -template -void sortUnique(T* array, int& size, LessThan lt) -{ - int i, j; - T last; - - if (size == 0) return; - - sort(array, size, lt); - - i = 1; - last = array[0]; - for (j = 1; j < size; j++){ - if (lt(last, array[j])){ - last = array[i] = array[j]; - i++; } - } - - size = i; -} -template static inline void sortUnique(T* array, int& size) { - sortUnique(array, size, LessThan_default()); } - - -//================================================================================================= -// For 'vec's: - - -template void sort(vec& v, LessThan lt) { - sort((T*)v, v.size(), lt); } -template void sort(vec& v) { - sort(v, LessThan_default()); } - - -template void sortUnique(vec& v, LessThan lt) { - int size = v.size(); - T* data = v.release(); - sortUnique(data, size, lt); - v.~vec(); - new (&v) vec(data, size); } -template void sortUnique(vec& v) { - sortUnique(v, LessThan_default()); } - - -//================================================================================================= -#endif diff --git a/src/itp/gvSat.cpp b/src/itp/gvSat.cpp deleted file mode 100644 index 09073227..00000000 --- a/src/itp/gvSat.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/**************************************************************************** - FileName [ sat.cpp ] - PackageName [ sat ] - Synopsis [ Define miniSat solver interface functions ] - Author [ Chung-Yang (Ric) Huang, Cheng-Yin Wu ] - Copyright [ Copyleft(c) 2010-2014 LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#ifndef SAT_C -#define SAT_C - -#include "gvSat.h" -#include -#include - -GVSatSolver::GVSatSolver(GVNtkMgr* ntk) : _ntk(ntk) { - _solver = new SolverV(); - _solver->proof = new Proof(); - _assump.clear(); - _curVar = 0; - _solver->newVar(); - ++_curVar; - _ntkData = new vector[ntk->getNetSize()]; - for (uint32_t i = 0; i < ntk->getNetSize(); ++i) _ntkData[i].clear(); -} - -GVSatSolver::~GVSatSolver() { - delete _solver; - assumeRelease(); - for (uint32_t i = 0; i < _ntk->getNetSize(); ++i) _ntkData[i].clear(); - delete[] _ntkData; -} - -void -GVSatSolver::reset() { - delete _solver; - _solver = new SolverV(); - _solver->proof = new Proof(); - _assump.clear(); - _curVar = 0; - _solver->newVar(); - ++_curVar; - _ntkData = new vector[_ntk->getNetSize()]; - for (uint32_t i = 0; i < _ntk->getNetSize(); ++i) _ntkData[i].clear(); -} - -void -GVSatSolver::assumeRelease() { - _assump.clear(); -} - -void -GVSatSolver::assumeProperty(const size_t& var, const bool& invert) { - _assump.push(mkLit(getOriVar(var), invert ^ isNegFormula(var))); -} - -void -GVSatSolver::assertProperty(const size_t& var, const bool& invert) { - _solver->addUnit(mkLit(getOriVar(var), invert ^ isNegFormula(var))); -} - -void -GVSatSolver::assumeProperty(const GVNetId& id, const bool& invert, const uint32_t& depth) { - const Var var = getVerifyData(id, depth); - _assump.push(mkLit(var, invert ^ id.cp)); -} - -void -GVSatSolver::assertProperty(const GVNetId& id, const bool& invert, const uint32_t& depth) { - const Var var = getVerifyData(id, depth); - _solver->addUnit(mkLit(var, invert ^ id.cp)); -} - -const bool -GVSatSolver::simplify() { - return _solver->simplifyDB(); -} - -const bool -GVSatSolver::solve() { - _solver->solve(); - return _solver->okay(); -} - -const bool -GVSatSolver::assump_solve() { - bool result = _solver->solve(_assump); - return result; -} - -const GVBitVecX -GVSatSolver::getDataValue(const GVNetId& id, const uint32_t& depth) const { - Var var = getVerifyData(id, depth); - uint32_t i, width = 1; - GVBitVecX value(width); - if (isGVNetInverted(id)) { - for (i = 0; i < width; ++i) - if (gv_l_True == _solver->model[var + i]) value.set0(i); - else value.set1(i); - } else { - for (i = 0; i < width; ++i) - if (gv_l_True == _solver->model[var + i]) value.set1(i); - else value.set0(i); - } - return value; -} - -const bool -GVSatSolver::getDataValue(const size_t& var) const { - return (isNegFormula(var)) ^ (gv_l_True == _solver->model[getOriVar(var)]); -} - -const size_t -GVSatSolver::getFormula(const GVNetId& id, const uint32_t& depth) { - Var var = getVerifyData(id, depth); - return (id.fanin0Cp ? getNegVar(var) : getPosVar(var)); -} - -void -GVSatSolver::resizeNtkData(const uint32_t& num) { - vector* tmp = new vector[_ntk->getNetSize()]; - for (uint32_t i = 0, j = (_ntk->getNetSize() - num); i < j; ++i) tmp[i] = _ntkData[i]; - delete[] _ntkData; - _ntkData = tmp; -} - -const Var -GVSatSolver::newVar() { - Var cur_var = _curVar; - _solver->newVar(); - _curVar++; - return cur_var; -} - -const Var -GVSatSolver::getVerifyData(const GVNetId& id, const uint32_t& depth) const { - if (depth >= _ntkData[getGVNetIndex(id)].size()) return 0; - else return _ntkData[getGVNetIndex(id)][depth]; -} - -void -GVSatSolver::add_FALSE_Formula(const GVNetId& out, const uint32_t& depth) { - const uint32_t index = getGVNetIndex(out); - _ntkData[index].push_back(newVar()); - _solver->addUnit(mkLit(_ntkData[index].back(), true)); -} - -void -GVSatSolver::add_PI_Formula(const GVNetId& out, const uint32_t& depth) { - const uint32_t index = getGVNetIndex(out); - _ntkData[index].push_back(newVar()); -} - -void -GVSatSolver::add_FF_Formula(const GVNetId& out, const uint32_t& depth) { - const uint32_t index = getGVNetIndex(out); - // assert(depth == _ntkData[index].size()); - - if (depth) { - // Build FF I/O Relation - const GVNetId in1 = _ntk->getInputNetId(out, 0); - const Var var1 = getVerifyData(in1, depth - 1); - - if (out.fanin0Cp) { - // a <-> b - _ntkData[index].push_back(newVar()); - Lit a = mkLit(_ntkData[index].back()); - Lit b = mkLit(var1, true); - vec lits; - lits.clear(); - lits.push(~a); - lits.push(b); - _solver->addClause(lits); - lits.clear(); - lits.push(a); - lits.push(~b); - _solver->addClause(lits); - lits.clear(); - } else _ntkData[index].push_back(var1); - } else { // Timeframe 0 - _ntkData[index].push_back(newVar()); - } -} - -void -GVSatSolver::add_AND_Formula(const GVNetId& out, const uint32_t& depth) { - const uint32_t index = getGVNetIndex(out); - _ntkData[index].push_back(newVar()); - - const Var& var = _ntkData[index].back(); - // Build AND I/O Relation - const GVNetId in1 = _ntk->getInputNetId(out, 0); - const GVNetId in2 = _ntk->getInputNetId(out, 1); - const Var var1 = getVerifyData(in1, depth); - const Var var2 = getVerifyData(in2, depth); - - Lit y = mkLit(var); - Lit a = mkLit(var1, out.fanin0Cp); - Lit b = mkLit(var2, out.fanin1Cp); - - vec lits; - lits.clear(); - lits.push(a); - lits.push(~y); - _solver->addClause(lits); - lits.clear(); - lits.push(b); - lits.push(~y); - _solver->addClause(lits); - lits.clear(); - lits.push(~a); - lits.push(~b); - lits.push(y); - _solver->addClause(lits); - lits.clear(); -} - -void -GVSatSolver::addBoundedVerifyData(const GVNetId& id, const uint32_t& depth) { - if (existVerifyData(id, depth)) return; - addBoundedVerifyDataRecursively(id, depth); -} - -void -GVSatSolver::addBoundedVerifyDataRecursively(const GVNetId& id, const uint32_t& depth) { - const GV_Ntk_Type_t type = gvNtkMgr->getGateType(id); - if (existVerifyData(id, depth)) return; - if (GV_NTK_OBJ_PI == type) add_PI_Formula(id, depth); - else if (GV_NTK_OBJ_FF_CS == type || GV_NTK_OBJ_FF_NS == type) { - uint32_t newDepth = depth; - if (depth) { - if (GV_NTK_OBJ_FF_NS == type) newDepth -= 1; - addBoundedVerifyDataRecursively(_ntk->getInputNetId(id, 0), newDepth); - } - add_FF_Formula(id, depth); - } else if (GV_NTK_OBJ_AIG >= type) { - // if (GV_NTK_OBJ_PO == type) { - // addBoundedVerifyDataRecursively(_ntk->getInputNetId(id, 0), depth); - // add_FF_Formula(id, depth); - // } else - if (GV_NTK_OBJ_AIG == type) { - addBoundedVerifyDataRecursively(_ntk->getInputNetId(id, 0), depth); - addBoundedVerifyDataRecursively(_ntk->getInputNetId(id, 1), depth); - add_AND_Formula(id, depth); - } else { - add_FALSE_Formula(id, depth); - } - } else { - assert(0); - } -} - -const bool -GVSatSolver::existVerifyData(const GVNetId& id, const uint32_t& depth) { - return getVerifyData(id, depth); -} - -#endif diff --git a/src/itp/gvSat.h b/src/itp/gvSat.h deleted file mode 100644 index 77a73601..00000000 --- a/src/itp/gvSat.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** - FileName [ sat.h ] - PackageName [ sat ] - Synopsis [ Define miniSat solver interface functions ] - Author [ Chung-Yang (Ric) Huang, Cheng-Yin Wu ] - Copyright [ Copyleft(c) 2010-2014 LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#ifndef GV_SAT_H -#define GV_SAT_H - -#include "SolverV.h" -#include "gvBitVec.h" -#include "gvNtk.h" -#include -#include -#include -using namespace std; - -class SATMgr; - -/********** MiniSAT_Solver **********/ -class GVSatSolver -{ - friend class SATMgr; - - public: - GVSatSolver(GVNtkMgr*); - ~GVSatSolver(); - - void reset(); - void assumeRelease(); - void assumeProperty(const size_t&, const bool&); - void assertProperty(const size_t&, const bool&); - void assumeProperty(const GVNetId& id, const bool& invert, const uint32_t& depth); - void assertProperty(const GVNetId& id, const bool& invert, const uint32_t& depth); - const bool simplify(); - const bool solve(); - const bool assump_solve(); - int getNumClauses() const { return _solver->nRootCla(); } - - // Network to Solver Functions - const size_t getFormula(const GVNetId&, const uint32_t&); - const GVBitVecX getDataValue(const GVNetId&, const uint32_t&) const; - const bool getDataValue(const size_t&) const; - // Variable Interface Functions - inline const size_t reserveFormula() { return getPosVar(newVar()); } - inline const bool isNegFormula(const size_t& v) const { return (v & 1ul); } - inline const size_t getNegFormula(const size_t& v) const { return (v ^ 1ul); } - - // Gate Formula to Solver Functions - void add_FALSE_Formula(const GVNetId&, const uint32_t&); - void add_PI_Formula(const GVNetId&, const uint32_t&); - void add_FF_Formula(const GVNetId&, const uint32_t&); - void add_AND_Formula(const GVNetId&, const uint32_t&); - - void addBoundedVerifyData(const GVNetId&, const uint32_t&); - const bool existVerifyData(const GVNetId&, const uint32_t&); - void resizeNtkData(const uint32_t& num); - - private: - const Var newVar(); - const Var getVerifyData(const GVNetId&, const uint32_t&) const; - void addBoundedVerifyDataRecursively(const GVNetId&, const uint32_t&); - - inline const Var getOriVar(const size_t& v) const { return (Var)(v >> 1ul); } - inline const size_t getPosVar(const Var& v) const { return (((size_t)v) << 1ul); } - inline const size_t getNegVar(const Var& v) const { return ((getPosVar(v)) | 1ul); } - - SolverV* _solver; // Pointer to a Minisat solver - Var _curVar; // Variable currently - vec _assump; // Assumption List for assumption solve - GVNtkMgr* _ntk; // Network Under Verification - vector* _ntkData; // Mapping between GVNetId and Solver Data -}; - -#endif // SAT_H diff --git a/src/itp/gvSatCmd.cpp b/src/itp/gvSatCmd.cpp deleted file mode 100644 index c5139ec3..00000000 --- a/src/itp/gvSatCmd.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** - FileName [ satCmd.cpp ] - PackageName [ sat ] - Synopsis [ Define basic sat prove package commands ] - Author [ ] - Copyright [ Copyleft(c) 2010 LaDs(III), GIEE, NTU, Taiwan ] - ****************************************************************************/ - -#include "gvSatCmd.h" -#include "gvMsg.h" -#include "gvSatMgr.h" -#include "util.h" -#include -#include -using namespace std; - -static SATMgr* satMgr = new SATMgr(); - -bool -GVinitItpCmd() { - return (gvCmdMgr->regCmd("SATVerify ITP", 4, 3, new SATVerifyItpCmd) && - gvCmdMgr->regCmd("SATVerify BMC", 4, 3, new SATVerifyBmcCmd)); -} - -//---------------------------------------------------------------------- -// SATVerify ITP < -Netid | -Output > > -//---------------------------------------------------------------------- -GVCmdExecStatus -SATVerifyItpCmd::exec(const string& option) { - vector options; - GVCmdExec::lexOptions(option, options); - - if (options.size() < 2) return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, ""); - if (options.size() > 2) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[2]); - - bool isNet = false; - - if (myStrNCmp("-Netid", options[0], 2) == 0) isNet = true; - else if (myStrNCmp("-Output", options[0], 2) == 0) isNet = false; - else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); - - int num = 0; - GVNetId netId; - if (!myStr2Int(options[1], num) || (num < 0)) return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); - if (isNet) { - if ((unsigned)num >= gvNtkMgr->getNetSize()) { - gvMsg(GV_MSG_ERR) << "Net with Id " << num << " does NOT Exist in Current Ntk !!" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); - } - netId = GVNetId::makeNetId(num); - } else { - if ((unsigned)num >= gvNtkMgr->getOutputSize()) { - gvMsg(GV_MSG_ERR) << "Output with Index " << num << " does NOT Exist in Current Ntk !!" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); - } - netId = gvNtkMgr->getOutput(num); - } - // get PO's input, since the PO is actually a redundant node and should be removed - GVNetId redundantNode = gvNtkMgr->getGVNetId(netId.id); - GVNetId monitor = gvNtkMgr->getInputNetId(redundantNode, 0); - satMgr->verifyPropertyItp(gvNtkMgr->getNetNameFromId(redundantNode.id), monitor); - - return GV_CMD_EXEC_DONE; -} - -void -SATVerifyItpCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: SATVerify ITP < -Netid | -Output >" << endl; -} - -void -SATVerifyItpCmd::help() const { - cout << setw(20) << left << "SATVerify ITP:" - << "check the monitor by interpolation-based technique" << endl; -} - -// //---------------------------------------------------------------------- -// // SATVerify BMC < -Netid | -Output > > -// //---------------------------------------------------------------------- -GVCmdExecStatus -SATVerifyBmcCmd::exec(const string& option) { - vector options; - GVCmdExec::lexOptions(option, options); - - if (options.size() < 2) return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, ""); - if (options.size() > 2) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[2]); - - bool isNet = false; - - if (myStrNCmp("-Netid", options[0], 2) == 0) isNet = true; - else if (myStrNCmp("-Output", options[0], 2) == 0) isNet = false; - else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); - - int num = 0; - GVNetId netId; - if (!myStr2Int(options[1], num) || (num < 0)) return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); - if (isNet) { - if ((unsigned)num >= gvNtkMgr->getNetSize()) { - gvMsg(GV_MSG_ERR) << "Net with Id " << num << " does NOT Exist in Current Ntk !!" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); - } - netId = GVNetId::makeNetId(num); - } else { - if ((unsigned)num >= gvNtkMgr->getOutputSize()) { - gvMsg(GV_MSG_ERR) << "Output with Index " << num << " does NOT Exist in Current Ntk !!" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); - } - netId = gvNtkMgr->getOutput(num); - } - // get PO's input, since the PO is actually a redundant node and should be removed - GVNetId redundantNode = gvNtkMgr->getGVNetId(netId.id); - GVNetId monitor = gvNtkMgr->getInputNetId(redundantNode, 0); - satMgr->verifyPropertyBmc(gvNtkMgr->getNetNameFromId(redundantNode.id), monitor); - - return GV_CMD_EXEC_DONE; -} - -void -SATVerifyBmcCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: SATVerify BMC < -Netid | -Output < outputIndex >> " << endl; -} - -void -SATVerifyBmcCmd::help() const { - cout << setw(20) << left << "SATVerify BMC:" - << "check the monitor by bounded model checking" << endl; -} diff --git a/src/itp/gvSatCmd.h b/src/itp/gvSatCmd.h deleted file mode 100644 index 9ca3975e..00000000 --- a/src/itp/gvSatCmd.h +++ /dev/null @@ -1,20 +0,0 @@ -/**************************************************************************** - FileName [ satCmd.h ] - PackageName [ sat ] - Synopsis [ Define basic sat prove package commands ] - Author [ ] - Copyright [ Copyleft(c) 2010 LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#ifndef GV_SAT_CMD_H_ -#define GV_SAT_CMD_H_ - -#include "gvCmdMgr.h" - -// ============================================================================ -// Classes for Prove package commands -// ============================================================================ -GV_COMMAND(SATVerifyItpCmd, GV_CMD_TYPE_ITP); -GV_COMMAND(SATVerifyBmcCmd, GV_CMD_TYPE_ITP); - -#endif diff --git a/src/itp/gvSatMgr.cpp b/src/itp/gvSatMgr.cpp deleted file mode 100644 index 86a00a1f..00000000 --- a/src/itp/gvSatMgr.cpp +++ /dev/null @@ -1,677 +0,0 @@ -/**************************************************************************** - FileName [ satMgr.cpp ] - PackageName [ sat ] - Synopsis [ Define sat prove package interface ] - Author [ ] - Copyright [ Copyleft(c) 2010 LaDs(III), GIEE, NTU, Taiwan ] - ****************************************************************************/ - -#include "gvSatMgr.h" -#include "gvMsg.h" -#include "reader.h" -#include -#include -#include -#include - -using namespace std; - -void -SATMgr::verifyPropertyItp(const string& name, const GVNetId& monitor) { - // Initialize - // duplicate the network, so you can modified - // the ntk for the proving property without - // destroying the original network - SatProofRes pRes; - GVSatSolver* gvSatSolver = new GVSatSolver(gvNtkMgr); - - // Prove the monitor here!! - pRes.setMaxDepth(1000); - pRes.setSatSolver(gvSatSolver); - itpUbmc(monitor, pRes); - - pRes.reportResult(name); - if (pRes.isFired()) pRes.reportCex(monitor, gvNtkMgr); - - // delete gvSatSolver; - // delete _ntk; - reset(); -} - -void -SATMgr::verifyPropertyBmc(const string& name, const GVNetId& monitor) { - // Initialize - // duplicate the network, so you can modified - // the ntk for the proving property without - // destroying the original network - SatProofRes pRes; - GVSatSolver* gvSatSolver = new GVSatSolver(gvNtkMgr); - - // Prove the monitor here!! - pRes.setMaxDepth(1000); - pRes.setSatSolver(gvSatSolver); - indBmc(monitor, pRes); - - pRes.reportResult(name); - if (pRes.isFired()) pRes.reportCex(monitor, gvNtkMgr); - - // delete gvSatSolver; - // delete _ntk; - reset(); -} - -void -SATMgr::indBmc(const GVNetId& monitor, SatProofRes& pRes) { - GVSatSolver* gvSatSolver = pRes.getSatSolver(); - bind(gvSatSolver); - - uint32_t i = 0; - GVNetId I = buildInitState(); - - gvSatSolver->addBoundedVerifyData(I, i); - gvSatSolver->assertProperty(I, false, i); - // Start Bounded Model Checking - for (uint32_t j = pRes.getMaxDepth(); i < j; ++i) { - // Add time frame expanded circuit to SAT Solver - gvSatSolver->addBoundedVerifyData(monitor, i); - gvSatSolver->assumeRelease(); - gvSatSolver->assumeProperty(monitor, false, i); - gvSatSolver->simplify(); - // Assumption Solver: If SAT, diproved! - if (gvSatSolver->assump_solve()) { - pRes.setFired(i); - break; - } - gvSatSolver->assertProperty(monitor, true, i); - } -} - -void -SATMgr::itpUbmc(const GVNetId& monitor, SatProofRes& pRes) { - GVSatSolver* gvSatSolver = pRes.getSatSolver(); - bind(gvSatSolver); - - size_t num_clauses = getNumClauses(); - bool proved = false; - gvSatSolver->assumeRelease(); - GVNetId S, R, R_prime, tmp1, tmp2, tmp3, tmp4; - - // TODO : finish your own Interpolation-based property checking - - // PART I: - // Build Initial State - GVNetId I = buildInitState(); - // PART II: - // Take care the first timeframe (i.e. Timeframe 0 ) - // Check if monitor is violated at timeframe 0 - // Build the whole timeframe 0 and map the var to latch net - // Mark the added clauses ( up to now ) to onset - uint32_t i = 0, k = 0; - gvSatSolver->addBoundedVerifyData(I, i); - gvSatSolver->assumeProperty(I, false, i); - gvSatSolver->addBoundedVerifyData(monitor, i); - gvSatSolver->assumeProperty(monitor, false, i); - gvSatSolver->simplify(); - if (gvSatSolver->assump_solve()) { - pRes.setFired(i); - return; - } - - num_clauses = getNumClauses(); - gvSatSolver->assertProperty(monitor, true, i); - for (size_t j = 0; j < gvNtkMgr->getFFSize(); ++j) { - gvSatSolver->addBoundedVerifyData(gvNtkMgr->getFF(j), i); - mapVar2Net(gvSatSolver->getVerifyData(gvNtkMgr->getFF(j), i), gvNtkMgr->getFF(j)); - } - i++; // i = 1 - // map gvSatSolver vars to latch nets - for (size_t j = 0; j < gvNtkMgr->getFFSize(); ++j) { - gvSatSolver->addBoundedVerifyData(gvNtkMgr->getFF(j), i); - mapVar2Net(gvSatSolver->getVerifyData(gvNtkMgr->getFF(j), i), gvNtkMgr->getFF(j)); - } - num_clauses = getNumClauses(); - - // mark the onset clauses - for (size_t j = 0; j < getNumClauses(); ++j) { - markOnsetClause(j); - } - num_clauses = getNumClauses(); - - for (size_t j = 0; j < gvNtkMgr->getFFSize(); ++j) { - gvSatSolver->addBoundedVerifyData(gvNtkMgr->getFF(j), i); - mapVar2Net(gvSatSolver->getVerifyData(gvNtkMgr->getFF(j), i), gvNtkMgr->getFF(j)); - } - num_clauses = getNumClauses(); - - // PART III: - // Start the ITP verification loop - // Perform BMC - // SAT -> cex found - // UNSAT-> start inner loop to compute the approx. images - // Each time the clauses are added to the solver, - // mark them to onset/offset carefully - // ( ex. addedBoundedVerifyData(), assertProperty() are called ) - for (; i < pRes.getMaxDepth(); ++i) { - // perfrom BMC - gvSatSolver->addBoundedVerifyData(monitor, i); - gvSatSolver->assumeRelease(); - // gvSatSolver->assumeProperty(monitor, false, i); - gvSatSolver->assumeProperty(monitor, false, i); - gvSatSolver->assumeProperty(I, false, 0); - gvSatSolver->simplify(); - - if (gvSatSolver->assump_solve()) { - pRes.setFired(i); - break; - } - - // mark the offset - for (size_t j = num_clauses; j < getNumClauses(); ++j) { - markOffsetClause(j); - } - num_clauses = getNumClauses(); - - k = 0; - R = I; - S = getItp(); - for (; k < pRes.getMaxDepth(); ++k) { - gvSatSolver->assumeRelease(); - gvSatSolver->addBoundedVerifyData(S, 0); - gvSatSolver->assumeProperty(S, false, 0); - for (size_t j = num_clauses; j < getNumClauses(); ++j) { - markOnsetClause(j); - } - num_clauses = getNumClauses(); - - gvSatSolver->assumeProperty(monitor, false, i); - gvSatSolver->simplify(); - - // Assumption Solver: If SAT, disproved! - if (gvSatSolver->assump_solve()) { - - gvSatSolver->assertProperty(monitor, true, i); - for (size_t j = num_clauses; j < getNumClauses(); ++j) { - markOffsetClause(j); - } - num_clauses = getNumClauses(); - break; - } else num_clauses = getNumClauses(); - S = getItp(); - // see if Si or Ri-1 equals to Ri - tmp2 = ~gvNtkMgr->createNet(); - tmp3 = ~gvNtkMgr->createNet(); - tmp4 = ~gvNtkMgr->createNet(); - R_prime = ~gvNtkMgr->createNet(); - gvSatSolver->resizeNtkData(4); - - gvNtkMgr->createGVAndGate(R_prime, ~R, ~S); // or(R, S) - gvNtkMgr->createGVAndGate(tmp2, ~R, R_prime); - gvNtkMgr->createGVAndGate(tmp3, R, ~R_prime); - gvNtkMgr->createGVAndGate(tmp4, tmp2, tmp3); // tmp4 = R xor R_prime - - gvSatSolver->addBoundedVerifyData(tmp4, 0); - gvSatSolver->assumeRelease(); - gvSatSolver->assumeProperty(tmp4, false, 0); // assume R xor R_prime is true - gvSatSolver->simplify(); - if (!gvSatSolver->assump_solve()) // USAT - { - pRes.setProved(k); - proved = true; - break; - } else { - for (size_t j = num_clauses; j < getNumClauses(); ++j) { - markOnsetClause(j); - } - num_clauses = getNumClauses(); - R = R_prime; - } - } - if (proved) break; - } - return; -} - -void -SATMgr::bind(GVSatSolver* ptrMinisat) { - _ptrMinisat = ptrMinisat; - if (_ptrMinisat->_solver->proof == NULL) { - gvMsg(GV_MSG_ERR) << "The Solver has no Proof!! Try Declaring the Solver with proofLog be set!!" << endl; - exit(0); - } -} - -void -SATMgr::reset() { - _ptrMinisat = NULL; - _varGroup.clear(); - _var2Net.clear(); - _isClauseOn.clear(); - _isClaOnDup.clear(); -} - -void -SATMgr::markOnsetClause(const ClauseId& cid) { - unsigned cSize = getNumClauses(); - assert(cid < (int)cSize); - if (_isClauseOn.size() < cSize) { - _isClauseOn.resize(cSize, false); - } - _isClauseOn[cid] = true; -} - -void -SATMgr::markOffsetClause(const ClauseId& cid) { - unsigned cSize = getNumClauses(); - assert(cid < (int)cSize); - if (_isClauseOn.size() < cSize) { - _isClauseOn.resize(cSize, false); - } - _isClauseOn[cid] = false; -} - -void -SATMgr::mapVar2Net(const Var& var, const GVNetId& net) { - _var2Net[var] = net; -} - -GVNetId -SATMgr::getItp() const { - assert(_ptrMinisat); - assert(_ptrMinisat->_solver->proof); - - string proofName = "socv_proof.itp"; - // remove proof log if exist - ifstream logFile(proofName.c_str()); - if (logFile.good()) { - string rmCmd = "rm " + proofName + " -f"; - system(rmCmd.c_str()); - } - - // save proof log - _ptrMinisat->_solver->proof->save(proofName.c_str()); - - // bulding ITP - GVNetId netId = buildItp(proofName); - - // delete proof log - unlink(proofName.c_str()); - - return netId; -} - -vector -SATMgr::getUNSATCore() const { - assert(_ptrMinisat); - assert(_ptrMinisat->_solver->proof); - - vector unsatCore; - unsatCore.clear(); - - // save proof log - string proofName = "socv_proof.itp"; - _ptrMinisat->_solver->proof->save(proofName.c_str()); - - // generate unsat core - Reader rdr; - rdr.open(proofName.c_str()); - retrieveProof(rdr, unsatCore); - - // delete proof log - unlink(proofName.c_str()); - - return unsatCore; -} - -void -SATMgr::retrieveProof(Reader& rdr, vector& unsatCore) const { - unsigned int tmp, cid, idx, tmp_cid; - - // Clear all - vector clausePos; - clausePos.clear(); - unsatCore.clear(); - - // Generate clausePos - assert(!rdr.null()); - rdr.seek(0); - for (unsigned int pos = 0; (tmp = rdr.get64()) != RDR_EOF; pos = rdr.Current_Pos()) { - cid = clausePos.size(); - clausePos.push_back(pos); - if ((tmp & 1) == 0) { // root clause - while ((tmp = rdr.get64()) != 0) { - } - } else { // learnt clause - idx = 0; - while ((tmp = rdr.get64()) != 0) { - idx = 1; - } - if (idx == 0) clausePos.pop_back(); // Clause Deleted - } - } - - // Generate unsatCore - priority_queue clause_queue; - vector in_queue; - in_queue.resize(clausePos.size()); - for (unsigned int i = 0; i < in_queue.size(); ++i) in_queue[i] = false; - in_queue[in_queue.size() - 1] = true; - clause_queue.push(clausePos.size() - 1); // Push leaf (empty) clause - while (clause_queue.size() != 0) { - cid = clause_queue.top(); - clause_queue.pop(); - - rdr.seek(clausePos[cid]); - - tmp = rdr.get64(); - if ((tmp & 1) == 0) { - // root clause - vec lits; - idx = tmp >> 1; - lits.push(gvToLit(idx)); - while (_varGroup[idx >> 1] != COMMON) { - tmp = rdr.get64(); - if (tmp == 0) break; - idx += tmp; - lits.push(gvToLit(idx)); - } - unsatCore.push_back(Clause(false, lits)); - } else { - // derived clause - tmp_cid = cid - (tmp >> 1); - if (!in_queue[tmp_cid]) { - in_queue[tmp_cid] = true; - clause_queue.push(tmp_cid); - } - while (1) { - tmp = rdr.get64(); - if (tmp == 0) break; - tmp_cid = cid - rdr.get64(); - if (!in_queue[tmp_cid]) { - in_queue[tmp_cid] = true; - clause_queue.push(tmp_cid); - } - } - } - } -} - -void -SATMgr::retrieveProof(Reader& rdr, vector& clausePos, vector& usedClause) const { - unsigned int tmp, cid, idx, tmp_cid, root_cid; - - // Clear all - clausePos.clear(); - usedClause.clear(); - _varGroup.clear(); - _varGroup.resize(_ptrMinisat->_solver->nVars(), NONE); - _isClaOnDup.clear(); - assert((int)_isClauseOn.size() == getNumClauses()); - - // Generate clausePos && varGroup - assert(!rdr.null()); - rdr.seek(0); - root_cid = 0; - for (unsigned int pos = 0; (tmp = rdr.get64()) != RDR_EOF; pos = rdr.Current_Pos()) { - cid = clausePos.size(); - clausePos.push_back(pos); - if ((tmp & 1) == 0) { - // Root Clause - _isClaOnDup.push_back(_isClauseOn[root_cid]); - idx = tmp >> 1; - if (_isClauseOn[root_cid]) { - if (_varGroup[idx >> 1] == NONE) _varGroup[idx >> 1] = LOCAL_ON; - else if (_varGroup[idx >> 1] == LOCAL_OFF) _varGroup[idx >> 1] = COMMON; - } else { - if (_varGroup[idx >> 1] == NONE) _varGroup[idx >> 1] = LOCAL_OFF; - else if (_varGroup[idx >> 1] == LOCAL_ON) _varGroup[idx >> 1] = COMMON; - } - while (1) { - tmp = rdr.get64(); - if (tmp == 0) break; - idx += tmp; - if (_isClauseOn[root_cid]) { - if (_varGroup[idx >> 1] == NONE) _varGroup[idx >> 1] = LOCAL_ON; - else if (_varGroup[idx >> 1] == LOCAL_OFF) _varGroup[idx >> 1] = COMMON; - } else { - if (_varGroup[idx >> 1] == NONE) _varGroup[idx >> 1] = LOCAL_OFF; - else if (_varGroup[idx >> 1] == LOCAL_ON) _varGroup[idx >> 1] = COMMON; - } - } - ++root_cid; - } else { - _isClaOnDup.push_back(false); - idx = 0; - while (1) { - tmp = rdr.get64(); - if (tmp == 0) break; - idx = 1; - tmp = rdr.get64(); - } - if (idx == 0) { - clausePos.pop_back(); // Clause Deleted - _isClaOnDup.pop_back(); // Clause Deleted - } - } - } - - // Generate usedClause - priority_queue clause_queue; - vector in_queue; - in_queue.resize(clausePos.size()); - for (unsigned int i = 0; i < in_queue.size(); ++i) in_queue[i] = false; - in_queue[in_queue.size() - 1] = true; - clause_queue.push(clausePos.size() - 1); // Push root empty clause - while (clause_queue.size() != 0) { - cid = clause_queue.top(); - clause_queue.pop(); - - rdr.seek(clausePos[cid]); - - tmp = rdr.get64(); - if ((tmp & 1) == 0) continue; // root clause - - // else, derived clause - tmp_cid = cid - (tmp >> 1); - if (!in_queue[tmp_cid]) { - in_queue[tmp_cid] = true; - clause_queue.push(tmp_cid); - } - while (1) { - tmp = rdr.get64(); - if (tmp == 0) break; - tmp_cid = cid - rdr.get64(); - if (!in_queue[tmp_cid]) { - in_queue[tmp_cid] = true; - clause_queue.push(tmp_cid); - } - } - } - for (unsigned int i = 0; i < in_queue.size(); ++i) { - if (in_queue[i]) { - usedClause.push_back(i); - } - } -} - -GVNetId -SATMgr::buildInitState() const { - // TODO: build initial state - GVNetId I, in1, in2; - // and const 1 with the first latch - in2 = ~(gvNtkMgr->getConst(0)); - // iteratively and adn all the PI's negation with otthers - for (size_t i = 0; i < gvNtkMgr->getFFSize(); ++i) { - I = gvNtkMgr->createNet(); - in1 = ~gvNtkMgr->getFF(i); - gvNtkMgr->createGVAndGate(I, in1, in2); - in2 = I; - } - // resize solver data to ntk size - _ptrMinisat->resizeNtkData(gvNtkMgr->getFFSize()); - return I; -} - -// build the McMillan Interpolant -GVNetId -SATMgr::buildItp(const string& proofName) const { - Reader rdr; - // records - map claItpLookup; - vector clausePos; - vector usedClause; - // ntk - uint32_t netSize = gvNtkMgr->getNetSize(); - // temperate variables - GVNetId nId, nId1, nId2; - int i, cid, tmp, idx, tmp_cid; - // const 1 & const 0 - GVNetId CONST0, CONST1; - CONST0 = gvNtkMgr->getConst(0); - CONST1 = ~CONST0; - - rdr.open(proofName.c_str()); - retrieveProof(rdr, clausePos, usedClause); - - for (i = 0; i < (int)usedClause.size(); i++) { - cid = usedClause[i]; - rdr.seek(clausePos[cid]); - tmp = rdr.get64(); - if ((tmp & 1) == 0) { - // Root Clause - if (_isClaOnDup[cid]) { - idx = tmp >> 1; - while (_varGroup[idx >> 1] != COMMON) { - tmp = rdr.get64(); - if (tmp == 0) break; - idx += tmp; - } - if (_varGroup[idx >> 1] == COMMON) { - assert(_var2Net.find(idx >> 1) != _var2Net.end()); - nId = (_var2Net.find(idx >> 1))->second; - nId1 = (_var2Net.find(idx >> 1))->second; - if ((idx & 1) == 1) nId1 = ~nId1; - if ((idx & 1) == 1) nId = ~nId; - while (1) { - tmp = rdr.get64(); - if (tmp == 0) break; - idx += tmp; - if (_varGroup[idx >> 1] == COMMON) { - assert(_var2Net.find(idx >> 1) != _var2Net.end()); - nId2 = (_var2Net.find(idx >> 1))->second; - if ((idx & 1) == 1) nId2 = ~nId2; - // or - nId = ~gvNtkMgr->createNet(); - gvNtkMgr->createGVAndGate(nId, ~nId1, ~nId2); - nId1 = nId; - } - } - } else { - nId = CONST0; - } - claItpLookup[cid] = nId; - } else { - claItpLookup[cid] = CONST1; - } - } else { - // Derived Clause - tmp_cid = cid - (tmp >> 1); - assert(claItpLookup.find(tmp_cid) != claItpLookup.end()); - nId = (claItpLookup.find(tmp_cid))->second; - nId1 = (claItpLookup.find(tmp_cid))->second; - while (1) { - idx = rdr.get64(); - if (idx == 0) break; - idx--; - // Var is idx - tmp_cid = cid - rdr.get64(); - assert(claItpLookup.find(tmp_cid) != claItpLookup.end()); - nId2 = (claItpLookup.find(tmp_cid))->second; - if (nId1 != nId2) { - if (_varGroup[idx] == LOCAL_ON) { // Local to A. Build OR Gate. - if (nId1 == CONST1 || nId2 == CONST1) { - nId = CONST1; - nId1 = nId; - } else if (nId1 == CONST0) { - nId = nId2; - nId1 = nId; - } else if (nId2 == CONST0) { - nId = nId1; - nId1 = nId; - } else { - // or - nId = ~gvNtkMgr->createNet(); - gvNtkMgr->createGVAndGate(nId, ~nId1, ~nId2); - nId1 = nId; - } - } else { // Build AND Gate. - if (nId1 == CONST0 || nId2 == CONST0) { - nId = CONST0; - nId1 = nId; - } else if (nId1 == CONST1) { - nId = nId2; - nId1 = nId; - } else if (nId2 == CONST1) { - nId = nId1; - nId1 = nId; - } else { - // and - nId = gvNtkMgr->createNet(); - gvNtkMgr->createGVAndGate(nId, nId1, nId2); - nId1 = nId; - } - } - } - } - claItpLookup[cid] = nId; - } - } - - cid = usedClause[usedClause.size() - 1]; - nId = claItpLookup[cid]; - - _ptrMinisat->resizeNtkData(gvNtkMgr->getNetSize() - netSize); // resize Solver data to ntk size - - return nId; -} - -void -SatProofRes::reportResult(const string& name) const { - // Report Verification Result - gvMsg(GV_MSG_IFO) << endl; - if (isProved()) { - gvMsg(GV_MSG_IFO) << "Monitor \"" << name << "\" is safe." << endl; - } else if (isFired()) { - gvMsg(GV_MSG_IFO) << "Monitor \"" << name << "\" is violated." << endl; - } else { - gvMsg(GV_MSG_IFO) << "UNDECIDED at depth = " << _maxDepth << endl; - } -} - -void -SatProofRes::reportCex(const GVNetId& monitor, const GVNtkMgr* const ntk) const { - assert(_satSolver != 0); - - // Output Pattern Value (PI + PIO) - GVBitVecX dataValue; - for (uint32_t i = 0; i <= _fired; ++i) { - gvMsg(GV_MSG_IFO) << i << ": "; - for (int j = ntk->getInoutSize() - 1; j >= 0; --j) { - if (_satSolver->existVerifyData(ntk->getInout(j), i)) { - dataValue = _satSolver->getDataValue(ntk->getInout(j), i); - gvMsg(GV_MSG_IFO) << dataValue[0]; - } else { - gvMsg(GV_MSG_IFO) << 'x'; - } - } - for (int j = ntk->getInputSize() - 1; j >= 0; --j) { - if (_satSolver->existVerifyData(ntk->getInput(j), i)) { - dataValue = _satSolver->getDataValue(ntk->getInput(j), i); - gvMsg(GV_MSG_IFO) << dataValue[0]; - } else { - gvMsg(GV_MSG_IFO) << 'x'; - } - } - gvMsg(GV_MSG_IFO) << endl; - assert(_satSolver->existVerifyData(monitor, i)); - } -} diff --git a/src/itp/gvSatMgr.h b/src/itp/gvSatMgr.h deleted file mode 100644 index e54bf0ed..00000000 --- a/src/itp/gvSatMgr.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** - FileName [ SATMgr.h ] - PackageName [ sat ] - Synopsis [ Define sat prove package interface ] - Author [ ] - Copyright [ Copyleft(c) 2010 LaDs(III), GIEE, NTU, Taiwan ] - ****************************************************************************/ - -#ifndef SAT_MGR_H_ -#define SAT_MGR_H_ - -#include "gvNtk.h" -#include "gvSat.h" -#include -#include -#include -#include -// #include "SolverTypesV.h" -#include "reader.h" - -class GVNetId; -typedef int ClauseId; - -enum VAR_GROUP -{ - LOCAL_ON, - LOCAL_OFF, - COMMON, - NONE -}; - -class SatProofRes -{ - public: - SatProofRes(GVSatSolver* s = 0) : _proved(GVNtkUD), _fired(GVNtkUD), _maxDepth(GVNtkUD), _satSolver(s) {} - - void setProved(uint32_t i) { _proved = i; } - void setFired(uint32_t i) { _fired = i; } - - bool isProved() const { return (_proved != GVNtkUD); } - bool isFired() const { return (_fired != GVNtkUD); } - - void setMaxDepth(uint32_t d) { _maxDepth = d; } - uint32_t getMaxDepth() const { return _maxDepth; } - - void setSatSolver(GVSatSolver* s) { _satSolver = s; } - GVSatSolver* getSatSolver() const { return _satSolver; } - - void reportResult(const string&) const; - void reportCex(const GVNetId&, const GVNtkMgr* const) const; - - private: - uint32_t _proved; - uint32_t _fired; - uint32_t _maxDepth; // maximum proof depth - GVSatSolver* _satSolver; -}; - -class SATMgr -{ - public: - SATMgr() : _ptrMinisat(NULL), _ntk(NULL) { reset(); } - ~SATMgr() { reset(); } - - // entry point for SoCV SAT property checking - void verifyPropertyItp(const string& name, const GVNetId& monitor); - void verifyPropertyBmc(const string& name, const GVNetId& monitor); - // Various proof engines - void indBmc(const GVNetId&, SatProofRes&); - void itpUbmc(const GVNetId&, SatProofRes&); - - // bind with a solver to get proof info. - void bind(GVSatSolver* ptrMinisat); - // clear data members - void reset(); - // mark onset/offset clause - void markOnsetClause(const ClauseId& cid); - void markOffsetClause(const ClauseId& cid); - // map var to V3Net (PPI) - void mapVar2Net(const Var& var, const GVNetId& net); - // please be sure that you call these function right after a UNSAT solving - GVNetId getItp() const; - vector getUNSATCore() const; - // get number of clauses (the latest clause id + 1) - int getNumClauses() const { return _ptrMinisat->getNumClauses(); } - - // self define helper function - void markSet(bool onORoff, ClauseId& currClause); - bool startSatSolver(GVSatSolver* GVSatSolver); - void buildMiter(GVSatSolver* GVSatSolver, GVNetId& R_, GVNetId& R, int& orgNtkSize); - - private: - // helper functions to get proof info. - GVNetId buildInitState() const; - GVNetId buildItp(const string& proofName) const; - void retrieveProof(Reader& rdr, vector& clausePos, vector& usedClause) const; - void retrieveProof(Reader& rdr, vector& unsatCore) const; - - // V3 minisat interface for model checking - GVSatSolver* _ptrMinisat; - // The duplicated V3Ntk - GVNtkMgr* _ntk; - - // to handle interpolation - map _var2Net; // mapping common variables to net - vector _isClauseOn; // record onset clauses - // will be determined in retrieveProof, you don't need to take care about this! - mutable vector _isClaOnDup; // duplication & extension of _isClauseOn - mutable vector _varGroup; // mapping var to different groups -}; - -#endif /* SAT_MGR_H_ */ diff --git a/src/itp/reader.cpp b/src/itp/reader.cpp deleted file mode 100644 index a965fdbc..00000000 --- a/src/itp/reader.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** - FileName [ reader.cpp ] - PackageName [ sat ] - Synopsis [ Proof reader for Minisat1.14_p ] - Author [ Jiunru Yang ] - Copyright [ Copyleft(c) 2013 LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#include "reader.h" -#include - -void Reader::open( const char* file_name ){ - fd = ::open( file_name, O_RDONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH ); - buf = new unsigned char [BUF_SIZE]; - pos = 0; - overall_pos = 0; - size = read( fd, buf, BUF_SIZE ); -} - -void Reader::open(int filedesc) -{ - fd = filedesc; - buf = new unsigned char [BUF_SIZE]; - pos = 0; - overall_pos = 0; - size = read(fd, buf, BUF_SIZE); -} - -void Reader::seek( const unsigned int to ){ - lseek( fd, to, SEEK_SET ); - size = read( fd, buf, BUF_SIZE ); - pos = 0; - overall_pos = to; -} - -unsigned int Reader::getChar(){ - if( pos < size ){ - overall_pos++; - return static_cast(buf[pos++]); - } - if( size < BUF_SIZE ) return RDR_EOF; - pos = 1; - overall_pos++; - size = read( fd, buf, BUF_SIZE ); - if( size == 0 ) return RDR_EOF; - return static_cast(buf[0]); -} - -unsigned long long Reader::get64(){ - unsigned int byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7; - byte0 = getChar(); - if(byte0 == RDR_EOF) return RDR_EOF; - if (!(byte0 & 0x80)) - return byte0; - else{ - switch ((byte0 & 0x60) >> 5){ - case 0: - byte1 = getChar(); - return ((byte0 & 0x1F) << 8) | byte1; - case 1: - byte1 = getChar(); - byte2 = getChar(); - return ((byte0 & 0x1F) << 16) | (byte1 << 8) | byte2; - case 2: - byte1 = getChar(); - byte2 = getChar(); - byte3 = getChar(); - return ((byte0 & 0x1F) << 24) | (byte1 << 16) | (byte2 << 8) | byte3; - default: - byte0 = getChar(); - byte1 = getChar(); - byte2 = getChar(); - byte3 = getChar(); - byte4 = getChar(); - byte5 = getChar(); - byte6 = getChar(); - byte7 = getChar(); - return ((unsigned long long)((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3) << 32) - | (unsigned long long)((byte4 << 24) | (byte5 << 16) | (byte6 << 8) | byte7); - } - } -} - -void Reader::close(){ - if( fd == -1 ) return; - ::close(fd); - fd = -1; - delete [] buf; -} - -Reader::~Reader(){ - close(); -} - -bool Reader::eof() { - if(pos < size) return false; - if(size < BUF_SIZE) return true; - pos = 0; - size = read(fd, buf, BUF_SIZE); - return size == 0; -} diff --git a/src/itp/reader.h b/src/itp/reader.h deleted file mode 100644 index cb2f4792..00000000 --- a/src/itp/reader.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** - FileName [ reader.h ] - PackageName [ sat ] - Synopsis [ Proof reader for Minisat1.14_p ] - Author [ Jiunru Yang ] - Copyright [ Copyleft(c) 2013 LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#ifndef _READER_H_ -#define _READER_H_ - -#include -#include -#include -#include - -#define BUF_SIZE 1024 -#define RDR_EOF ((unsigned)~0) - -class Reader{ - int fd; - unsigned char* buf; - unsigned int size; - unsigned int pos; - unsigned int getChar(); - unsigned int overall_pos; -public: - Reader():fd(-1) {}; - void open ( const char* file_name ); - void open ( int file_descriptor ); - void close (); - void seek ( const unsigned int to ); - unsigned long long get64 (); - ~Reader (); - bool null() { return fd == -1; } - unsigned int Current_Pos() { return overall_pos; } - //unsigned int Current_Pos() { return lseek(fd, 0, SEEK_CUR) - (size - pos); } - bool eof(); -}; - -#endif // _READER_H_ diff --git a/src/main/.depend.mak b/src/main/.depend.mak deleted file mode 100644 index b96a8e22..00000000 --- a/src/main/.depend.mak +++ /dev/null @@ -1,8 +0,0 @@ -main.o: main.cpp ../../include/gvCmdMgr.h ../../include/gvMsg.h \ - ../../include/gvUsage.h ../../include/gvMsg.h ../../include/gvIntType.h \ - ../../include/kernel/yosys.h /usr/include/tcl8.6/tcl.h \ - /usr/include/tcl8.6/tclDecls.h /usr/include/tcl8.6/tclPlatDecls.h \ - ../../include/kernel/hashlib.h ../../include/kernel/log.h \ - ../../include/kernel/rtlil.h ../../include/kernel/constids.inc \ - ../../include/kernel/register.h ../../include/util.h \ - ../../include/rnGen.h ../../include/myUsage.h diff --git a/src/main/.extheader.mak b/src/main/.extheader.mak deleted file mode 100644 index 77e70864..00000000 --- a/src/main/.extheader.mak +++ /dev/null @@ -1 +0,0 @@ -.d: diff --git a/src/main/Makefile b/src/main/Makefile deleted file mode 100644 index daee9310..00000000 --- a/src/main/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -PKGFLAG = $(DEBUG_FLAG) -EXTHDRS = - -include ../Makefile.in - -TARGET = ../../$(EXEC) -TOPPATH = $(abspath $(firstword $(MAKEFILE_LIST))) -LIBABSPATH = $(patsubst %src/main/Makefile, %lib/,$(TOPPATH)) -GVABSPATH = $(patsubst %src/main/Makefile, %,$(TOPPATH)) -LIBABSPATH = $(patsubst %src/main/Makefile, %lib/,$(TOPPATH)) -MACLIB = /opt/homebrew/lib -OS = $(shell uname -s) - - -target: $(TARGET) - -$(TARGET): $(COBJS) $(LIBDEP) - @echo "> building $(EXEC)..." -# @echo $(TOPPATH); -# @echo $(LIBABSPATH); -# @echo $(GVABSPATH); - -ifeq ($(OS), Darwin) -# echo "This is MacOS"; - @$(CC) $(CFLAGS) -I$(INCDIR) $(COBJS) $(LIBPATH) -Wl,-rpath $(LIBABSPATH) -Wl,-rpath $(GVABSPATH) -L$(LIBDIR) -L$(MACLIB) $(EXTLIB) -lpthread -o $@ -else -# echo "This is Linux"; - @$(CC) $(CFLAGS) -I$(INCDIR) $(COBJS) $(LIBPATH) -Wl,-rpath $(LIBABSPATH) -Wl,-rpath $(GVABSPATH) -L$(LIBDIR) $(EXTLIB) -lpthread -o $@ -endif - - @echo "" - @echo " Build Successful !!" - -# @$(YOSYSCONF) -o $@ --cxxflags -rdynamic -I$(INCDIR) $(COBJS) -L$(LIBDIR) --ldlibs -lstdc++ $(EXTLIB) -pthread -lyosys -# @$(CC) $(CFLAGS) -I$(INCDIR) $(COBJS) -L$(LIBDIR) $(EXTLIB) -static -lpthread -o $@ -# @$(CC) $(CFLAGS) -I$(INCDIR) $(COBJS) -L$(LIBDIR) $(EXTLIB) -lpthread -o $@ diff --git a/src/main/main.cpp b/src/main/main.cpp index d29f9577..0ab9056b 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -3,60 +3,55 @@ PackageName [ main ] Synopsis [ Define main() ] Author [ Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2007-present LaDs(III), GIEE, NTU, Taiwan ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ -#ifndef GV_MAIN_CC -#define GV_MAIN_CC - #include "gvCmdMgr.h" #include "gvMsg.h" -#include "gvUsage.h" -#include "kernel/yosys.h" +/*#include "gvUsage.h"*/ #include "util.h" using namespace std; -string GVMsg::_allName = ""; +string GVMsg::_allName = ""; ofstream GVMsg::_allout; GVMsgMgr gvMsg; -GVUsage gvUsage; +/*GVUsage gvUsage;*/ //---------------------------------------------------------------------- // Global cmd Manager //---------------------------------------------------------------------- GVCmdMgr* gvCmdMgr = new GVCmdMgr("gv"); -extern bool GVinitCommonCmd(); -extern bool GVinitNtkCmd(); -extern bool GVinitSimCmd(); -extern bool GVinitVrfCmd(); -extern bool GVinitAbcCmd(); -extern bool GVinitModCmd(); -extern bool GVinitBddCmd(); -extern bool GVinitProveCmd(); -extern bool GVinitProveCmd(); -extern bool GVinitItpCmd(); -extern bool GVinitCirCmd(); - -static void -usage() { - cout << "Usage: cirTest [ -File < doFile > ]" << endl; -} +extern bool initCommonCmd(); +extern bool initSimCmd(); +extern bool initVrfCmd(); +extern bool initAbcCmd(); +extern bool initModCmd(); +extern bool initBddCmd(); +/*extern bool initProveCmd();*/ +/*extern bool initItpCmd();*/ +extern bool initCirCmd(); +extern bool initYosysCmd(); +extern bool initAppCmd(); +extern bool initExpCmd(); +/*static void usage() {*/ +/* cout << "Usage: ./gv [ -File < doFile > ]" << endl;*/ +/*}*/ +/**/ static void myexit() { - usage(); + /*usage();*/ exit(-1); } -int -main(int argc, char** argv) { - myUsage.reset(); +int main(int argc, char** argv) { + /*myUsage.reset();*/ ifstream dof; - if (argc == 3) { // -file + if (argc == 3) { // -file if (myStrNCmp("-File", argv[1], 2) == 0) { if (!gvCmdMgr->openDofile(argv[2])) { cout << "Error: cannot open file \"" << argv[2] << "\"!!\n"; @@ -70,19 +65,22 @@ main(int argc, char** argv) { cout << "Error: illegal number of argument (" << argc << ")!!\n"; myexit(); } - Yosys::yosys_setup(); // initial yosys command - Yosys::log_streams.push_back(&std::cout); // log yosys message - if (!(GVinitCommonCmd() && GVinitNtkCmd() && GVinitSimCmd() && GVinitVrfCmd() && - GVinitAbcCmd() && GVinitModCmd() && GVinitBddCmd() && GVinitProveCmd() && GVinitItpCmd() && GVinitCirCmd())) + + // cout << "[EXPERIMENTAL VERSION FOR CMAKE v0.1]\n"; + // clang-format off + if (!(initCommonCmd() && initVrfCmd() && initAbcCmd() && initModCmd() && initBddCmd() + && initCirCmd() && initYosysCmd() && initAppCmd() && initExpCmd())) return 1; + // clang-format on + + // printBanner(); + // cout << "GV v0.3.0 - Copyright © 2023-present, DVLab.\n"; GVCmdExecStatus status = GV_CMD_EXEC_DONE; while (status != GV_CMD_EXEC_QUIT) { gvCmdMgr->setPrompt(); status = gvCmdMgr->execOneCmd(); - cout << endl; + if (status != GV_CMD_EXEC_COMMENT) cout << endl; } return 0; } - -#endif diff --git a/src/mod/.depend.mak b/src/mod/.depend.mak deleted file mode 100644 index 787aa841..00000000 --- a/src/mod/.depend.mak +++ /dev/null @@ -1,32 +0,0 @@ -gvModCmd.o: gvModCmd.cpp gvModCmd.h ../../include/gvCmdMgr.h gvModMgr.h \ - ../../include/gvAbcMgr.h ../../include/base/abc/abc.h \ - ../../include/misc/vec/vec.h ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/abc/abc.h \ - ../../include/base/main/abcapis.h ../../include/base/cmd/cmd.h \ - ../../include/base/io/ioAbc.h ../../include/misc/util/utilNam.h \ - ../../include/base/main/mainInt.h ../../include/base/main/main.h \ - ../../include/misc/tim/tim.h ../../include/map/if/if.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/util/utilTruth.h \ - ../../include/opt/dau/dau.h ../../include/misc/vec/vecHash.h \ - ../../include/aig/aig/aig.h ../../include/proof/ssw/ssw.h \ - ../../include/proof/fra/fra.h ../../include/opt/dar/dar.h \ - ../../include/sat/bsat/satSolver.h ../../include/sat/bsat/satVec.h \ - ../../include/sat/bsat/satClause.h ../../include/misc/util/utilDouble.h \ - ../../include/aig/ioa/ioa.h ../../include/gvAbcNtk.h \ - ../../include/gvMsg.h ../../include/kernel/yosys.h \ - /usr/include/tcl8.6/tcl.h /usr/include/tcl8.6/tclDecls.h \ - /usr/include/tcl8.6/tclPlatDecls.h ../../include/kernel/hashlib.h \ - ../../include/kernel/log.h ../../include/kernel/rtlil.h \ - ../../include/kernel/constids.inc ../../include/kernel/register.h \ - ../../include/util.h ../../include/rnGen.h ../../include/myUsage.h -gvModMgr.o: gvModMgr.cpp gvModMgr.h ../../include/gvCmdMgr.h diff --git a/src/mod/.extheader.mak b/src/mod/.extheader.mak deleted file mode 100644 index 57447686..00000000 --- a/src/mod/.extheader.mak +++ /dev/null @@ -1,7 +0,0 @@ -mod.d: ../../include/gvModMgr.h ../../include/gvModCmd.h -../../include/gvModMgr.h: gvModMgr.h - @rm -f ../../include/gvModMgr.h - @ln -fs ../src/mod/gvModMgr.h ../../include/gvModMgr.h -../../include/gvModCmd.h: gvModCmd.h - @rm -f ../../include/gvModCmd.h - @ln -fs ../src/mod/gvModCmd.h ../../include/gvModCmd.h diff --git a/src/mod/Makefile b/src/mod/Makefile deleted file mode 100644 index 4957d3a2..00000000 --- a/src/mod/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -PKGFLAG = $(DEBUG_FLAG) -EXTHDRS = gvModMgr.h gvModCmd.h - -include ../Makefile.in -include ../Makefile.lib diff --git a/src/mod/gvModCmd.cpp b/src/mod/gvModCmd.cpp deleted file mode 100644 index 6b2ec956..00000000 --- a/src/mod/gvModCmd.cpp +++ /dev/null @@ -1,219 +0,0 @@ -#ifndef GV_MOD_CMD_C -#define GV_MOD_CMD_C - -#include "gvModCmd.h" -#include "gvAbcMgr.h" -#include "gvModMgr.h" -#include "gvMsg.h" -#include "kernel/yosys.h" -#include "util.h" -#include -#include -#include - -bool -GVinitModCmd() { - if (gvModMgr) delete gvModMgr; - gvModMgr = new GVModMgr; - return (gvCmdMgr->regCmd("SEt SYStem", 2, 3, new GVSetSystemCmd) && - gvCmdMgr->regCmd("RESET SYStem", 5, 3, new GVResetCmd) && - gvCmdMgr->regCmd("WIZard", 3, new GVSetWizardCmd)); -} - -GVCmdExecStatus -GVSetSystemCmd::exec(const string& option) { - if (!gvModMgr->getInputFileExist()) { - gvMsg(GV_MSG_IFO) << "[ERROR]: Please use command \"READ DESIGN\" to " - "read the input file first !!\n"; - return GV_CMD_EXEC_NOP; - } - - bool setup = false, vrf = false; - vector options; - - GVCmdExec::lexOptions(option, options); - if (options.size() == 0) - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, "<(string mode)>"); - - size_t n = options.size(); - for (size_t i = 0; i < n; ++i) { - const string& token = options[i]; - if (myStrNCmp("setup", token, 3) == 0) { - if (vrf) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - else setup = true; - - } else if (myStrNCmp("vrf", token, 3) == 0) { - if (setup) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - else vrf = true; - } else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); - } - - if (setup) gvModMgr->setGVMode(GV_MOD_TYPE_SETUP); - else if (vrf) gvModMgr->setGVMode(GV_MOD_TYPE_VERIFY); - - return GV_CMD_EXEC_DONE; -} - -void -GVSetSystemCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: SEt SYStem " << endl; -} - -void -GVSetSystemCmd::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "SEt System: " - << "Switch to setup/vrf mode." << endl; -} - -GVCmdExecStatus -GVResetCmd ::exec(const string& option) { - - bool delete_abc = true; - bool delete_yosys = true; - - vector options; - GVCmdExec::lexOptions(option, options); - if (options.size() > 1) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[1]); - if (options.size() == 1) { - const string& token = options[0]; - if (myStrNCmp("abc", token, 1) == 0) { - delete_yosys = false; - } else if (myStrNCmp("yosys", token, 1) == 0) { - delete_abc = false; - } else { - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); - } - } - - if (delete_abc) { - Cmd_CommandExecute(abcMgr->get_Abc_Frame_t(), "empty"); - if (abcMgr) delete abcMgr; - abcMgr = new AbcMgr; - } - - if (delete_yosys) { - Yosys::run_pass("delete"); - } - - myUsage.reset(); - gvModMgr->reset(); - - // if (gvModMgr) delete gvModMgr; - // gvModMgr = new GVModMgr; -} - -void -GVResetCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: RESET SYStem [ Abc | Yosys ]" << endl; - gvMsg(GV_MSG_IFO) - << " If engine is specified, only delete the ntk stored inside. " - "However, it may be risky to only delete partial datas." - << endl; -} - -void -GVResetCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "RESET SYStem: " - << "Delete all ntks in gv and reset to setup mode." - << endl; -} - -GVCmdExecStatus -GVSetWizardCmd::exec(const string& option) { - GVCmdExecStatus status = GV_CMD_EXEC_DONE; - bool isFile = false; - string wizardFileName = ""; - vector options; - - gvModMgr->setWizard(true); - GVCmdExec::lexOptions(option, options); - if (options.size() < 2) - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, - "<-File> <(string wizardFileName)>"); - - size_t n = options.size(); - for (size_t i = 0; i < n; ++i) { - const string& token = options[i]; - if (myStrNCmp("-File", token, 2) == 0) { - if (isFile) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - else { - isFile = true; - } - } else if (isFile) { - if (wizardFileName != "") - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - else { - wizardFileName = token; - } - } else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); - } - // Start read the wizard file content - ifstream infile(wizardFileName); - if (!infile) { - gvMsg(GV_MSG_IFO) << "[ERROR]: Wizard file name \"" + wizardFileName + - "\" not found !!\n"; - return GV_CMD_EXEC_ERROR; - } - - string prompt = ""; - vector promptBound; - string bound; - - while (1) { - getline(infile, bound); - if (stoi(bound) == 0) break; - promptBound.push_back(stoi(bound)); - cout << bound << endl; - for (int i = 0; i < stoi(bound); ++i) { - getline(infile, prompt); - gvModMgr->setWizardContent(prompt); - } - } - - // Start the GV tutorial wizard - int promptPos = 0, wizardIdx = 0, progress = 1; - bool firstPrompt = true, debug = false; - system("clear"); - while (status != GV_CMD_EXEC_QUIT) { - gvCmdMgr->setPrompt(); - gvModMgr->printWizardPrompt(promptPos, promptBound[wizardIdx]); - if (!firstPrompt) - gvModMgr->printWizardProgress(progress, promptBound.size()); - - status = gvCmdMgr->execOneCmd(); - - if (wizardIdx == promptBound.size() - 1) { - system("clear"); - break; - } - - if (status == GV_CMD_EXEC_DONE || firstPrompt || debug) { - promptPos = promptBound[wizardIdx] + promptPos; - wizardIdx++; - } - cout << endl; - - if (!firstPrompt) { - if (status == GV_CMD_EXEC_DONE || debug) { - gvModMgr->printWizardPrompt(-1, promptBound[wizardIdx]); - progress++; - } else gvModMgr->printWizardPrompt(-2, promptBound[wizardIdx]); - } else firstPrompt = false; - - system("clear"); - } - return GV_CMD_EXEC_DONE; -} - -void -GVSetWizardCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: Type \"WIZard\" " << endl; -} - -void -GVSetWizardCmd::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "WIZard: " - << "Start the GV turtorial wizard." << endl; -} -#endif diff --git a/src/mod/gvModCmd.h b/src/mod/gvModCmd.h deleted file mode 100644 index 819ec2a5..00000000 --- a/src/mod/gvModCmd.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef GV_MOD_CMD_H -#define GV_MOD_CMD_H - -#include "gvCmdMgr.h" -#include "gvModMgr.h" - -GV_COMMAND(GVSetSystemCmd, GV_CMD_TYPE_MOD); -GV_COMMAND(GVResetCmd, GV_CMD_TYPE_MOD); -GV_COMMAND(GVSetWizardCmd, GV_CMD_TYPE_MOD); - -#endif \ No newline at end of file diff --git a/src/mod/gvModMgr.cpp b/src/mod/gvModMgr.cpp deleted file mode 100644 index 582d8b3e..00000000 --- a/src/mod/gvModMgr.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include "gvModMgr.h" -#include "gvCmdMgr.h" -#include -#include -#include -#include - -GVModMgr* gvModMgr; - -/* -------------------------------------------------- *\ - * Class GVModMgr Implementations -\* -------------------------------------------------- */ -GVModMgr::GVModMgr() { - _inputFileExist = false; - _property = -1; - _propertySet = false; - _inputFileName = ""; - _aig_name = ""; - _gvMode = GVModType::GV_MOD_TYPE_SETUP; // default mode : Setup - _gvEng = GVModEngine::GV_MOD_ENGINE_YOSYS; // default engine : yosys - setModPromt(); -} - -GVModMgr::~GVModMgr() {} - -/* ------------------------- *\ - * GET functions -\* ------------------------- */ -bool -GVModMgr::getInputFileExist() { - return _inputFileExist; -} - -string -GVModMgr::getInputFileName() { - return _inputFileName; -} - -string -GVModMgr::getAigFileName() { - return _aig_name; -} - -string -GVModMgr::getTopModuleName() { - return _top_module_name; -} - -GVModType -GVModMgr::getGVMode() { - return _gvMode; -} - -GVModEngine -GVModMgr::getGVEngine() { - return _gvEng; -} - -string -GVModMgr::getModPrompt() { - setModPromt(); // update mode prompt - return _modPrompt; -} - -int -GVModMgr::getSafe() { - return _property; -} - -void -GVModMgr::printWizardPrompt(int promptStart, int promptLength) { - if (promptStart < 0) { - if (promptStart == -1) { - cout << "[CORRECT COMMAND] !! "; - cout << "(press Enter to continue) ..."; - } else if (promptStart == -2) { - // cout << "[ERROR COMMAND] !! "; - cout << "(press Enter to type the command again) ..."; - } - cin.get(); - return; - } - - int idx = 0; - while (idx++ < promptLength) cout << _wizardContent[promptStart++] << "\n"; -} - -void -GVModMgr::printWizardProgress(int pos, int promptNum) { - float float_percent = (static_cast(pos) / (promptNum - 1)) * 100; - int int_percent = float_percent; - int idx = 0; - cout << "progress : ["; - while (idx++ < pos) cout << "="; - cout << ">"; - idx = 0; - while (idx++ < promptNum - pos - 1) cout << " "; - cout << "] "; - - cout << int_percent << "%\n\n"; -} - -/* ------------------------- *\ - * SET functions -\* ------------------------- */ -void -GVModMgr::setInputFileExist(bool exist) { - _inputFileExist = exist; -} - -void -GVModMgr::setInputFileName(string& filename) { - _inputFileName = filename; -} - -void -GVModMgr::setAigFileName(string aigFileName) { - _aig_name = aigFileName; -} - -void -GVModMgr::setTopModuleName(string topModuleName) { - _top_module_name = topModuleName; -} - -void -GVModMgr::setGVMode(GVModType mode) { - _gvMode = mode; - setModPromt(); -} -void -GVModMgr::setGVEngine(GVModEngine engine) { - _gvEng = engine; - setModPromt(); -} -void -GVModMgr::setModPromt() { - if (_gvMode == GVModType::GV_MOD_TYPE_SETUP) - _modPrompt = GVEngineString[_gvEng] + GVModTypeString[_gvMode]; - else _modPrompt = GVModTypeString[_gvMode]; - gvCmdMgr->updateModPrompt(_modPrompt); -} -void -GVModMgr::setSafe(int p) { - _property = p; - _propertySet = true; -} - -void -GVModMgr::setWizardContent(string prompt) { - _wizardContent.push_back(prompt); -} - -/* ------------------------- *\ - * RESET functions -\* ------------------------- */ -void -GVModMgr::reset() { - _inputFileExist = false; - _property = -1; - _propertySet = false; - _inputFileName = ""; - _aig_name = ""; - setModPromt(); -} diff --git a/src/mod/gvModMgr.h b/src/mod/gvModMgr.h deleted file mode 100644 index 13d86534..00000000 --- a/src/mod/gvModMgr.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef GV_MOD_MGR -#define GV_MOD_MGR - -#include "gvCmdMgr.h" -#include -#include -using namespace std; - -class GVModMgr; - -const string GVEngineString[] = {"yosys", "abc"}; - -const string GVModTypeString[] = {"gv", "SETUP", "vrf"}; - -enum GVModType -{ - GV_MOD_TYPE_NONE = 0, - GV_MOD_TYPE_SETUP = 1, - GV_MOD_TYPE_VERIFY = 2 -}; - -enum GVModEngine -{ - GV_MOD_ENGINE_YOSYS = 0, - GV_MOD_ENGINE_ABC = 1 -}; - -extern GVModMgr* gvModMgr; - -class GVModMgr -{ - public: - GVModMgr(); - ~GVModMgr(); - // get functions - bool getInputFileExist(); - string getInputFileName(); - string getAigFileName(); - string getTopModuleName(); - GVModType getGVMode(); - GVModEngine getGVEngine(); - string getModPrompt(); - int getSafe(); - bool getWizard() { return _wizard; }; - - // set functions - void setInputFileExist(bool exist); - void setInputFileName(string& filename); - void setAigFileName(string aigFileName); - void setTopModuleName(string topModuleName); - void setGVMode(GVModType mode); - void setGVEngine(GVModEngine engine); - void setModPromt(); - void setSafe(int p); - void setWizard(bool wiz) { _wizard = wiz; }; - void setWizardContent(string prompt); - - // reset - void reset(); - - // GV tutorial wizard - void printWizardPrompt(int promptStart, int promptLength); - void printWizardProgress(int pos, int promptNum); - - private: - bool _inputFileExist; - string _inputFileName; - string _aig_name; - string _modPrompt; - string _top_module_name; - GVModType _gvMode; - GVModEngine _gvEng; - vector _vrfMode; - vector _setupMode; - vector _wizardContent; - int _property; - bool _propertySet; - bool _wizard; -}; - -#endif diff --git a/src/mod/modCmd.cpp b/src/mod/modCmd.cpp new file mode 100644 index 00000000..e1fb8374 --- /dev/null +++ b/src/mod/modCmd.cpp @@ -0,0 +1,115 @@ +#ifndef GV_MOD_CMD_C +#define GV_MOD_CMD_C + +#include "modCmd.h" + +#include +#include +#include + +#include "cirMgr.h" +#include "modMgr.h" +#include "util.h" + +bool initModCmd() { + if (modeMgr) delete modeMgr; + modeMgr = new ModMgr; + return (gvCmdMgr->regCmd("SEt SYStem", 2, 3, new ModSetSystemCmd)); +} + +GVCmdExecStatus ModSetSystemCmd::exec(const string& option) { + bool setup = false, vrf = false, app = false; + ModType mode = MOD_TYPE_SETUP; + vector options; + + GVCmdExec::lexOptions(option, options); + if (options.size() == 0) + return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, "<(string mode)>"); + + size_t n = options.size(); + for (size_t i = 0; i < n; ++i) { + const string& token = options[i]; + if (myStrNCmp("setup", token, 3) == 0) { + if (vrf) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); + else setup = true; + } else if (myStrNCmp("vrf", token, 3) == 0) { + if (setup) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); + else vrf = true; + } else if (myStrNCmp("app", token, 3) == 0) { + if (setup) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); + else app = true; + } else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); + } + + if (vrf) mode = MOD_TYPE_VERIFY; + else if (app) mode = MOD_TYPE_APP; + + if (vrf && cirMgr == 0) { + cout << "[ERROR]: Please use command \"CIRREAD\" to read the input file first !!\n"; + return GV_CMD_EXEC_NOP; + } + + modeMgr->setGVMode(mode); + + return GV_CMD_EXEC_DONE; +} + +void ModSetSystemCmd::usage(const bool& verbose) const { + cout << "Usage: SEt SYStem " << endl; +} + +void ModSetSystemCmd::help() const { + cout << setw(20) << left << "SEt System: " + << "Switch to setup/vrf mode." << endl; +} + +// GVCmdExecStatus GVResetCmd ::exec(const string& option) { +// bool delete_abc = true; +// bool delete_yosys = true; + +// vector options; +// GVCmdExec::lexOptions(option, options); +// if (options.size() > 1) +// return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[1]); +// if (options.size() == 1) { +// const string& token = options[0]; +// if (myStrNCmp("abc", token, 1) == 0) { +// delete_yosys = false; +// } else if (myStrNCmp("yosys", token, 1) == 0) { +// delete_abc = false; +// } else { +// return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); +// } +// } + +// if (delete_abc) { +// Cmd_CommandExecute(abcMgr->get_Abc_Frame_t(), "empty"); +// if (abcMgr) delete abcMgr; +// abcMgr = new AbcMgr; +// } + +// if (delete_yosys) { +// Yosys::run_pass("delete"); +// } + +// myUsage.reset(); +// modeMgr->reset(); + +// // if (modeMgr) delete modeMgr; +// // modeMgr = new modeMgr; +// } + +// void GVResetCmd ::usage(const bool& verbose) const { +// cout << "Usage: RESET SYStem [ Abc | Yosys ]" << endl; +// cout +// << " If engine is specified, only delete the ntk stored inside. " +// "However, it may be risky to only delete partial datas." +// << endl; +// } + +// void GVResetCmd ::help() const { +// cout << setw(20) << left << "RESET SYStem: " +// << "Delete all ntks in gv and reset to setup mode." << endl; +// } + +#endif diff --git a/src/mod/modCmd.h b/src/mod/modCmd.h new file mode 100644 index 00000000..ad849742 --- /dev/null +++ b/src/mod/modCmd.h @@ -0,0 +1,7 @@ +#pragma once + + +#include "gvCmdMgr.h" + +GV_COMMAND(ModSetSystemCmd, GV_CMD_TYPE_MOD); + diff --git a/src/mod/modMgr.cpp b/src/mod/modMgr.cpp new file mode 100644 index 00000000..e7f86c1b --- /dev/null +++ b/src/mod/modMgr.cpp @@ -0,0 +1,48 @@ +#include "modMgr.h" + +#include + +#include "gvCmdMgr.h" + +ModMgr* modeMgr; + +ModType getMode() { return modeMgr->getCurrMode(); }; +/** + * @brief Constructs a ModMgr object with default values. + * + */ +ModMgr::ModMgr() { + _gvMode = ModType::MOD_TYPE_SETUP; // default mode : Setup + setModPromt(); +} + +/** + * @brief Resets the Mode Manager object to its initial state. + * + */ +void ModMgr::reset() { + setModPromt(); +} + +/** + * @brief Sets the Mode Type (setup/vrf) + * + * This function sets the current mode type. + * Default type is the SETUP mode. + * + * @param mode MOD_TYPE_SETUP or MOD_TYPE_VRF + */ +void ModMgr::setGVMode(const ModType& mode) { + _gvMode = mode; + setModPromt(); +} + +/** + * @brief Sets the module prompt (string) based on the current mode. + * + * This function sets the module prompt based on the current ModType mode (_gvMode). + */ +void ModMgr::setModPromt() { + _modPrompt = ModTypeString[_gvMode]; + gvCmdMgr->updateModPrompt(_modPrompt); +} diff --git a/src/mod/modMgr.h b/src/mod/modMgr.h new file mode 100644 index 00000000..113d2356 --- /dev/null +++ b/src/mod/modMgr.h @@ -0,0 +1,39 @@ +#pragma once +#define MOD_MGR + +#include + +#include "gvType.h" + +using namespace std; + +class ModMgr; + +const string ModTypeString[] = {"gv", "setup", "vrf", "app"}; + +extern ModMgr* modeMgr; + +class ModMgr { +public: + ModMgr(); + ~ModMgr(){}; + // reset + void reset(); + + // get functions + string getModPrompt() { + setModPromt(); // update mode prompt + return _modPrompt; + }; + inline ModType getCurrMode() { return _gvMode; }; + + // set functions + void setGVMode(const ModType& = ModType::MOD_TYPE_SETUP); + void setModPromt(); + +private: + string _modPrompt; + ModType _gvMode; +}; + + diff --git a/src/ntk/.depend.mak b/src/ntk/.depend.mak deleted file mode 100644 index ea91cf4a..00000000 --- a/src/ntk/.depend.mak +++ /dev/null @@ -1,99 +0,0 @@ -gvNtkBdd.o: gvNtkBdd.cpp ../../include/bddMgrV.h ../../include/myHash.h \ - ../../include/bddNodeV.h ../../include/bddNodeV.h ../../include/gvMsg.h \ - gvNtk.h ../../include/gvAbcMgr.h ../../include/base/abc/abc.h \ - ../../include/misc/vec/vec.h ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/abc/abc.h \ - ../../include/base/main/abcapis.h ../../include/base/cmd/cmd.h \ - ../../include/base/io/ioAbc.h ../../include/misc/util/utilNam.h \ - ../../include/base/main/mainInt.h ../../include/base/main/main.h \ - ../../include/misc/tim/tim.h ../../include/map/if/if.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/util/utilTruth.h \ - ../../include/opt/dau/dau.h ../../include/misc/vec/vecHash.h \ - ../../include/aig/aig/aig.h ../../include/proof/ssw/ssw.h \ - ../../include/proof/fra/fra.h ../../include/opt/dar/dar.h \ - ../../include/sat/bsat/satSolver.h ../../include/sat/bsat/satVec.h \ - ../../include/sat/bsat/satClause.h ../../include/misc/util/utilDouble.h \ - ../../include/aig/ioa/ioa.h ../../include/gvAbcNtk.h \ - ../../include/kernel/sigtools.h ../../include/kernel/yosys.h \ - /usr/include/tcl8.6/tcl.h /usr/include/tcl8.6/tclDecls.h \ - /usr/include/tcl8.6/tclPlatDecls.h ../../include/kernel/hashlib.h \ - ../../include/kernel/log.h ../../include/kernel/rtlil.h \ - ../../include/kernel/constids.inc ../../include/kernel/register.h \ - ../../include/kernel/utils.h ../../include/util.h ../../include/rnGen.h \ - ../../include/myUsage.h -gvNtkCmd.o: gvNtkCmd.cpp gvNtkCmd.h ../../include/gvCmdMgr.h \ - ../../include/gvMsg.h ../../include/util.h ../../include/rnGen.h \ - ../../include/myUsage.h ../../include/gvAbcMgr.h \ - ../../include/base/abc/abc.h ../../include/misc/vec/vec.h \ - ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/abc/abc.h \ - ../../include/base/main/abcapis.h ../../include/base/cmd/cmd.h \ - ../../include/base/io/ioAbc.h ../../include/misc/util/utilNam.h \ - ../../include/base/main/mainInt.h ../../include/base/main/main.h \ - ../../include/misc/tim/tim.h ../../include/map/if/if.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/util/utilTruth.h \ - ../../include/opt/dau/dau.h ../../include/misc/vec/vecHash.h \ - ../../include/aig/aig/aig.h ../../include/proof/ssw/ssw.h \ - ../../include/proof/fra/fra.h ../../include/opt/dar/dar.h \ - ../../include/sat/bsat/satSolver.h ../../include/sat/bsat/satVec.h \ - ../../include/sat/bsat/satClause.h ../../include/misc/util/utilDouble.h \ - ../../include/aig/ioa/ioa.h ../../include/gvAbcNtk.h \ - ../../include/gvModMgr.h ../../include/gvCmdMgr.h gvNtk.h \ - ../../include/kernel/sigtools.h ../../include/kernel/yosys.h \ - /usr/include/tcl8.6/tcl.h /usr/include/tcl8.6/tclDecls.h \ - /usr/include/tcl8.6/tclPlatDecls.h ../../include/kernel/hashlib.h \ - ../../include/kernel/log.h ../../include/kernel/rtlil.h \ - ../../include/kernel/constids.inc ../../include/kernel/register.h \ - ../../include/kernel/utils.h -gvNtk.o: gvNtk.cpp gvNtk.h ../../include/gvAbcMgr.h \ - ../../include/base/abc/abc.h ../../include/misc/vec/vec.h \ - ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/abc/abc.h \ - ../../include/base/main/abcapis.h ../../include/base/cmd/cmd.h \ - ../../include/base/io/ioAbc.h ../../include/misc/util/utilNam.h \ - ../../include/base/main/mainInt.h ../../include/base/main/main.h \ - ../../include/misc/tim/tim.h ../../include/map/if/if.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/util/utilTruth.h \ - ../../include/opt/dau/dau.h ../../include/misc/vec/vecHash.h \ - ../../include/aig/aig/aig.h ../../include/proof/ssw/ssw.h \ - ../../include/proof/fra/fra.h ../../include/opt/dar/dar.h \ - ../../include/sat/bsat/satSolver.h ../../include/sat/bsat/satVec.h \ - ../../include/sat/bsat/satClause.h ../../include/misc/util/utilDouble.h \ - ../../include/aig/ioa/ioa.h ../../include/gvAbcNtk.h \ - ../../include/kernel/sigtools.h ../../include/kernel/yosys.h \ - /usr/include/tcl8.6/tcl.h /usr/include/tcl8.6/tclDecls.h \ - /usr/include/tcl8.6/tclPlatDecls.h ../../include/kernel/hashlib.h \ - ../../include/kernel/log.h ../../include/kernel/rtlil.h \ - ../../include/kernel/constids.inc ../../include/kernel/register.h \ - ../../include/kernel/utils.h ../../include/gvMsg.h ../../include/util.h \ - ../../include/rnGen.h ../../include/myUsage.h diff --git a/src/ntk/.extheader.mak b/src/ntk/.extheader.mak deleted file mode 100644 index 81497bb9..00000000 --- a/src/ntk/.extheader.mak +++ /dev/null @@ -1,7 +0,0 @@ -ntk.d: ../../include/gvNtkCmd.h ../../include/gvNtk.h -../../include/gvNtkCmd.h: gvNtkCmd.h - @rm -f ../../include/gvNtkCmd.h - @ln -fs ../src/ntk/gvNtkCmd.h ../../include/gvNtkCmd.h -../../include/gvNtk.h: gvNtk.h - @rm -f ../../include/gvNtk.h - @ln -fs ../src/ntk/gvNtk.h ../../include/gvNtk.h diff --git a/src/ntk/.map.txt b/src/ntk/.map.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/src/ntk/.mapGold.txt b/src/ntk/.mapGold.txt deleted file mode 100644 index a247120e..00000000 --- a/src/ntk/.mapGold.txt +++ /dev/null @@ -1,23 +0,0 @@ -input 0 0 reset -input 1 0 clk -output 0 0 z1 -output 1 0 z2 -output 2 0 z3 -output 3 0 z4 -output 4 0 z5 -latch 0 0 x -latch 1 1 x -latch 2 2 x -latch 3 3 x -latch 4 4 x -latch 5 5 x -latch 6 6 x -latch 7 7 x -latch 8 0 y -latch 9 1 y -latch 10 2 y -latch 11 3 y -latch 12 4 y -latch 13 5 y -latch 14 6 y -latch 15 7 y diff --git a/src/ntk/.mapOld.txt b/src/ntk/.mapOld.txt deleted file mode 100644 index a247120e..00000000 --- a/src/ntk/.mapOld.txt +++ /dev/null @@ -1,23 +0,0 @@ -input 0 0 reset -input 1 0 clk -output 0 0 z1 -output 1 0 z2 -output 2 0 z3 -output 3 0 z4 -output 4 0 z5 -latch 0 0 x -latch 1 1 x -latch 2 2 x -latch 3 3 x -latch 4 4 x -latch 5 5 x -latch 6 6 x -latch 7 7 x -latch 8 0 y -latch 9 1 y -latch 10 2 y -latch 11 3 y -latch 12 4 y -latch 13 5 y -latch 14 6 y -latch 15 7 y diff --git a/src/ntk/Makefile b/src/ntk/Makefile deleted file mode 100644 index a7c9a1f5..00000000 --- a/src/ntk/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -PKGFLAG = $(DEBUG_FLAG) - -EXTHDRS = gvNtkCmd.h gvNtk.h - -include ../Makefile.in -include ../Makefile.lib - diff --git a/src/ntk/abcc b/src/ntk/abcc deleted file mode 120000 index c1ce9170..00000000 --- a/src/ntk/abcc +++ /dev/null @@ -1 +0,0 @@ -../../engine/abc/gv_src/ \ No newline at end of file diff --git a/src/ntk/gvNtk.cpp b/src/ntk/gvNtk.cpp deleted file mode 100644 index 452833d0..00000000 --- a/src/ntk/gvNtk.cpp +++ /dev/null @@ -1,581 +0,0 @@ -/**************************************************************************** - FileName [ gvNtk.cpp ] - PackageName [ gv/src/ntk ] - Synopsis [ GV Network ] - Author [ ] - Copyright [ ] -****************************************************************************/ -#include "gvNtk.h" -#include "base/abc/abc.h" -#include "gvMsg.h" -#include "map" -#include "util.h" -#include - -// extern functions -extern "C" -{ - Gia_Man_t* Wln_BlastSystemVerilog(char* pFileName, char* pTopModule, - char* pDefines, int fSkipStrash, - int fInvert, int fTechMap, int fVerbose); -} -// declaration -GVRTLDesign* gvRTLDesign; -GVNtkMgr* gvNtkMgr; - -// ---------------------------------------------------------------------- -// constructor / deconstructor for GVNtkMgr -// ---------------------------------------------------------------------- -void -GVNtkMgr::reset() { - // info - _InputList.clear(); - _OutputList.clear(); - _InoutList.clear(); - _FFList.clear(); - _ConstList.clear(); - _FFConst0List.clear(); - // map - _id2FaninId.clear(); - _id2GVNetId.clear(); - _netId2Name.clear(); - _netName2Id.clear(); - _idRo2Ppi.clear(); - _idRo2Ri.clear(); - _idRi2Ro.clear(); - _id2Type.clear(); - // fanout info - _id2Fanout.clear(); - // flag - _miscList.clear(); - _globalMisc = 0; // Initial misc value = 0; - // file type - _fileType = 0; -} - -// ---------------------------------------------------------------------- -// print GV network -// ---------------------------------------------------------------------- -// recursively print the gia network -void -GVNtkMgr::print_rec(Gia_Man_t* pGia, Gia_Obj_t* pObj) { - // if the TravId of the node is equal to the global TravId, return - if (Gia_ObjIsTravIdCurrent(pGia, pObj)) { - return; - } - - // set the TravId of the node to be the same as the global TravId, that is - // mark it as traversed - Gia_ObjSetTravIdCurrent(pGia, pObj); - - // If we reach the combinational input(PI + RO (register output, or pseudo - // PI)), return - if (Gia_ObjIsCi(pObj)) { - return; - } - - /* AIG node: #fanin = 2 */ - if (Gia_ObjFaninNum(pGia, pObj) > 1) { - // create a new GVNetId corresponding to abc's id - GVNetId id = - GVNetId::makeNetId(Gia_ObjId(pGia, pObj), 0, GV_NTK_OBJ_AIG); - // map - _id2Type[id.id] = id.type; - // fanin phase - id.fanin0Cp = Gia_ObjFaninC0(pObj); - id.fanin1Cp = Gia_ObjFaninC1(pObj); - createNet(id, GV_NTK_OBJ_AIG); - - /* if fanin id is RO, replace it with PPI */ - // fanin 0 - if (_fileType == GV_NTK_TYPE_V) { - if (getTypeFromId(Gia_ObjId(pGia, Gia_ObjFanin0(pObj))) == - GV_NTK_OBJ_RO) { - _id2FaninId[Gia_ObjId(pGia, pObj)].push_back( - getPpiIdFromRoId(Gia_ObjId(pGia, Gia_ObjFanin0(pObj)))); - GVFanout fanout; - fanout.id = Gia_ObjId(pGia, pObj); - fanout.fanin = 0; - _id2Fanout[getPpiIdFromRoId(Gia_ObjId(pGia, - Gia_ObjFanin0(pObj)))] - .push_back(fanout); - } else { - _id2FaninId[Gia_ObjId(pGia, pObj)].push_back( - Gia_ObjId(pGia, Gia_ObjFanin0(pObj))); - GVFanout fanout; - fanout.id = Gia_ObjId(pGia, pObj); - fanout.fanin = 0; - _id2Fanout[Gia_ObjId(pGia, Gia_ObjFanin0(pObj))].push_back(fanout); - } - } - if (_fileType == GV_NTK_TYPE_AIG) { - _id2FaninId[Gia_ObjId(pGia, pObj)].push_back( - Gia_ObjId(pGia, Gia_ObjFanin0(pObj))); - GVFanout fanout; - fanout.id = Gia_ObjId(pGia, pObj); - fanout.fanin = 0; - _id2Fanout[Gia_ObjId(pGia, Gia_ObjFanin0(pObj))].push_back(fanout); - } - // recursive traverse its left child - print_rec(pGia, Gia_ObjFanin0(pObj)); - - // fanin 1 - if (_fileType == GV_NTK_TYPE_V) { - if (getTypeFromId(Gia_ObjId(pGia, Gia_ObjFanin1(pObj))) == - GV_NTK_OBJ_RO) { - _id2FaninId[Gia_ObjId(pGia, pObj)].push_back( - getPpiIdFromRoId(Gia_ObjId(pGia, Gia_ObjFanin1(pObj)))); - GVFanout fanout; - fanout.id = Gia_ObjId(pGia, pObj); - fanout.fanin = 1; - _id2Fanout[getPpiIdFromRoId(Gia_ObjId(pGia, - Gia_ObjFanin1(pObj)))] - .push_back(fanout); - } else { - _id2FaninId[Gia_ObjId(pGia, pObj)].push_back( - Gia_ObjId(pGia, Gia_ObjFanin1(pObj))); - GVFanout fanout; - fanout.id = Gia_ObjId(pGia, pObj); - fanout.fanin = 1; - _id2Fanout[Gia_ObjId(pGia, Gia_ObjFanin1(pObj))].push_back(fanout); - } - } - if (_fileType == GV_NTK_TYPE_AIG) { - _id2FaninId[Gia_ObjId(pGia, pObj)].push_back( - Gia_ObjId(pGia, Gia_ObjFanin1(pObj))); - } - print_rec(pGia, Gia_ObjFanin1(pObj)); - } - /* PO and RI: #fanin = 1 */ - else if (Gia_ObjFaninNum(pGia, pObj) == 1) { - // fanin 0 - if (_fileType == GV_NTK_TYPE_V) { - if (getTypeFromId(Gia_ObjId(pGia, Gia_ObjFanin0(pObj))) == - GV_NTK_OBJ_RO) { - _id2FaninId[Gia_ObjId(pGia, pObj)].push_back( - getPpiIdFromRoId(Gia_ObjId(pGia, Gia_ObjFanin0(pObj)))); - GVFanout fanout; - fanout.id = Gia_ObjId(pGia, pObj); - fanout.fanin = 0; - _id2Fanout[getPpiIdFromRoId(Gia_ObjId(pGia, - Gia_ObjFanin0(pObj)))] - .push_back(fanout); - - } else { - _id2FaninId[Gia_ObjId(pGia, pObj)].push_back( - Gia_ObjId(pGia, Gia_ObjFanin0(pObj))); - GVFanout fanout; - fanout.id = Gia_ObjId(pGia, pObj); - fanout.fanin = 0; - _id2Fanout[Gia_ObjId(pGia, Gia_ObjFanin0(pObj))].push_back(fanout); - } - } - if (_fileType == GV_NTK_TYPE_AIG) { - _id2FaninId[Gia_ObjId(pGia, pObj)].push_back( - Gia_ObjId(pGia, Gia_ObjFanin0(pObj))); - GVFanout fanout; - fanout.id = Gia_ObjId(pGia, pObj); - fanout.fanin = 0; - _id2Fanout[Gia_ObjId(pGia, Gia_ObjFanin0(pObj))].push_back(fanout); - } - // fanin phase - _id2GVNetId[Gia_ObjId(pGia, pObj)].fanin0Cp = Gia_ObjFaninC0(pObj); - - // recursive traverse its left child - print_rec(pGia, Gia_ObjFanin0(pObj)); - } -} - -// ---------------------------------------------------------------------- -// construct GV network -// ---------------------------------------------------------------------- -void -GVNtkMgr::createNet(const GVNetId& id, const int net_type) { - // assert(!isGVNetInverted(id)); - if (net_type == GV_NTK_OBJ_PI) { - _InputList.push_back(id); - } else if (net_type == GV_NTK_OBJ_PO) { - _OutputList.push_back(id); - } else if (net_type == GV_NTK_OBJ_FF_CS) { - _FFList.push_back(id); - } else { // AIG node - _id2GVNetId[id.id] = id; - } - return; -} - -void -GVNtkMgr::createNetFromAbc(char* pFileName) { - Gia_Man_t* pGia = NULL; // the gia pointer of abc - Gia_Obj_t *pObj, *pObjRi, *pObjRo; // the obj element of gia - - // abc function parameters - char* pTopModule = - NULL; // the top module can be auto detected by yosys, no need to set - char* pDefines = NULL; - int fBlast = 1; // blast the ntk to gia (abc's aig data structure) - int fInvert = 0; - int fTechMap = 1; - int fSkipStrash = 0; - int fCollapse = 0; - int c, fVerbose = 1; // set verbose to 1 to see which yosys command is used - int i, *pWire; - - // read and blast the RTL verilog file into gia - if (_fileType == GV_NTK_TYPE_V) { - pGia = Wln_BlastSystemVerilog(pFileName, pTopModule, pDefines, - fSkipStrash, fInvert, fTechMap, fVerbose); - } else if (_fileType == GV_NTK_TYPE_AIG) { - cout << "reading file" << endl; - pGia = Gia_AigerRead(pFileName, 0, fSkipStrash, 0); - cout << "reading file end" << endl; - } else { - cout << "Error type!!!!!!" << endl; - assert(false); - } - - // increment the global travel id for circuit traversing usage - Gia_ManIncrementTravId(pGia); - // since we don't want to traverse the constant node, set the TravId of the - // constant node to be as the global one - Gia_ObjSetTravIdCurrent(pGia, Gia_ManConst0(pGia)); - // create the PI and PPI - if (_fileType == GV_NTK_TYPE_V) { - Gia_ManForEachPi(pGia, pObj, i) { - // cout << "fff " << i << endl; - // PI - if (i <= (Gia_ManPiNum(pGia) - Gia_ManRegNum(pGia))) { - // create a new GVNetId corresponding to abc's id - GVNetId id = - GVNetId::makeNetId(Gia_ObjId(pGia, pObj), 0, GV_NTK_OBJ_PI); - createNet(id, GV_NTK_OBJ_PI); - // map - _id2GVNetId[id.id] = id; - _id2Type[id.id] = id.type; - } - // PPI - else { - // create a new GVNetId corresponding to abc's id - GVNetId id = GVNetId::makeNetId(Gia_ObjId(pGia, pObj), 0, - GV_NTK_OBJ_FF_CS); - createNet(id, GV_NTK_OBJ_FF_CS); - // map - _id2GVNetId[id.id] = id; - _id2Type[id.id] = id.type; - } - } - } else if (_fileType == GV_NTK_TYPE_AIG) { - Gia_ManForEachPi(pGia, pObj, i) { - // cout << "fff " << i << endl; - // PI - // if (i <= (Gia_ManPiNum(pGia) - Gia_ManRegNum(pGia))) { - // create a new GVNetId corresponding to abc's id - GVNetId id = - GVNetId::makeNetId(Gia_ObjId(pGia, pObj), 0, GV_NTK_OBJ_PI); - createNet(id, GV_NTK_OBJ_PI); - // map - _id2GVNetId[id.id] = id; - _id2Type[id.id] = id.type; - // } - // // PPI - // else { - // // create a new GVNetId corresponding to abc's id - // GVNetId id = GVNetId::makeNetId(Gia_ObjId(pGia, pObj), 0, - // GV_NTK_OBJ_FF_CS); - // createNet(id, GV_NTK_OBJ_FF_CS); - // // map - // _id2GVNetId[id.id] = id; - // _id2Type[id.id] = id.type; - // } - } - } - - // create the PO - Gia_ManForEachPo(pGia, pObj, i) { - // create a new GVNetId corresponding to abc's id - GVNetId id = - GVNetId::makeNetId(Gia_ObjId(pGia, pObj), 0, GV_NTK_OBJ_PO); - createNet(id, GV_NTK_OBJ_PO); - // map - _id2GVNetId[id.id] = id; - _id2Type[id.id] = id.type; - } - - // create the RI (register input, D in FF) - bool hasConst = false; - Gia_ManForEachRi(pGia, pObj, i) { - // create a new GVNetId corresponding to abc's id - GVNetId id = - GVNetId::makeNetId(Gia_ObjId(pGia, pObj), 0, GV_NTK_OBJ_FF_NS); - createNet(id, GV_NTK_OBJ_FF_NS); - // map - _id2GVNetId[id.id] = id; - _id2Type[id.id] = id.type; - if (_fileType == GV_NTK_TYPE_V) { - // the last FF is used to connect const0 - if (i == Gia_ManRegNum(pGia) - 1) { - // FF - _FFConst0List.push_back(id); - // create a new GVNetId for const 0 - GVNetId id_const0 = GVNetId::makeNetId(Gia_ObjId(pGia, Gia_ObjFanin0(pObj)), 0, GV_NTK_OBJ_CONST0); - createNet(id_const0, GV_NTK_OBJ_CONST0); - _ConstList.push_back(id_const0); - // map - _id2GVNetId[id_const0.id] = id_const0; - _id2Type[id_const0.id] = id_const0.type; - } - } - if (_fileType == GV_NTK_TYPE_AIG) { - // the last FF is used to connect const0 - // if (Gia_ObjId(pGia, Gia_ObjFanin0(pObj)) == 0) { - // hasConst = true; - // // FF - // _FFConst0List.push_back(id); - // // create a new GVNetId for const 0 - // GVNetId id_const0 = GVNetId::makeNetId( - // Gia_ObjId(pGia, Gia_ObjFanin0(pObj)), 0, GV_NTK_OBJ_CONST0); - // createNet(id_const0, GV_NTK_OBJ_CONST0); - // _ConstList.push_back(id_const0); - // // map - // _id2GVNetId[id_const0.id] = id_const0; - // _id2Type[id_const0.id] = id_const0.type; - // } - } - // if(!hasConst) { - // create a new GVNetId for const 0 - GVNetId id_const0 = GVNetId::makeNetId(0, 0, GV_NTK_OBJ_CONST0); - createNet(id_const0, GV_NTK_OBJ_CONST0); - _ConstList.push_back(id_const0); - // map - _id2GVNetId[id_const0.id] = id_const0; - _id2Type[id_const0.id] = id_const0.type; - // } - } - - // create the RO (register output, Q in FF) - GVNetId id; - Gia_ManForEachRo(pGia, pObj, i) { - // create a new GVNetId corresponding to abc's id - if (_fileType == GV_NTK_TYPE_V) { - id = - GVNetId::makeNetId(Gia_ObjId(pGia, pObj), 0, GV_NTK_OBJ_RO); - } - if (_fileType == GV_NTK_TYPE_AIG) { - id = - GVNetId::makeNetId(Gia_ObjId(pGia, pObj), 0, GV_NTK_OBJ_FF_CS); - } - // map - _id2GVNetId[id.id] = id; - _id2Type[id.id] = id.type; - // debug - if (_fileType == GV_NTK_TYPE_AIG) { - createNet(id, GV_NTK_OBJ_FF_CS); - } - // the last FF is used to connect const0 - if (_fileType == GV_NTK_TYPE_V) { - if (i < Gia_ManRegNum(pGia) - 1) { - _idRo2Ppi[id.id] = getFF(i).id; - } - } - } - - // map RI and RO - Gia_ManForEachRiRo(pGia, pObjRi, pObjRo, i) { - // map - _idRo2Ri[Gia_ObjId(pGia, pObjRo)] = Gia_ObjId(pGia, pObjRi); - _idRi2Ro[Gia_ObjId(pGia, pObjRi)] = Gia_ObjId(pGia, pObjRo); - // the last FF is used to connect const0 (skip) - if (i < Gia_ManRegNum(pGia)) { - if (_fileType == GV_NTK_TYPE_V) { - _id2FaninId[getPpiIdFromRoId(Gia_ObjId(pGia, pObjRo))].push_back( - Gia_ObjId(pGia, pObjRi)); - } - else if (_fileType == GV_NTK_TYPE_AIG) { - _id2FaninId[Gia_ObjId(pGia, pObjRo)].push_back( - Gia_ObjId(pGia, pObjRi)); - } - } - } - - // dfs traverse from each combinational output PO (primary output) and - // RI (register input, which can be viewed as pseudo PO) - Gia_ManForEachCo(pGia, pObj, i) { - print_rec(pGia, pObj); - } - - // propagate the bubble of Co's - Gia_ManForEachCo(pGia, pObj, i) { - _id2GVNetId[getFaninId(Gia_ObjId(pGia, pObj))[0]].cp ^= _id2GVNetId[Gia_ObjId(pGia, pObj)].fanin0Cp; - } - - // construct the net id/name mapping - if (_fileType == GV_NTK_TYPE_V) { - parseAigMapping(pGia); - } -} - -string -netName(string name, int bit) { - return name + "[" + to_string(bit) + "]"; -} - -// ---------------------------------------------------------------------- -// parse the aig mapping from the ".map.txt" file -// ---------------------------------------------------------------------- -void -GVNtkMgr::parseAigMapping(Gia_Man_t* pGia) { - string buffer; - ifstream mapFile; - int idx, bit; - string name; - - mapFile.open(".map.txt"); - assert(mapFile.is_open()); - while (mapFile) { - if (!(mapFile >> buffer)) break; - // input - if (buffer == "input") { - mapFile >> buffer; - myStr2Int(buffer, idx); - mapFile >> buffer; - myStr2Int(buffer, bit); - mapFile >> buffer; - name = buffer; - _netId2Name[Gia_ObjId(pGia, Gia_ManPi(pGia, idx))] = - netName(name, bit); - _netName2Id[netName(name, bit)] = - Gia_ObjId(pGia, Gia_ManPi(pGia, idx)); - } - // output - else if (buffer == "output") { - mapFile >> buffer; - myStr2Int(buffer, idx); - mapFile >> buffer; - myStr2Int(buffer, bit); - mapFile >> buffer; - name = buffer; - _netId2Name[Gia_ObjId(pGia, Gia_ManPo(pGia, idx))] = - netName(name, bit); - _netName2Id[netName(name, bit)] = - Gia_ObjId(pGia, Gia_ManPo(pGia, idx)); - } - // FF - else if (buffer == "latch") { - mapFile >> buffer; - myStr2Int(buffer, idx); - mapFile >> buffer; - myStr2Int(buffer, bit); - mapFile >> buffer; - name = buffer; - _netId2Name[Gia_ObjId(pGia, - Gia_ObjRiToRo(pGia, Gia_ManRi(pGia, idx)))] = - netName(name, bit); - _netName2Id[netName(name, bit)] = - Gia_ObjId(pGia, Gia_ObjRiToRo(pGia, Gia_ManRi(pGia, idx))); - _netId2Name[Gia_ObjId(pGia, Gia_ManRi(pGia, idx))] = - netName(name, bit) + "_ns"; - _netName2Id[netName(name, bit) + "_ns"] = - Gia_ObjId(pGia, Gia_ManRi(pGia, idx)); - } - } -} - -// ---------------------------------------------------------------------- -// print the information of all PI's -// ---------------------------------------------------------------------- -void -GVNtkMgr::printPi() { - cout << "\nPI :" << endl; - for (unsigned i = 0; i < getInputSize(); i++) { - // if (getNetNameFromId(getInput(i).id).length() != 0) - cout << "PI #" << setw(5) << i << " : net name = " << setw(20) - << getNetNameFromId(getInput(i).id) << " net id = " << setw(10) - << getInput(i).id << endl; - } -} - -// ---------------------------------------------------------------------- -// print the information of all PO's -// ---------------------------------------------------------------------- -void -GVNtkMgr::printPo() { - cout << "\nPO :" << endl; - for (unsigned i = 0; i < getOutputSize(); i++) { - cout << "PO #" << setw(5) << i << " : net name = " << setw(20) - << getNetNameFromId(getOutput(i).id) << " net id = " << setw(10) - << getOutput(i).id << endl; - } -} - -// ---------------------------------------------------------------------- -// print the information of all RI's -// ---------------------------------------------------------------------- -void -GVNtkMgr::printRi() { - cout << "\nFF :" << endl; - for (unsigned i = 0; i < getFFSize(); i++) { - cout << "FF #" << setw(5) << i << " : net name = " << setw(20) - << getNetNameFromId(getFF(i).id) << " net id = " << setw(10) - << getFF(i).id << endl; - } -} - -// ---------------------------------------------------------------------- -// print the information of all Obj in the aig ntk -// ---------------------------------------------------------------------- -void -GVNtkMgr::printSummary() { - // iterate through the net ids - for (auto obj : _id2GVNetId) { - cout << "net " << setw(7) << obj.first; - // if it has fanin - if (_id2FaninId.find(obj.first) != _id2FaninId.end()) { - cout << " , fanin0 = " << setw(7) << _id2FaninId[obj.first][0]; - // if it has the second fanin - if (_id2FaninId[obj.first].size() >= 2) - cout << setw(7) << " , fanin1 = " << _id2FaninId[obj.first][1]; - // cout << endl; - } else if (getGateType(getGVNetId(obj.first)) == GV_NTK_OBJ_PI) { - cout << " , PI, No fanin."; - } else if (getGateType(getGVNetId(obj.first)) == GV_NTK_OBJ_RO) { - cout << " , RO, No fanin. (Please also note that RO is overlapped " - "with PI, so no BDD " - "node is created.)"; - } - if (_id2Fanout.find(obj.first) != _id2Fanout.end()) { - for (int i = 0; i < _id2Fanout[obj.first].size(); ++i) { - cout << setw(7) << " fanout = " << setw(7) - << _id2Fanout[obj.first][i].id << "'s fanin" - << _id2Fanout[obj.first][i].fanin; - } - cout << endl; - } else { - cout << endl; - } - } -} -// ---------------------------------------------------------------------- -// create the new net -// ---------------------------------------------------------------------- -GVNetId -GVNtkMgr::createNet() { - GVNetId id = GVNetId::makeNetId(getNetSize()); - createNet(id, GV_NTK_OBJ_AIG); - return id; -} - -bool -GVNtkMgr::createGVAndGate(GVNetId& id, GVNetId id1, GVNetId id2) { - id.type = GV_NTK_OBJ_AIG; - // Modification for complement - id.fanin0Cp = id1.cp; - id.fanin1Cp = id2.cp; - _id2Type[id.id] = id.type; - vector faninIdList; - faninIdList.push_back(id1.id); - faninIdList.push_back(id2.id); - _id2FaninId[id.id] = faninIdList; - // Update the complement info - createNet(id, GV_NTK_OBJ_AIG); - return true; -} diff --git a/src/ntk/gvNtk.h b/src/ntk/gvNtk.h deleted file mode 100644 index bda9c6a9..00000000 --- a/src/ntk/gvNtk.h +++ /dev/null @@ -1,265 +0,0 @@ -/**************************************************************************** - FileName [ gvNtk.h ] - PackageName [ gv/src/ntk ] - Synopsis [ GV Network ] - Author [ ] - Copyright [ ] ->>>>>>> e49dc0e73d18f38a26c685cf95dad078bf400c08 -****************************************************************************/ - -#ifndef GV_NTK_H -#define GV_NTK_H -#include "gvAbcMgr.h" -#include "kernel/sigtools.h" // Sigmap -#include "kernel/utils.h" // Toposort -#include "kernel/yosys.h" -#include -#include - -USING_YOSYS_NAMESPACE - -// GV Ntk defines -#define isGVNetInverted(netId) (netId.cp) -#define getGVNetIndex(netId) (netId.id) - -// constant -const unsigned GVNtkUD = UINT_MAX; -// declaration -class GVNtkMgr; -extern GVNtkMgr* gvNtkMgr; - -// object types -typedef enum -{ - GV_NTK_OBJ_NONE, // 0: non-existent object - GV_NTK_OBJ_CONST0, // 1: constant 0 - GV_NTK_OBJ_CONST1, // 2: constant 1 - GV_NTK_OBJ_PI, // 3: primary input - GV_NTK_OBJ_PO, // 4: primary output - GV_NTK_OBJ_BUF, // 5: buffer node - GV_NTK_OBJ_AND, // 6: AND node - GV_NTK_OBJ_RO, // 7: Register Output - GV_NTK_OBJ_FF_CS, // 8: Flip Flop Current State - GV_NTK_OBJ_FF_NS, // 9: Flip Flop Next State - GV_NTK_OBJ_NOT, // 10: NOT node - GV_NTK_OBJ_LAST, // 11: last element of the type - GV_NTK_OBJ_AIG // 12: AIG node -} GV_Ntk_Type_t; - -typedef enum -{ - GV_NTK_TYPE_V, // 0: verilog - GV_NTK_TYPE_AIG, // 1: aig - GV_NTK_TYPE_BLIF, // 2: blif - GV_NTK_TYPE_BTOR // 3: btor -} GV_Ntk_Format_t; - -/* - _ _ _ _ _ _ _ _ _ _ _ _ _ _ - | | - (PI) ---------> | | ---------> (PO) - (PPI) .------------> | Combinational Network | -------------> (PPO) - | .---------> | | ----------> | - | | |_ _ _ _ _ _ _ _ _ _ _ _ _ _| | | - | | | | - | | _ _ _ _ _ _ _ _ _ _ | | - | <-------------- | | <-------------. | - | | Flip Flop (FF) | | - (RO=Q) <----------------- |_ _ _ _ _ _ _ _ _ _| <----------------. (RI=D) - (X: current state) (Y: next state) - -*/ - -//---------------------------------------------------------------------- -// GV Ntk Defines -//---------------------------------------------------------------------- -struct GVNetId { - unsigned cp : 1; - unsigned id : 31; - bool fanin0Cp; // fanin 0 is complement - bool fanin1Cp; // fanin 1 is complement - GV_Ntk_Type_t type : GV_NTK_OBJ_AIG; - static GVNetId makeNetId(unsigned i = GVNtkUD, unsigned c = 0, GV_Ntk_Type_t t = GV_NTK_OBJ_AIG, - bool f0cp = false, bool f1cp = false) { - GVNetId j; - j.cp = c; - j.id = i; - j.type = t; - j.fanin0Cp = f0cp; - j.fanin1Cp = f1cp; - return j; - } - GVNetId operator~() const { return makeNetId(id, cp ^ 1); } - const bool operator==(const GVNetId& i) const { return cp == i.cp && id == i.id; } - const bool operator!=(const GVNetId& i) const { return !(*this == i); } -}; - -// fanout info -struct GVFanout { - unsigned id; // the id of the fanout obj - unsigned fanin; // record which fanin is the obj -}; - -class GVNtkMgr -{ - public: - // ------------------------------------------------------------------------- - // Information - // ------------------------------------------------------------------------- - // Constructors for BV Network - GVNtkMgr() { reset(); }; - ~GVNtkMgr() { reset(); } - // get size - inline const uint32_t getNetSize() const { return _id2GVNetId.size(); } - inline const unsigned getInputSize() const { return _InputList.size(); } - inline const unsigned getOutputSize() const { return _OutputList.size(); } - inline const unsigned getInoutSize() const { return _InoutList.size(); } - inline const uint32_t getFFSize() const { return _FFList.size(); } - inline const uint32_t getConstSize() const { return _ConstList.size(); } - inline const uint32_t getFFConst0Size() const { return _FFConst0List.size(); } - // access function - inline const GVNetId& getInput(const unsigned& i) const { - assert(i < getInputSize()); - return _InputList[i]; - } - inline const GVNetId& getOutput(const unsigned& i) const { - assert(i < getOutputSize()); - return _OutputList[i]; - } - inline const GVNetId& getInout(const unsigned& i) const { - assert(i < getInoutSize()); - return _InoutList[i]; - } - inline const GVNetId& getFF(const unsigned& i) const { - assert(i < getFFSize()); - return _FFList[i]; - } - inline const GVNetId& getConst(const unsigned& i) const { - assert(i < getConstSize()); - return _ConstList[i]; - } - inline const GVNetId& getFFConst0(const unsigned& i) const { - assert(i < getFFConst0Size()); - return _FFConst0List[i]; - } - // GV net id - inline const GVNetId& getGVNetId(const unsigned& i) const { return _id2GVNetId.at(i); } - // GV gate type - inline const GV_Ntk_Type_t getGateType(const GVNetId& id) { return id.type; } - inline GV_Ntk_Type_t& getTypeFromId(const unsigned& i) { return _id2Type[i]; } - // fanin - inline const vector& getFaninId(const unsigned& i) const { return _id2FaninId.at(i); } - inline const bool hasFanout(const unsigned& i) const { return _id2Fanout.count(i); } - inline const vector& getFanout(const unsigned& i) const { return _id2Fanout.at(i); } - inline const GVNetId& getInputNetId(const GVNetId&, const uint32_t&) const; - // flag - inline void newMiscData() { - if (getNetSize() > _miscList.size()) { - _miscList.resize(getNetSize()); - } - ++_globalMisc; - } - inline bool isLatestMiscData(const GVNetId& id) const { return _globalMisc == _miscList[id.id]; } - inline void setLatestMiscData(const GVNetId& id) { _miscList[id.id] = _globalMisc; } - // mapping (get id) - inline unsigned getNetIdFromName(string name) { return _netName2Id[name]; } - inline unsigned getPpiIdFromRoId(unsigned id) { return _idRo2Ppi[id]; } - inline unsigned getRiIdFromRoId(unsigned id) { return _idRo2Ri[id]; } - inline unsigned getRoIdFromRiId(unsigned id) { return _idRi2Ro[id]; } - // mapping (get name) - inline string getNetNameFromId(unsigned id) { return _netId2Name[id]; } - - // ------------------------------------------------------------------------- - // Network - // ------------------------------------------------------------------------- - // construct ntk - void createNet(const GVNetId& id, const int net_type); - void createNetFromAbc(char*); - void parseAigMapping(Gia_Man_t* pGia); - void setFileType(unsigned type) { _fileType = type; }; - unsigned getFileType() { return _fileType; }; - // print ntk - void print_rec(Gia_Man_t* pGia, Gia_Obj_t* pObj); - // print functions - void printPi(); // print the information of all PI's - void printPo(); // print the information of all PO's - void printRi(); // print the information of all RI's - void printSummary(); // print the information of all Obj in the aig ntk - // generate net - GVNetId createNet(); - bool createGVAndGate(GVNetId&, GVNetId, GVNetId); - // ------------------------------------------------------------------------- - // BDD - // ------------------------------------------------------------------------- - // build the BDD - const bool setBddOrder(const bool&); - void buildNtkBdd(); - void buildBdd(const GVNetId& netId); - // DFS tranversal - void dfsOrder(const GVNetId&, vector&); - - protected: - // info - vector _InputList; // GVNetId of PI's - vector _OutputList; // GVNetId of PO's - vector _InoutList; // GVNetId of Inout's - vector _FFList; // GVNetId of Flip Flops (current state) - vector _ConstList; // GVNetId of Constants (const0) - vector _FFConst0List; // GVNetId of FF that stores const0 - // map - map> _id2FaninId; - map _id2GVNetId; - map _netId2Name; - map _netName2Id; - map _idRo2Ppi; // PPI: pseudo PI - map _idRo2Ri; // RO: register output (Q) - map _idRi2Ro; // RI: register input (D) - map _id2Type; - map> _id2Fanout; - // flag - vector _miscList; // global misc date list - unsigned _globalMisc; // global misc data for GVNetId in network - // file type - unsigned _fileType; - private: - void reset(); -}; - -// Inline function implementation -inline const GVNetId& -GVNtkMgr::getInputNetId(const GVNetId& id, const uint32_t& i) const { - unsigned faninId = getFaninId(id.id)[i]; - return getGVNetId(faninId); -} - -//---------------------------------------------------------------------- -// Forward Declarations -//---------------------------------------------------------------------- -class GVRTLDesign; - -//---------------------------------------------------------------------- -// Global Variables -//---------------------------------------------------------------------- -extern GVRTLDesign* gvRTLDesign; - -//---------------------------------------------------------------------- -// Data Structure : yosys -//---------------------------------------------------------------------- -class GVRTLDesign -{ - public: - // Constructors for GV RTL Design Instance - GVRTLDesign() {} - ~GVRTLDesign(); - - // Ntk Reference Functions - RTLIL::Design* getDesign() { return yosys_design; } - - private: -}; - -//---------------------------------------------------------------------- -// Inline Functions -//---------------------------------------------------------------------- - -#endif diff --git a/src/ntk/gvNtkBdd.cpp b/src/ntk/gvNtkBdd.cpp deleted file mode 100644 index dd4ade24..00000000 --- a/src/ntk/gvNtkBdd.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/**************************************************************************** - FileName [ v3NtkBdd.cpp ] - PackageName [ v3/src/ntk ] - Synopsis [ V3 Network to BDDs. ] - Author [ Cheng-Yin Wu ] - Copyright [ Copyright(c) 2012-present LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#ifndef V3_NTK_C -#define V3_NTK_C - -#include "bddMgrV.h" // MODIFICATION FOR SoCV BDD -#include "bddNodeV.h" // MODIFICATION FOR SoCV BDD -#include "gvMsg.h" -#include "gvNtk.h" -#include "stack" -#include "util.h" - -extern BddMgrV* bddMgrV; // MODIFICATION FOR SoCV BDD - -const bool -GVNtkMgr::setBddOrder(const bool& file) { - unsigned supportSize = getInputSize() + getInoutSize() + 2 * getFFSize(); - unsigned bddspsize = bddMgrV->getNumSupports(); - if (supportSize >= bddMgrV->getNumSupports()) { - gvMsg(GV_MSG_ERR) - << "BDD Support Size is Smaller Than Current Design Required !!" - << endl; - return false; - } - // build support - unsigned supportId = 1; - // build PI (primary input) - for (unsigned i = 0, n = getInputSize(); i < n; ++i) { - GVNetId nId = (file) ? getInput(i) : getInput(n - i - 1); - string netName = getNetNameFromId(nId.id); - bddMgrV->addBddNodeV(nId.id, bddMgrV->getSupport(supportId)()); - bddMgrV->addBddNodeV(netName, bddMgrV->getSupport(supportId)()); - cout << " Name : " << netName << "-> Id : " << nId.id << endl; - cout << "Support Id : " << supportId << "\n\n"; - cout << " --- \n"; - ++supportId; - } - // build InOut (Not use) - for (unsigned i = 0, n = getInoutSize(); i < n; ++i) { - const GVNetId& nId = (file) ? getInout(i) : getInout(n - i - 1); - string netName = getNetNameFromId(nId.id); - bddMgrV->addBddNodeV(nId.id, bddMgrV->getSupport(supportId)()); - bddMgrV->addBddNodeV(netName, bddMgrV->getSupport(supportId)()); - ++supportId; - } - // build FF_CS (X: current state) - for (unsigned i = 0, n = getFFSize(); i < n; ++i) { - const GVNetId& nId = (file) ? getFF(i) : getFF(n - i - 1); - string netName = getNetNameFromId(nId.id); - bddMgrV->addBddNodeV(nId.id, bddMgrV->getSupport(supportId)()); - bddMgrV->addBddNodeV(netName, bddMgrV->getSupport(supportId)()); - // cout << " Name : " << netName << "-> Id : " << nId.id << endl; - // cout << "Support Id : " << supportId << "\n\n"; - // cout << " --- \n"; - ++supportId; - } - // build FF_NS (Y: next state) - // here we only create "CS_name + _ns" for y_i - for (unsigned i = 0, n = getFFSize(); i < n; ++i) { - const GVNetId& nId = (file) ? getFF(i) : getFF(n - i - 1); - GVNetId ri = getInputNetId(nId, 0); // get RI - string netName = getNetNameFromId(ri.id); - bddMgrV->addBddNodeV(netName, bddMgrV->getSupport(supportId)()); - ++supportId; - } - // Constants (const0 node, id=0) - for (uint32_t i = 0; i < getConstSize(); ++i) { - assert(getGateType(getConst(i)) == GV_NTK_OBJ_CONST0); - bddMgrV->addBddNodeV(getConst(i).id, BddNodeV::_zero()); - ++supportId; - } - // FF that stores const0 (take as const0 node) - for (uint32_t i = 0; i < getFFConst0Size(); ++i) { - assert(getGateType(getFFConst0(i)) == GV_NTK_OBJ_FF_NS); - bddMgrV->addBddNodeV(getFFConst0(i).id, BddNodeV::_zero()); - bddMgrV->addBddNodeV(getRoIdFromRiId(getFFConst0(i).id), - BddNodeV::_zero()); - ++supportId; - } - - return true; -} - -void -GVNtkMgr::buildNtkBdd() { - // TODO: build BDD for ntk here - // Perform DFS traversal from DFF inputs, inout, and output gates. - // Collect ordered nets to a GVNetVec - // Construct BDDs in the DFS order - - // build PO - stack s; - for (unsigned i = 0; i < getOutputSize(); ++i) { - s.push(getOutput(i)); - } - while (s.size() > 0) { - buildBdd(s.top()); - s.pop(); - } - - // build next state (RI) - for (unsigned i = 0; i < getFFSize(); ++i) { - GVNetId left = getInputNetId(getFF(i), 0); // get RI - if (bddMgrV->getBddNodeV(left.id) == (size_t)0) { - buildBdd(left); - } - BddNodeV ns = ((left.fanin0Cp) ? ~bddMgrV->getBddNodeV(left.id) - : bddMgrV->getBddNodeV(left.id)); - } -} - -void -GVNtkMgr::buildBdd(const GVNetId& netId) { - vector orderedNets; - - orderedNets.clear(); - orderedNets.reserve(getNetSize()); - - // set flag for DFS - newMiscData(); - dfsOrder(netId, orderedNets); - assert(orderedNets.size() <= getNetSize()); - - // TODO: build BDD for the specified net here - GVNetId left, right; - for (unsigned i = 0; i < orderedNets.size(); ++i) { - if (getGateType(orderedNets[i]) == GV_NTK_OBJ_AIG) { - // build fanin0 - left = getInputNetId(orderedNets[i], 0); - // build fanin1 - right = getInputNetId(orderedNets[i], 1); - if (bddMgrV->getBddNodeV(left.id) == (size_t)0) { - buildBdd(left); - } - if (bddMgrV->getBddNodeV(right.id) == (size_t)0) { - buildBdd(right); - } - BddNodeV newNode = - ((orderedNets[i].fanin0Cp) ? ~bddMgrV->getBddNodeV(left.id) - : bddMgrV->getBddNodeV(left.id)) & - ((orderedNets[i].fanin1Cp) ? ~bddMgrV->getBddNodeV(right.id) - : bddMgrV->getBddNodeV(right.id)); - bddMgrV->addBddNodeV(orderedNets[i].id, newNode()); - } - // PO, RI - else if ((getGateType(orderedNets[i]) == GV_NTK_OBJ_FF_NS) || - (getGateType(orderedNets[i]) == GV_NTK_OBJ_PO)) { - GVNetId fanin = getInputNetId(orderedNets[i], 0); - BddNodeV newNode = (orderedNets[i].fanin0Cp) - ? ~bddMgrV->getBddNodeV(fanin.id) - : bddMgrV->getBddNodeV(fanin.id); - bddMgrV->addBddNodeV(orderedNets[i].id, newNode()); - } - } -} - -// Put fanins of a net (id) into a vector (nets) in topological order -void -GVNtkMgr::dfsOrder(const GVNetId& id, vector& nets) { - if (isLatestMiscData(id)) return; - - setLatestMiscData(id); - // traverse fanin logics - const GV_Ntk_Type_t type = getGateType(id); - if ((type == GV_NTK_OBJ_FF_NS) || (type == GV_NTK_OBJ_PO)) { - dfsOrder(getInputNetId(id, 0), nets); - } else if (type == GV_NTK_OBJ_AIG) { - dfsOrder(getInputNetId(id, 0), nets); - dfsOrder(getInputNetId(id, 1), nets); - } - nets.push_back(id); // Record Order -} - -#endif \ No newline at end of file diff --git a/src/ntk/gvNtkCmd.cpp b/src/ntk/gvNtkCmd.cpp deleted file mode 100644 index bcdd35cf..00000000 --- a/src/ntk/gvNtkCmd.cpp +++ /dev/null @@ -1,732 +0,0 @@ -#ifndef GV_NTK_CMD_C -#define GV_NTK_CMD_C - -#include "gvNtkCmd.h" -#include "gvMsg.h" -#include "util.h" -#include -#include -#include - -#include "gvAbcMgr.h" -#include "gvModMgr.h" -#include "gvNtk.h" - -USING_YOSYS_NAMESPACE - -bool -GVinitNtkCmd() { - if (gvNtkMgr) delete gvNtkMgr; - gvNtkMgr = new GVNtkMgr; - return (gvCmdMgr->regCmd("SEt Engine", 2, 1, new GVSetEngineCmd) && - gvCmdMgr->regCmd("REad Design", 2, 1, new GVReadDesignCmd) && - gvCmdMgr->regCmd("PRint Info", 2, 1, new GVPrintInfoCmd) && - gvCmdMgr->regCmd("FILE2 Aig", 4, 1, new GVFile2AigCmd) && - gvCmdMgr->regCmd("YOSYSCMD", 8, new GVYosysOriginalCmd) && - gvCmdMgr->regCmd("FILE2 BLIF", 4, 4, new GVFile2BlifCmd) && - gvCmdMgr->regCmd("WRite Aig", 2, 1, new GVWriteAigCmd) && - gvCmdMgr->regCmd("BLAst NTK", 3, 3, new GVBlastNtkCmd) && - gvCmdMgr->regCmd("PRInt Aig", 3, 1, new GVPrintAigCmd)); -} - -//---------------------------------------------------------------------- -// SEt Engine <(string engineName)> -//---------------------------------------------------------------------- - -GVCmdExecStatus -GVSetEngineCmd ::exec(const string& option) { - gvMsg(GV_MSG_IFO) << "I am GVSetEngineCmd" << endl; - - vector options; - GVCmdExec::lexOptions(option, options); - size_t n = options.size(); - - bool engABC = false, engYOSYS = false; - // try to match engine names - if (n == 0) - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, - "<(string engineName)>"); - else { - for (size_t i = 0; i < n; ++i) { - const string& token = options[i]; - if (myStrNCmp("yosys", token, 1) == 0) { - if (engABC | engYOSYS) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - engYOSYS = true; - continue; - } else if (myStrNCmp("abc", token, 1) == 0) { - if (engABC | engYOSYS) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - engABC = true; - continue; - } else { - if (!engABC && !engYOSYS) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); - } - } - } - - // set current engine - if (engYOSYS) gvModMgr->setGVEngine(GV_MOD_ENGINE_YOSYS); - else if (engABC) gvModMgr->setGVEngine(GV_MOD_ENGINE_ABC); - - // print the successful message - int engPos = gvModMgr->getGVEngine(); - string engNameList[2] = {"yosys", "abc"}; - cout << "Set Engine \"" << engNameList[engPos] << "\" Success !!" << endl; - return GV_CMD_EXEC_DONE; -} - -void -GVSetEngineCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: SEt Engine <(string engineName)> " << endl; - gvMsg(GV_MSG_IFO) << "Param: <(string engineName)> : Name of the engine. " - "<(yosys) | (abc)>" - << endl; -} - -void -GVSetEngineCmd::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "SEt Engine: " - << "Set the specific engine to parse the design." << endl; -} - -//---------------------------------------------------------------------- -// REad Design <-Verilog | -Blif | -Aig | -btor> <(string fileName)> -//---------------------------------------------------------------------- - -GVCmdExecStatus -GVReadDesignCmd ::exec(const string& option) { - - // check option - vector options; - GVCmdExec::lexOptions(option, options); - - bool fileVerilog = false, fileBlif = false, fileAig = false, - fileBtor = false; - size_t n = options.size(); - string filename, topName; - - // try to match file type options - if (n == 0) fileVerilog = true; - else { - for (size_t i = 0; i < n; ++i) { - const string& token = options[i]; - if (myStrNCmp("-Verilog", token, 2) == 0) { - if (fileVerilog | fileBlif | fileAig | fileBtor) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - fileVerilog = true; - continue; - } else if (myStrNCmp("-Blif", token, 3) == 0) { - if (fileVerilog | fileBlif | fileAig | fileBtor) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - fileBlif = true; - continue; - } else if (myStrNCmp("-Aig", token, 2) == 0) { - if (fileVerilog | fileBlif | fileAig | fileBtor) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - fileAig = true; - continue; - } else if (myStrNCmp("-Btor", token, 3) == 0) { - if (fileVerilog | fileBlif | fileAig | fileBtor) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - fileBtor = true; - continue; - } else { - if (!fileVerilog && !fileBlif && !fileAig && !fileBtor) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); - - if (filename == "") filename = token; - else return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - continue; - } - } - } - // check filename - if (filename == "") - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, - "<(string filename)>"); - - // check file extension - if (fileVerilog) { - gvNtkMgr->setFileType(GV_NTK_TYPE_V); - string fileExt = filename.substr(filename.size() - 2, 2); - if (fileExt != ".v") - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, filename); - } else if (fileBlif) { - gvNtkMgr->setFileType(GV_NTK_TYPE_BLIF); - string fileExt = filename.substr(filename.size() - 5, 5); - if (fileExt != ".blif") - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, filename); - } else if (fileAig) { - gvNtkMgr->setFileType(GV_NTK_TYPE_AIG); - string fileExt = filename.substr(filename.size() - 4, 4); - if (fileExt != ".aig") - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, filename); - // set the aig file name - gvModMgr->setAigFileName(filename); - } else if (fileBtor) { - gvNtkMgr->setFileType(GV_NTK_TYPE_BTOR); - string fileExt = filename.substr(filename.size() - 5, 5); - if (fileExt != ".btor") - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, filename); - } - - // print the input file name - cout << "\nfile name: " << filename << "\n"; - - // set input file name to Mode manager - gvModMgr->setInputFileName(filename); - gvModMgr->setInputFileExist(true); - GVModEngine currEng = gvModMgr->getGVEngine(); - - // read design - if (currEng == GV_MOD_ENGINE_YOSYS) { - if (fileAig | fileBtor) { - gvMsg(GV_MSG_IFO) << "[ERROR]: Engine yosys doesn't support aig " - "file and btor file !!" - << endl; - return GV_CMD_EXEC_NOP; - } - string yosCommand = ""; - if (fileVerilog) yosCommand += "read_verilog -sv "; - else if (fileBlif) yosCommand += "read_blif "; - run_pass(yosCommand + filename); - run_pass("hierarchy -auto-top"); - if (gvRTLDesign->getDesign()->top_module()->name.str() != "") { - topName = gvRTLDesign->getDesign()->top_module()->name.str(); - gvModMgr->setTopModuleName(topName); - } - } else if (currEng == GV_MOD_ENGINE_ABC) { - abcMgr->abcReadDesign(filename); - } - - return GV_CMD_EXEC_DONE; -} - -void -GVReadDesignCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) - << "Usage: REad Design <-Verilog | -Blif | -Aig> <(string fileName)> " - << endl; -} - -void -GVReadDesignCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "REad Design: " - << "Read the Design." << endl; -} - -//---------------------------------------------------------------------- -// PRint Info [-Verbose] -//---------------------------------------------------------------------- - -GVCmdExecStatus -GVPrintInfoCmd ::exec(const string& option) { - gvMsg(GV_MSG_IFO) << "I am GVPrintInfoCmd" << endl; - - int numFF = 0, numPI = 0, numPO = 0, numPIO = 0, numConst = 0, numNet = 0; - int numMux = 0, numAnd = 0, numAdd = 0, numSub = 0, numMul = 0, numEq = 0, - numNot = 0, numLe = 0, numGe = 0; - bool verbose = false; - - // check options - vector options; - GVCmdExec::lexOptions(option, options); - size_t n = options.size(); - - // try to match options - for (size_t i = 0; i < n; ++i) { - const string& token = options[i]; - if (myStrNCmp("-Verbose", token, 2) == 0) { - verbose = true; - continue; - } else { - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); - } - } - - // print info - GVModEngine currEng = gvModMgr->getGVEngine(); - if (currEng == GV_MOD_ENGINE_YOSYS) { - gvMsg(GV_MSG_IFO) << "Modules in current design: "; - string moduleName = gvRTLDesign->getDesign()->top_module()->name.str(); - cout << moduleName << "(" - << GetSize(gvRTLDesign->getDesign()->top_module()->wires()) - << " wires, " - << GetSize(gvRTLDesign->getDesign()->top_module()->cells()) - << " cells)\n"; - for (auto wire : gvRTLDesign->getDesign()->top_module()->wires()) { - // string wire_name = log_id(wire->name); - if (wire->port_input) numPI++; - else if (wire->port_output) numPO++; - } - if (verbose) { - for (auto cell : gvRTLDesign->getDesign()->top_module()->cells()) { - if (cell->type.in(ID($mux))) numMux++; - else if (cell->type.in(ID($logic_and))) numAnd++; - else if (cell->type.in(ID($add))) numAdd++; - else if (cell->type.in(ID($sub))) numSub++; - else if (cell->type.in(ID($mul))) numMul++; - else if (cell->type.in(ID($eq))) numEq++; - else if (cell->type.in(ID($logic_not))) numNot++; - else if (cell->type.in(ID($lt))) numLe++; - else if (cell->type.in(ID($ge))) numGe++; - } - gvMsg(GV_MSG_IFO) - << "==================================================\n"; - gvMsg(GV_MSG_IFO) << " MUX" << setw(40) << numMux << "\n"; - gvMsg(GV_MSG_IFO) << " AND" << setw(40) << numAnd << "\n"; - gvMsg(GV_MSG_IFO) << " ADD" << setw(40) << numAdd << "\n"; - gvMsg(GV_MSG_IFO) << " SUB" << setw(40) << numSub << "\n"; - gvMsg(GV_MSG_IFO) << " MUL" << setw(40) << numMul << "\n"; - gvMsg(GV_MSG_IFO) << " EQ" << setw(41) << numEq << "\n"; - gvMsg(GV_MSG_IFO) << " NOT" << setw(40) << numNot << "\n"; - gvMsg(GV_MSG_IFO) << " LT" << setw(41) << numLe << "\n"; - gvMsg(GV_MSG_IFO) << " GE" << setw(41) << numGe << "\n"; - gvMsg(GV_MSG_IFO) - << "--------------------------------------------------\n"; - gvMsg(GV_MSG_IFO) << " PI" << setw(41) << numPI << "\n"; - gvMsg(GV_MSG_IFO) << " PO" << setw(41) << numPO << "\n"; - gvMsg(GV_MSG_IFO) - << "==================================================\n"; - } else - gvMsg(GV_MSG_IFO) << "#PI = " << numPI << ", #PO = " << numPO - << ", #PIO = " << numPIO << "\n"; - } else if (currEng == GV_MOD_ENGINE_ABC) { - (abcMgr->get_abcNtkMgr())->printSummary(); - return GV_CMD_EXEC_DONE; - } - return GV_CMD_EXEC_DONE; -} - -void -GVPrintInfoCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: PRint Info [-Verbose]" << endl; -} - -void -GVPrintInfoCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "PRint Info: " - << "Print circuit information extracted by our parser." - << endl; -} - -//------------------------------------------------------------------------------------------------------- -// FILE2 Aig < [-Verilog | -Blif] > -Input -TOP -// -Output .aig -//------------------------------------------------------------------------------------------------------- - -GVCmdExecStatus -GVFile2AigCmd ::exec(const string& option) { - gvMsg(GV_MSG_IFO) << "I am GVFile2AigCmd" << endl; - - string inname, topname, outname; - bool preInfile = false, preTop = false; - bool fileVerilog = false, fileBlif = false; - bool hasInfile = false, hasTop = false, hasOutfile = false; - - // filename exists - if (gvModMgr->getInputFileExist()) { - // input file - inname = gvModMgr->getInputFileName(); - preInfile = true; - hasInfile = true; - // top module - if (gvModMgr->getTopModuleName() != "") { - topname = gvModMgr->getTopModuleName(); - preTop = true; - hasTop = true; - } - } - - vector options; - GVCmdExec::lexOptions(option, options); - size_t n = options.size(); - - for (size_t i = 0; i < n; ++i) { - const string& token = options[i]; - if (myStrNCmp("-Verilog", token, 2) == 0) { - if (fileVerilog | fileBlif) { - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - } - fileVerilog = true; - continue; - } else if (myStrNCmp("-Blif", token, 3) == 0) { - if (fileVerilog | fileBlif) { - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - } - fileBlif = true; - continue; - } else if ((!preInfile) && (myStrNCmp("-Input", token, 2) == 0)) { - // if no specify filename - if ((i + 1) >= n) { - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, token); - } else { - inname = options[i + 1]; - ++i; - } - gvModMgr->setInputFileName(inname); - gvModMgr->setInputFileExist(true); - hasInfile = true; - continue; - } else if ((!preTop) && (myStrNCmp("-TOP", token, 4) == 0)) { - // if no specify top module - if ((i + 1) >= n) { - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, token); - } else { - topname = options[i + 1]; - ++i; - } - gvModMgr->setTopModuleName(topname); - hasTop = true; - continue; - } else if (myStrNCmp("-Output", token, 2) == 0) { - // if no specify filename - if ((i + 1) >= n) { - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, token); - } else if (strncmp(options[i + 1] - .substr(options[i + 1].length() - 4, - options[i + 1].length()) - .c_str(), - ".aig", 4)) { - cout << "[ERROR]: Please output an \"AIG\" file " - "(.aig) !" - << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); - } else { - outname = options[i + 1]; - ++i; - } - hasOutfile = true; - continue; - } - } - - // command - string readCmd, topCmd, outCmd; - - if (!fileVerilog && !fileBlif) { - cout << "[ERROR]: Please specify input file format (-Verilog | -Blif) !" - << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, "FILE2 Aig"); - } else if (!hasInfile || !hasOutfile) { - cout << "[ERROR]: Please specify the file options !" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, "FILE2 Aig"); - } else if (fileVerilog) { - if (!hasTop) { - cout << "[ERROR]: Please specify the top module name options !" - << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, "FILE2 Aig"); - } - if (!preTop) { - readCmd = "read_verilog -sv " + inname; - } - } else if (fileBlif) { - readCmd = "read_blif " + inname; - } - topCmd = "synth -flatten -top " + topname; - outCmd = "write_aiger -symbols " + outname; - - run_pass(readCmd); - run_pass(topCmd); - run_pass("dffunmap"); - run_pass("abc -g AND"); - run_pass(outCmd); - - return GV_CMD_EXEC_DONE; -} - -void -GVFile2AigCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) - << "Usage: FILE2 Aig <[-Verilog|-Blif]> -Input -TOP " - " -Output .aig " - << endl; -} - -void -GVFile2AigCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "File2 Aig: " - << "Convert verilog file into AIG. " << endl; -} - -//---------------------------------------------------------------------- -// YOSYSCMD -//---------------------------------------------------------------------- - -GVCmdExecStatus -GVYosysOriginalCmd ::exec(const string& option) { - vector options; - GVCmdExec::lexOptions(option, options); - size_t n = options.size(); - string command; - for (size_t i = 0; i < n; ++i) { - command += options[i]; - if (i < n - 1) { - command += " "; - } - } - // calling Yosys's command - if ((yosys_design->top_module() == NULL) && - (myStrNCmp("READ", command, 4)) == 0) { - cout << "Error: Please read in a design first !" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, command); - } - - run_pass(command); - return GV_CMD_EXEC_DONE; -} - -void -GVYosysOriginalCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: YOSYSCMD " << endl; -} - -void -GVYosysOriginalCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "YosysCMD: " - << "Directly call Yosys's command." << endl; -} - -//---------------------------------------------------------------------- -// FILE2 Blif -//---------------------------------------------------------------------- -GVCmdExecStatus -GVFile2BlifCmd::exec(const string& option) { - gvMsg(GV_MSG_IFO) << "Create Blif from RTL " << endl; - - // gvMsg(GV_MSG_IFO) << "I am GVFile2AigCmd" << endl; - vector options; - GVCmdExec::lexOptions(option, options); - size_t n = options.size(); - if (n != 2) cout << "wrong arg number\n"; - string top = options[0]; - string outputf = options[1]; - cout << "top = " << top << " outputf = " << outputf << endl; - string command; - command = "hierarchy -top "; - command += top; - run_pass(command); - command = "hierarchy -check"; - run_pass(command); - command = "proc"; - run_pass(command); - command = "opt"; - run_pass(command); - command = "opt_expr -mux_undef"; - run_pass(command); - command = "opt"; - run_pass(command); - command = "rename -hide"; - run_pass(command); - command = "opt"; - run_pass(command); - command = "memory_collect"; - run_pass(command); - command = "flatten"; - run_pass(command); - command = "memory_unpack"; - run_pass(command); - command = "splitnets -driver"; - run_pass(command); - command = "setundef -zero -undriven"; - run_pass(command); - command = "dffunmap"; - run_pass(command); - command = "opt -fast -noff"; - run_pass(command); - command = "write_blif "; - command += outputf; - run_pass(command); - - return GV_CMD_EXEC_DONE; -} - -void -GVFile2BlifCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) - << "Usage: FILE2 Blif " - << endl; -} - -void -GVFile2BlifCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "File2 Blif: " - << "Convert verilog file into blif. " << endl; -} - -//---------------------------------------------------------------------- -// Write Aig -//---------------------------------------------------------------------- -GVCmdExecStatus -GVWriteAigCmd::exec(const string& option) { - - if (!gvRTLDesign->getDesign() || - gvRTLDesign->getDesign()->top_module() == NULL) { - gvMsg(GV_MSG_ERR) << "Empty design. Try command \"FILE2 AIG\"." << endl; - return GV_CMD_EXEC_ERROR; - } - - vector options; - GVCmdExec::lexOptions(option, options); - - if (options.size() > 1) { - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[1]); - } - - if (options.size() == 0) { - if (gvModMgr->getAigFileName() == "") { - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, "AIG filename"); - } - } - - else { - gvModMgr->setAigFileName(options[0]); - } - - string filename = options[0]; - - run_pass("synth -flatten -top " + gvModMgr->getTopModuleName()); - run_pass("dffunmap"); - run_pass("abc -g AND"); - run_pass("write_aiger -symbols " + filename); - - return GV_CMD_EXEC_DONE; -} - -void -GVWriteAigCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: WRite Aig " << endl; - gvMsg(GV_MSG_IFO) - << "Param: <(string filename)> : Name of the output aig file." - << endl; - gvMsg(GV_MSG_IFO) << " It could be , " - "or it can be skipped if specified before." - << endl; -} - -void -GVWriteAigCmd::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "WRite aig: " - << "Write out the processing design into AIGER file" - << endl; -} - -//---------------------------------------------------------------------- -// BLAst NTK (convert network to AIG) -//---------------------------------------------------------------------- - -GVCmdExecStatus -GVBlastNtkCmd ::exec(const string& option) { - vector options; - GVCmdExec::lexOptions(option, options); - size_t n = options.size(); - char* pFileName = new char[50]; // the file name is within 50 characters - - if (n > 0) { - gvMsg(GV_MSG_ERR) << "Usage: BLAst NTK" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, option); - } - // filename exists - if (gvModMgr->getInputFileExist()) { - strcpy(pFileName, gvModMgr->getInputFileName().c_str()); - } else { - gvMsg(GV_MSG_ERR) << "Error: Please read in a design first !" << endl; - return GV_CMD_EXEC_ERROR; - } - - // create the PI, PO and FF mapping - if(gvNtkMgr->getFileType() == GV_NTK_TYPE_V) { - run_pass("hierarchy -auto-top; flatten; proc; techmap; setundef -zero; " - "aigmap; write_aiger -map .map.txt ._temp_.aig"); - } - else if(gvNtkMgr->getFileType() == GV_NTK_TYPE_AIG) { - run_pass("read_aiger " + gvModMgr->getInputFileName() + "; flatten; proc; techmap; setundef -zero; " - "aigmap; write_aiger -map .map.txt ._temp_.aig"); - } - - // construct GV network - gvNtkMgr->createNetFromAbc(pFileName); - - // BSETOrder - // cout << "TEST : Start to build BDD : \n"; - // gvNtkMgr->setBddOrder(true); - - return GV_CMD_EXEC_DONE; -} - -void -GVBlastNtkCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: BLAst NTK" << endl; -} - -void -GVBlastNtkCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "BLAst NTK: " - << "Convert network to AIG." << endl; -} - -//---------------------------------------------------------------------- -// PRInt Aig (print the aig information) -//---------------------------------------------------------------------- -GVCmdExecStatus -GVPrintAigCmd ::exec(const string& option) { - vector options; - GVCmdExec::lexOptions(option, options); - size_t n = options.size(); - bool printPi = false, printPo = false, printRi = false, - printSummary = false; - - if (gvNtkMgr->getInputSize() == 0) { - gvMsg(GV_MSG_ERR) << "Please BLAst NTK first !" << endl; - return GV_CMD_EXEC_ERROR; - } - - if (n == 0) { - gvMsg(GV_MSG_ERR) - << "Usage: PRInt Aig <-PI | -PO | -RI | -RO | -Summary>" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, option); - } else { - for (size_t i = 0; i < n; ++i) { - const string& token = options[i]; - if (myStrNCmp("-PI", token, 3) == 0) { - printPi = true; - continue; - } else if (myStrNCmp("-PO", token, 3) == 0) { - printPo = true; - continue; - } else if (myStrNCmp("-RI", token, 3) == 0) { - printRi = true; - continue; - } else if (myStrNCmp("-Summary", token, 2) == 0) { - printSummary = true; - continue; - } else { - if (!printPi && !printPo && !printRi && !printSummary) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); - } - } - } - - if (printPi) gvNtkMgr->printPi(); - if (printPo) gvNtkMgr->printPo(); - if (printRi) gvNtkMgr->printRi(); - if (printSummary) gvNtkMgr->printSummary(); - - return GV_CMD_EXEC_DONE; -} - -void -GVPrintAigCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: PRInt Aig <-PI | -PO | -RI | -RO | -Summary>" - << endl; -} - -void -GVPrintAigCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "PRInt Aig: " - << "Print the aig network information." << endl; -} - -#endif diff --git a/src/ntk/gvNtkCmd.h b/src/ntk/gvNtkCmd.h deleted file mode 100644 index 2edc57ea..00000000 --- a/src/ntk/gvNtkCmd.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef GV_NTK_CMD_H -#define GV_NTK_CMD_H - -#include "gvCmdMgr.h" - -GV_COMMAND(GVSetEngineCmd, GV_CMD_TYPE_NETWORK); -GV_COMMAND(GVReadDesignCmd, GV_CMD_TYPE_NETWORK); -GV_COMMAND(GVPrintInfoCmd, GV_CMD_TYPE_NETWORK); -GV_COMMAND(GVFile2AigCmd, GV_CMD_TYPE_NETWORK); -GV_COMMAND(GVYosysOriginalCmd, GV_CMD_TYPE_NETWORK); -GV_COMMAND(GVFile2BlifCmd, GV_CMD_TYPE_NETWORK); -GV_COMMAND(GVWriteAigCmd, GV_CMD_TYPE_NETWORK); -GV_COMMAND(GVBlastNtkCmd, GV_CMD_TYPE_NETWORK); -GV_COMMAND(GVPrintAigCmd, GV_CMD_TYPE_NETWORK); - -#endif \ No newline at end of file diff --git a/src/prove/.depend.mak b/src/prove/.depend.mak deleted file mode 100644 index 4cd432ae..00000000 --- a/src/prove/.depend.mak +++ /dev/null @@ -1,67 +0,0 @@ -proveBdd.o: proveBdd.cpp ../../include/bddMgrV.h ../../include/myHash.h \ - ../../include/bddNodeV.h ../../include/gvMsg.h ../../include/gvNtk.h \ - ../../include/gvAbcMgr.h ../../include/base/abc/abc.h \ - ../../include/misc/vec/vec.h ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/abc/abc.h \ - ../../include/base/main/abcapis.h ../../include/base/cmd/cmd.h \ - ../../include/base/io/ioAbc.h ../../include/misc/util/utilNam.h \ - ../../include/base/main/mainInt.h ../../include/base/main/main.h \ - ../../include/misc/tim/tim.h ../../include/map/if/if.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/util/utilTruth.h \ - ../../include/opt/dau/dau.h ../../include/misc/vec/vecHash.h \ - ../../include/aig/aig/aig.h ../../include/proof/ssw/ssw.h \ - ../../include/proof/fra/fra.h ../../include/opt/dar/dar.h \ - ../../include/sat/bsat/satSolver.h ../../include/sat/bsat/satVec.h \ - ../../include/sat/bsat/satClause.h ../../include/misc/util/utilDouble.h \ - ../../include/aig/ioa/ioa.h ../../include/gvAbcNtk.h \ - ../../include/kernel/sigtools.h ../../include/kernel/yosys.h \ - /usr/include/tcl8.6/tcl.h /usr/include/tcl8.6/tclDecls.h \ - /usr/include/tcl8.6/tclPlatDecls.h ../../include/kernel/hashlib.h \ - ../../include/kernel/log.h ../../include/kernel/rtlil.h \ - ../../include/kernel/constids.inc ../../include/kernel/register.h \ - ../../include/kernel/utils.h ../../include/kernel/yosys.h \ - ../../include/util.h ../../include/rnGen.h ../../include/myUsage.h -proveCmd.o: proveCmd.cpp proveCmd.h ../../include/gvCmdMgr.h \ - ../../include/bddMgrV.h ../../include/myHash.h ../../include/bddNodeV.h \ - ../../include/gvMsg.h ../../include/gvNtk.h ../../include/gvAbcMgr.h \ - ../../include/base/abc/abc.h ../../include/misc/vec/vec.h \ - ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/abc/abc.h \ - ../../include/base/main/abcapis.h ../../include/base/cmd/cmd.h \ - ../../include/base/io/ioAbc.h ../../include/misc/util/utilNam.h \ - ../../include/base/main/mainInt.h ../../include/base/main/main.h \ - ../../include/misc/tim/tim.h ../../include/map/if/if.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/util/utilTruth.h \ - ../../include/opt/dau/dau.h ../../include/misc/vec/vecHash.h \ - ../../include/aig/aig/aig.h ../../include/proof/ssw/ssw.h \ - ../../include/proof/fra/fra.h ../../include/opt/dar/dar.h \ - ../../include/sat/bsat/satSolver.h ../../include/sat/bsat/satVec.h \ - ../../include/sat/bsat/satClause.h ../../include/misc/util/utilDouble.h \ - ../../include/aig/ioa/ioa.h ../../include/gvAbcNtk.h \ - ../../include/kernel/sigtools.h ../../include/kernel/yosys.h \ - /usr/include/tcl8.6/tcl.h /usr/include/tcl8.6/tclDecls.h \ - /usr/include/tcl8.6/tclPlatDecls.h ../../include/kernel/hashlib.h \ - ../../include/kernel/log.h ../../include/kernel/rtlil.h \ - ../../include/kernel/constids.inc ../../include/kernel/register.h \ - ../../include/kernel/utils.h ../../include/kernel/yosys.h \ - ../../include/util.h ../../include/rnGen.h ../../include/myUsage.h diff --git a/src/prove/.extheader.mak b/src/prove/.extheader.mak deleted file mode 100644 index c81d4d82..00000000 --- a/src/prove/.extheader.mak +++ /dev/null @@ -1 +0,0 @@ -prove.d: diff --git a/src/prove/.map.txt b/src/prove/.map.txt deleted file mode 100644 index a247120e..00000000 --- a/src/prove/.map.txt +++ /dev/null @@ -1,23 +0,0 @@ -input 0 0 reset -input 1 0 clk -output 0 0 z1 -output 1 0 z2 -output 2 0 z3 -output 3 0 z4 -output 4 0 z5 -latch 0 0 x -latch 1 1 x -latch 2 2 x -latch 3 3 x -latch 4 4 x -latch 5 5 x -latch 6 6 x -latch 7 7 x -latch 8 0 y -latch 9 1 y -latch 10 2 y -latch 11 3 y -latch 12 4 y -latch 13 5 y -latch 14 6 y -latch 15 7 y diff --git a/src/prove/Makefile b/src/prove/Makefile deleted file mode 100644 index 88057a87..00000000 --- a/src/prove/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -PKGFLAG = -EXTHDRS = - -include ../Makefile.in -include ../Makefile.lib diff --git a/src/prove/proveBdd.cpp b/src/prove/proveBdd.cpp deleted file mode 100644 index 697a5197..00000000 --- a/src/prove/proveBdd.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/**************************************************************************** - FileName [ proveBdd.cpp ] - PackageName [ prove ] - Synopsis [ For BDD-based verification ] - Author [ ] - Copyright [ Copyleft(c) 2010-present LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#include "bddMgrV.h" -#include "gvMsg.h" -#include "gvNtk.h" -#include "util.h" -#include -#include -#include - -void -BddMgrV::buildPInitialState() { - // TODO : remember to set _initState - // set initial state to all zero - BddNodeV newNode; - for (unsigned i = 0; i < gvNtkMgr->getFFSize(); ++i) { - if (i == 0) { - newNode = ite(bddMgrV->getBddNodeV(gvNtkMgr->getFF(i).id), - BddNodeV::_zero, BddNodeV::_one); - } else { - newNode = ite(bddMgrV->getBddNodeV(gvNtkMgr->getFF(i).id), - BddNodeV::_zero, newNode); - } - } - _initState = newNode; - _reachStates.clear(); - _reachStates.push_back(_initState); -} - -void -BddMgrV::buildPTransRelation() { - // TODO : remember to set _tr, _tri - - BddNodeV delta, y; - GVNetId delta_net; - - // build _tri - for (unsigned i = 0; i < gvNtkMgr->getFFSize(); ++i) { - // next state (y)'s name - string nsStr = gvNtkMgr->getNetNameFromId( - gvNtkMgr->getInputNetId(gvNtkMgr->getFF(i), 0).id); - // get BDD by name - y = bddMgrV->getBddNodeV(nsStr); - delta = bddMgrV->getBddNodeV( - gvNtkMgr->getInputNetId(gvNtkMgr->getFF(i), 0).id); - delta_net = gvNtkMgr->getInputNetId(gvNtkMgr->getFF(i), 0); - if (bddMgrV->getBddNodeV(delta_net.id) == (size_t)0) { - gvNtkMgr->buildBdd(delta_net); - } - // build _tri - if (i == 0) { - _tri = ~(y ^ delta); - } else { - _tri = _tri & ~(y ^ delta); - } - } - - // build _tr - _tr = _tri; - for (unsigned i = 0; i < gvNtkMgr->getInputSize(); ++i) { - _tr = _tr.exist(gvNtkMgr->getInput(i).id); - } - for (unsigned i = 0; i < gvNtkMgr->getInoutSize(); ++i) { - _tr = _tr.exist(gvNtkMgr->getInout(i).id); - } -} - -BddNodeV BddMgrV::restrict(const BddNodeV& f, const BddNodeV& g) { - if (g == BddNodeV::_zero) { - cerr << "Error in restrict!!" << endl; - } - if (g == BddNodeV::_one) { - return f; - } - if (f == BddNodeV::_zero || f == BddNodeV::_one) { - return f; - } - unsigned a = g.getLevel(); - if (g.getLeftCofactor(a) == BddNodeV::_zero) { - return restrict(f.getRightCofactor(a), g.getRightCofactor(a)); - } - if (g.getRightCofactor(a) == BddNodeV::_zero) { - return restrict(f.getLeftCofactor(a), g.getLeftCofactor(a)); - } - if (f.getLeftCofactor(a) == f.getRightCofactor(a)) { - return restrict(f, g.getLeftCofactor(a) | g.getRightCofactor(a)); - } - BddNodeV newNode = - (~getSupport(a)& restrict(f.getRightCofactor(a), - g.getRightCofactor(a))) | - (getSupport(a)& restrict(f.getLeftCofactor(a), g.getLeftCofactor(a))); - return newNode; -} - -void -BddMgrV::buildPImage(int level) { - // TODO : remember to add _reachStates and set _isFixed - // note:: _reachStates record the set of reachable states - BddNodeV cube, ns; - bool isMoved; - _isFixed = false; - for (unsigned i = 0; i < level; ++i) { - if (_isFixed) { - cout << "Fixed point is reached (time : " << _reachStates.size() - 1 - << ")" << endl; - break; - } - // build next state - if (_reachStates.size() == 1) { - ns = _tr & _initState; - } else { - ns = _tr& restrict(_reachStates[_reachStates.size() - 1], - (~_reachStates[_reachStates.size() - 2])); - } - // existential - for (unsigned j = 0; j < gvNtkMgr->getFFSize(); ++j) { - ns = ns.exist(gvNtkMgr->getFF(j).id); - } - ns = ns.nodeMove(gvNtkMgr->getFF(0).id + gvNtkMgr->getFFSize(), - gvNtkMgr->getFF(0).id, isMoved); - // isFixed ? - if (_reachStates.size() == 0) { - ns = ns | _initState; - if (ns == _initState) { - _isFixed = true; - cout << "Fixed point is reached (time : " - << _reachStates.size() - 1 << ")" << endl; - break; - } - } else { - ns = ns | _reachStates.back(); - if (ns == _reachStates.back()) { - _isFixed = true; - cout << "Fixed point is reached (time : " - << _reachStates.size() - 1 << ")" << endl; - break; - } - } - _reachStates.push_back(ns); - } -} - -void -BddMgrV::runPCheckProperty(const string& name, BddNodeV monitor) { - // TODO : prove the correctness of AG(~monitor) - BddNodeV result, cs, ns, test; - bool isMoved; - int numofstate = _reachStates.size() - 1; - vector> counter_ex; - vector timeframe; - - ns = monitor & _reachStates.back(); - if (ns != BddNodeV::_zero) { - // ~p can backtrace to init state ? - while ((monitor & _reachStates[numofstate]).countCube() != 0) { - if(numofstate == 0) break; - numofstate--; - } - if(numofstate != 0) - numofstate++; - //cout << "This is reachable state : \n" << _reachStates[numofstate]; - //cout << "This is monitor : \n" << monitor; - ns = monitor & _reachStates[numofstate]; - - //cout << "Monitor \"" << name << "\" is violated." << endl; - //cout << "Counter Example:" << endl; - - ns = ns.getCube(0); - counter_ex.clear(); - /* === MODIFICATION FOR PROPERTY 0 IN c.v === */ - if(numofstate == 0 ){ - BddNodeV firstState = ns; - for (unsigned j = 0; j < gvNtkMgr->getFFSize(); ++j) { - firstState = firstState.exist(gvNtkMgr->getFF(j).id); - } - for (unsigned j = 0; j < gvNtkMgr->getInputSize(); ++j) { - if (firstState.getLeft() != BddNodeV::_zero){ - if(firstState.isNegEdge()) timeframe.push_back(0); - else timeframe.push_back(1); - } - else if (firstState.getRight() != BddNodeV::_zero){ - if(firstState.isNegEdge()) timeframe.push_back(1); - else timeframe.push_back(0); - } - } - counter_ex.push_back(timeframe); - //cout << firstState << endl; - //cout << firstState.toString(); - } - /* === END OF MODIFICATION === */ - timeframe.clear(); - - for (unsigned i = 0; i < numofstate; ++i) { - // find legal current state - ns = ns.nodeMove(gvNtkMgr->getFF(0).id, - gvNtkMgr->getFF(0).id + gvNtkMgr->getFFSize(), - isMoved); - ns = _tri & ns & _reachStates[numofstate - 1 - i]; - for (unsigned j = 0; j < gvNtkMgr->getFFSize(); ++j) { - ns = ns.exist(gvNtkMgr->getFF(j).id + gvNtkMgr->getFFSize()); - } - - // find valid input value - for (unsigned j = 0; j < gvNtkMgr->getInputSize(); ++j) { - if (ns.getLeftCofactor(gvNtkMgr->getInput(j).id) != - BddNodeV::_zero) { - ns = ns.getLeftCofactor(gvNtkMgr->getInput(j).id); - timeframe.push_back(1); - } else if (ns.getRightCofactor(gvNtkMgr->getInput(j).id) != - BddNodeV::_zero) { - ns = ns.getRightCofactor(gvNtkMgr->getInput(j).id); - timeframe.push_back(0); - } else { - cerr << "error in monitor" << endl; - } - } - counter_ex.push_back(timeframe); - timeframe.clear(); - } - for (unsigned i = 0; i < counter_ex.size(); ++i) { - cout << i << ": "; - for (unsigned j = 0; j < gvNtkMgr->getInputSize(); ++j) { - cout << counter_ex[counter_ex.size() - 1 - i][j]; - } - cout << endl; - } - } else { - if (_isFixed) { - cout << "Monitor \"" << name << "\" is safe." << endl; - } else { - cout << "Monitor \"" << name << "\" is safe up to time " - << _reachStates.size() - 1 << "." << endl; - } - } -} - -BddNodeV -BddMgrV::find_ns(BddNodeV cs) {} - -BddNodeV -BddMgrV::ns_to_cs(BddNodeV ns) {} diff --git a/src/prove/proveCmd.cpp b/src/prove/proveCmd.cpp deleted file mode 100644 index 3e61c7fd..00000000 --- a/src/prove/proveCmd.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/**************************************************************************** - FileName [ proveCmd.cpp ] - PackageName [ prove ] - Synopsis [ Define basic prove package commands ] - Author [ ] - Copyright [ Copyleft(c) 2010-present LaDs(III), GIEE, NTU, Taiwan ] - ****************************************************************************/ - -#include "proveCmd.h" -#include "bddMgrV.h" -#include "gvMsg.h" -#include "gvNtk.h" -#include "util.h" -#include -#include - -using namespace std; - -bool -GVinitProveCmd() { - return (gvCmdMgr->regCmd("PINITialstate", 5, new PInitialStateCmd) && - gvCmdMgr->regCmd("PTRansrelation", 3, new PTransRelationCmd) && - gvCmdMgr->regCmd("PIMAGe", 5, new PImageCmd) && - gvCmdMgr->regCmd("PCHECKProperty", 7, new PCheckPropertyCmd)); -} - -extern BddNodeV getBddNodeV(const string& bddName); - -//---------------------------------------------------------------------- -// PINITialstate [(string varName)] -//---------------------------------------------------------------------- -GVCmdExecStatus -PInitialStateCmd::exec(const string& option) { - vector options; - GVCmdExec::lexOptions(option, options); - if (options.size() > 1) { - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[1]); - } - string token = ""; - if (options.size()) { - if (!isValidVarName(options[0])) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); - else token = options[0]; - } - - bddMgrV->buildPInitialState(); - if (!token.empty() && - !bddMgrV->addBddNodeV(token, bddMgrV->getPInitState()())) { - gvMsg(GV_MSG_ERR) - << "\"" << token - << "\" has Already been Associated With Another BddNode!!" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, token); - } - return GV_CMD_EXEC_DONE; -} - -void -PInitialStateCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: PINITialstate [(string varName)]" << endl; -} - -void -PInitialStateCmd::help() const { - cout << setw(20) << left << "PINITialstate: " - << "Set initial state BDD" << endl; -} - -//---------------------------------------------------------------------- -// PTRansrelation [(string triName)] [(string trName)] -//---------------------------------------------------------------------- -GVCmdExecStatus -PTransRelationCmd::exec(const string& option) { - size_t op = 0; - vector options; - GVCmdExec::lexOptions(option, options); - if (options.size() > 2) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[2]); - - string triName, trName; - if (op < options.size()) { - triName = options[op++]; - if (!isValidVarName(triName)) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, triName); - } - if (op < options.size()) { - trName = options[op++]; - if (!isValidVarName(trName)) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, trName); - } - bddMgrV->buildPTransRelation(); - if (!triName.empty() && - !bddMgrV->addBddNodeV(triName, bddMgrV->getPTri()())) { - gvMsg(GV_MSG_ERR) - << "\"" << triName - << "\" has Already been Associated With Another BddNode!!" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, triName); - } - if (!trName.empty() && !bddMgrV->addBddNodeV(trName, bddMgrV->getPTr()())) { - gvMsg(GV_MSG_ERR) - << "\"" << trName - << "\" has Already been Associated With Another BddNode!!" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, trName); - } - return GV_CMD_EXEC_DONE; -} - -void -PTransRelationCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) - << "Usage: PTRansrelation [(string triName)] [(stirng trName)]" << endl; -} - -void -PTransRelationCmd::help() const { - cout << setw(20) << left << "PTRansrelation: " - << "build the transition relationship in BDDs" << endl; -} - -//---------------------------------------------------------------------- -// PIMAGe [-Next <(int numTimeframes)>] [(string varName)] -//---------------------------------------------------------------------- -GVCmdExecStatus -PImageCmd::exec(const string& option) { - if (bddMgrV->getPInitState()() == 0) { - gvMsg(GV_MSG_ERR) << "BDD of Initial State is Not Yet Constructed !!!" - << endl; - return GV_CMD_EXEC_ERROR; - } else if (bddMgrV->getPTr()() == 0) { - gvMsg(GV_MSG_ERR) - << "BDD of Transition Relation is Not Yet Constructed !!!" << endl; - return GV_CMD_EXEC_ERROR; - } - - int level = 1; - string name; - vector options; - GVCmdExec::lexOptions(option, options); - - for (size_t i = 0, n = options.size(); i < n; ++i) - if (!myStrNCmp("-Next", options[i], 2)) - if (++i < n) { - if (!myStr2Int(options[i], level) || level <= 0) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, - options[i]); - } else - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, - options[i - 1]); - else if (name.empty()) { - name = options[i]; - if (!isValidVarName(name)) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, name); - } else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[i]); - bddMgrV->buildPImage(level); - if (!name.empty()) - bddMgrV->forceAddBddNodeV(name, bddMgrV->getPReachState()()); - return GV_CMD_EXEC_DONE; -} - -void -PImageCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) - << "Usage: PIMAGe [-Next <(int numTimeframes)>] [(string varName)]" - << endl; -} - -void -PImageCmd::help() const { - cout << setw(20) << left << "PIMAGe: " - << "build the next state images in BDDs" << endl; -} - -//---------------------------------------------------------------------- -// PCHECKProperty < -Netid | -Output > > -//---------------------------------------------------------------------- -GVCmdExecStatus -PCheckPropertyCmd::exec(const string& option) { - if (bddMgrV->getPReachState()() == 0) { - gvMsg(GV_MSG_ERR) << "BDD of Reached State is Not Yet Constructed !!!" - << endl; - return GV_CMD_EXEC_ERROR; - } - - vector options; - GVCmdExec::lexOptions(option, options); - - if (options.size() < 2) - return GVCmdExec::errorOption(GV_CMD_OPT_MISSING, ""); - if (options.size() > 2) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, options[2]); - - bool isNet = false; - - if (!myStrNCmp("-Netid", options[0], 2)) isNet = true; - else if (!myStrNCmp("-Output", options[0], 2)) isNet = false; - else return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[0]); - - int num = 0; - GVNetId netId; - if (!myStr2Int(options[1], num) || (num < 0)) - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); - if (isNet) { - if ((unsigned)num >= gvNtkMgr->getNetSize()) { - gvMsg(GV_MSG_ERR) << "Net with Id " << num - << " does NOT Exist in Current Ntk !!" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); - } - netId = GVNetId::makeNetId(num); - } else { - if ((unsigned)num >= gvNtkMgr->getOutputSize()) { - gvMsg(GV_MSG_ERR) << "Output with Index " << num - << " does NOT Exist in Current Ntk !!" << endl; - return GVCmdExec::errorOption(GV_CMD_OPT_ILLEGAL, options[1]); - } - netId = gvNtkMgr->getOutput(num); - } - - BddNodeV monitor = bddMgrV->getBddNodeV(netId.id); - assert(monitor()); - bddMgrV->runPCheckProperty(gvNtkMgr->getNetNameFromId(netId.id), monitor); - - return GV_CMD_EXEC_DONE; -} - -void -PCheckPropertyCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) - << "Usage: PCHECKProperty < -Netid | -Output >" - << endl; -} - -void -PCheckPropertyCmd::help() const { - cout << setw(20) << left << "PCHECKProperty:" - << "check the monitor by BDDs" << endl; -} diff --git a/src/prove/proveCmd.h b/src/prove/proveCmd.h deleted file mode 100644 index e6595d22..00000000 --- a/src/prove/proveCmd.h +++ /dev/null @@ -1,22 +0,0 @@ -/**************************************************************************** - FileName [ proveCmd.h ] - PackageName [ prove ] - Synopsis [ Define basic prove package commands ] - Author [ ] - Copyright [ Copyleft(c) 2010-present LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#ifndef PROVE_CMD_H_ -#define PROVE_CMD_H_ - -#include "gvCmdMgr.h" - -// ============================================================================ -// Classes for Prove package commands -// ============================================================================ -GV_COMMAND(PInitialStateCmd, GV_CMD_TYPE_PROVE); -GV_COMMAND(PTransRelationCmd, GV_CMD_TYPE_PROVE); -GV_COMMAND(PImageCmd, GV_CMD_TYPE_PROVE); -GV_COMMAND(PCheckPropertyCmd, GV_CMD_TYPE_PROVE); - -#endif diff --git a/src/sat/File.cpp b/src/sat/File.cpp deleted file mode 100644 index eb113245..00000000 --- a/src/sat/File.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "File.h" - -void File::open(int file_descr, FileMode m, bool own) -{ - if (fd != -1) ::close(fd); - fd = file_descr; - mode = m; - own_fd = own; - pos = 0; - buf = xmalloc(File_BufSize); - if (mode == READ) size = read(fd, buf, File_BufSize); - else size = -1; -} - -void File::open(cchar* name, cchar* mode_) -{ - if (fd != -1) ::close(fd); - bool has_r = strchr(mode_, 'r') != NULL; - bool has_w = strchr(mode_, 'w') != NULL; - bool has_a = strchr(mode_, 'a') != NULL; - bool has_p = strchr(mode_, '+') != NULL; - bool has_x = strchr(mode_, 'x') != NULL; - assert(!(has_r && has_w)); - assert(has_r || has_w || has_a); - - int mask = 0; - if (has_p) mask |= O_RDWR; - else if (has_r) mask |= O_RDONLY; - else mask |= O_WRONLY; - - if (!has_r) mask |= O_CREAT; - if (has_w) mask |= O_TRUNC; - if (has_x) mask |= O_EXCL; - - fd = open64(name, mask, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); - - if (fd != -1){ - mode = has_r ? READ : WRITE; - own_fd = true; - pos = 0; - if (has_a) lseek64(fd, 0, SEEK_END); - buf = xmalloc(File_BufSize); - if (mode == READ) size = read(fd, buf, File_BufSize); - else size = -1; - } -} - - -void File::close(void) -{ - if (fd == -1) return; - if (mode == WRITE) - flush(); - xfree(buf); buf = NULL; - if (own_fd) - ::close(fd); - fd = -1; -} - -void File::seek(int64 file_pos, int whence) -{ - if (mode == WRITE){ - flush(); - pos = 0; - lseek64(fd, file_pos, whence); - }else{ - if (whence == SEEK_CUR) lseek64(fd, file_pos - (size - pos), SEEK_CUR); - else lseek64(fd, file_pos, whence); - size = read(fd, buf, File_BufSize); - pos = 0; - } -} - -int64 File::tell(void) -{ - if (mode == WRITE) - return lseek64(fd, 0, SEEK_CUR); - else - return lseek64(fd, 0, SEEK_CUR) - (size - pos); -} - - -//================================================================================================= -// Marshaling: - - -void putUInt(File& out, uint64 val) -{ - if (val < 0x20000000){ - uint v = (uint)val; - if (v < 0x80) - out.putChar(v); - else{ - if (v < 0x2000) - out.putChar(0x80 | (v >> 8)), - out.putChar((uchar)v); - else if (v < 0x200000) - out.putChar(0xA0 | (v >> 16)), - out.putChar((uchar)(v >> 8)), - out.putChar((uchar)v); - else - out.putChar((v >> 24) | 0xC0), - out.putChar((uchar)(v >> 16)), - out.putChar((uchar)(v >> 8)), - out.putChar((uchar)v); - } - }else - out.putChar(0xE0), - out.putChar((uchar)(val >> 56)), - out.putChar((uchar)(val >> 48)), - out.putChar((uchar)(val >> 40)), - out.putChar((uchar)(val >> 32)), - out.putChar((uchar)(val >> 24)), - out.putChar((uchar)(val >> 16)), - out.putChar((uchar)(val >> 8)), - out.putChar((uchar)val); -} - - -uint64 getUInt(File& in) -// throw(Exception_EOF) -//warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated] -{ - uint byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7; - byte0 = in.getChar(); - if (byte0 == (uint)EOF) - throw Exception_EOF(); - if (!(byte0 & 0x80)) - return byte0; - else{ - switch ((byte0 & 0x60) >> 5){ - case 0: - byte1 = in.getChar(); - return ((byte0 & 0x1F) << 8) | byte1; - case 1: - byte1 = in.getChar(); - byte2 = in.getChar(); - return ((byte0 & 0x1F) << 16) | (byte1 << 8) | byte2; - case 2: - byte1 = in.getChar(); - byte2 = in.getChar(); - byte3 = in.getChar(); - return ((byte0 & 0x1F) << 24) | (byte1 << 16) | (byte2 << 8) | byte3; - default: - byte0 = in.getChar(); - byte1 = in.getChar(); - byte2 = in.getChar(); - byte3 = in.getChar(); - byte4 = in.getChar(); - byte5 = in.getChar(); - byte6 = in.getChar(); - byte7 = in.getChar(); - return ((uint64)((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3) << 32) - | (uint64)((byte4 << 24) | (byte5 << 16) | (byte6 << 8) | byte7); - } - } -} diff --git a/src/sat/File.h b/src/sat/File.h deleted file mode 100644 index 931a9542..00000000 --- a/src/sat/File.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef File_h -#define File_h - -#ifndef Global_h -#include "Global.h" -#endif - -#include -#include -#include - -#ifndef _LARGEFILE64_SOURCE -#define lseek64 ::lseek -#define open64 ::open -#endif - - -//================================================================================================= -// A buffered file abstraction with only 'putChar()' and 'getChar()'. - - -#define File_BufSize 1024 // A small buffer seem to work just as fine as a big one (at least under Linux) - -enum FileMode { READ, WRITE }; - -class Exception_EOF {}; - - -// WARNING! This code is not thoroughly tested. May contain bugs! - -class File { - int fd; // Underlying file descriptor. - FileMode mode; // Reading or writing. - uchar* buf; // Read or write buffer. - int size; // Size of buffer (at end of file, less than 'File_BufSize'). - int pos; // Current position in buffer - bool own_fd; // Do we own the file descriptor? If so, will close file in destructor. - -public: - #define DEFAULTS fd(-1), mode(READ), buf(NULL), size(-1), pos(0), own_fd(true) - File(void) : DEFAULTS {} - - File(int fd, FileMode mode, bool own_fd = true) : DEFAULTS { - open(fd, mode, own_fd); } - - File(cchar* name, cchar* mode) : DEFAULTS { - open(name, mode); } - #undef DEFAULTS - - ~File(void) { - close(); } - - void open(int fd, FileMode mode, bool own_fd = true); // Low-level open. If 'own_fd' is FALSE, descriptor will not be closed by destructor. - void open(cchar* name, cchar* mode); // FILE* compatible interface. - void close(void); - - bool null(void) { // TRUE if no file is opened. - return fd == -1; } - - int releaseDescriptor(void) { // Don't run UNIX function 'close()' on descriptor in 'File's 'close()'. - if (mode == READ) - lseek64(fd, pos - size, SEEK_CUR); - own_fd = false; - return fd; } - - FileMode getMode(void) { - return mode; } - - void setMode(FileMode m) { - if (m == mode) return; - if (m == READ){ - flush(); - size = read(fd, buf, File_BufSize); - }else{ - lseek64(fd, pos - size, SEEK_CUR); - size = -1; } - mode = m; - pos = 0; } - - int getCharQ(void) { // Quick version with minimal overhead -- don't call this in the wrong mode! - #ifdef PARANOID - assert(mode == READ); - #endif - if (pos < size) return (uchar)buf[pos++]; - if (size < File_BufSize) return EOF; - size = read(fd, buf, File_BufSize); - pos = 0; - if (size == 0) return EOF; - return (uchar)buf[pos++]; } - - int putCharQ(int chr) { // Quick version with minimal overhead -- don't call this in the wrong mode! - #ifdef PARANOID - assert(mode == WRITE); - #endif - if (pos == File_BufSize) - write(fd, buf, File_BufSize), - pos = 0; - return buf[pos++] = (uchar)chr; } - - int getChar(void) { - if (mode == WRITE) setMode(READ); - return getCharQ(); } - - int putChar(int chr) { - if (mode == READ) setMode(WRITE); - return putCharQ(chr); } - - bool eof(void) { - assert(mode == READ); - if (pos < size) return false; - if (size < File_BufSize) return true; - size = read(fd, buf, File_BufSize); - pos = 0; - if (size == 0) return true; - return false; } - - void flush(void) { - assert(mode == WRITE); - write(fd, buf, pos); - pos = 0; } - - void seek(int64 pos, int whence = SEEK_SET); - int64 tell(void); -}; - - -//================================================================================================= -// Some nice helper functions: - - -void putUInt (File& out, uint64 val); -//uint64 getUInt (File& in) throw(Exception_EOF); -//warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated] -uint64 getUInt (File& in); -static inline uint64 encode64(int64 val) { return (val >= 0) ? (uint64)val << 1 : (((uint64)(~val) << 1) | 1); } -static inline int64 decode64(uint64 val) { return ((val & 1) == 0) ? (int64)(val >> 1) : ~(int64)(val >> 1); } -static inline void putInt (File& out, int64 val) { putUInt(out, encode64(val)); } -static inline uint64 getInt (File& in) { return decode64(getUInt(in)); } - - -//================================================================================================= -#endif diff --git a/src/sat/Global.h b/src/sat/Global.h deleted file mode 100644 index 14dbfe85..00000000 --- a/src/sat/Global.h +++ /dev/null @@ -1,278 +0,0 @@ -/****************************************************************************************[Global.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Global_h -#define Global_h - -#include -#include -#include -#include -#include -#include -#include - - -//================================================================================================= -// Basic Types & Minor Things: - - -#ifdef _MSC_VER -typedef INT64 int64; -typedef UINT64 uint64; -typedef INT_PTR intp; -typedef UINT_PTR uintp; -#define I64_fmt "I64d" -#else -typedef long long int64; -typedef unsigned long long uint64; -typedef __PTRDIFF_TYPE__ intp; -typedef unsigned __PTRDIFF_TYPE__ uintp; -#define I64_fmt "lld" -#endif -typedef unsigned char uchar; -typedef const char cchar; - -// FIXED BY RIC -#ifndef uint -typedef unsigned int uint; -#endif - -template static inline T min(T x, T y) { return (x < y) ? x : y; } -template static inline T max(T x, T y) { return (x > y) ? x : y; } - -template struct STATIC_ASSERTION_FAILURE {}; -//template <> struct STATIC_ASSERTION_FAILURE{}; -#define TEMPLATE_FAIL STATIC_ASSERTION_FAILURE() - - -//================================================================================================= -// 'malloc()'-style memory allocation -- never returns NULL; aborts instead: - - -template static inline T* xmalloc(size_t size) { - T* tmp = (T*)malloc(size * sizeof(T)); - assert(size == 0 || tmp != NULL); - return tmp; } - -template static inline T* xrealloc(T* ptr, size_t size) { - T* tmp = (T*)realloc((void*)ptr, size * sizeof(T)); - assert(size == 0 || tmp != NULL); - return tmp; } - -template static inline void xfree(T *ptr) { - if (ptr != NULL) free((void*)ptr); } - - -//================================================================================================= -// Random numbers: - - -// Returns a random float 0 <= x < 1. Seed must never be 0. -static inline double drand(double& seed) { - seed *= 1389796; - int q = (int)(seed / 2147483647); - seed -= (double)q * 2147483647; - return seed / 2147483647; } - -// Returns a random integer 0 <= x < size. Seed must never be 0. -static inline int irand(double& seed, int size) { - return (int)(drand(seed) * size); } - - -//================================================================================================= -// Time and Memory: - - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#ifdef _MSC_VER - -#include - -static inline double cpuTime(void) { - return (double)clock() / CLOCKS_PER_SEC; } - -static inline int64 memUsed() { - return 0; } - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#else - -#include -#include -#include - -static inline double cpuTime(void) { - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; } - -static inline int memReadStat(int field) -{ - char name[256]; - pid_t pid = getpid(); - sprintf(name, "/proc/%d/statm", pid); - FILE* in = fopen(name, "rb"); - if (in == NULL) return 0; - int value; - for (; field >= 0; field--) - fscanf(in, "%d", &value); - fclose(in); - return value; -} - -static inline int64 memUsed() { return (int64)memReadStat(0) * (int64)getpagesize(); } - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#endif - - - -//================================================================================================= -// 'vec' -- automatically resizable arrays (via 'push()' method): - - -// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc) - -template -class vec { - T* data; - int sz; - int cap; - - void init(int size, const T& pad); - void grow(int min_cap); - -public: - // Types: - typedef int Key; - typedef T Datum; - - // Constructors: - vec(void) : data(NULL) , sz(0) , cap(0) { } - vec(int size) : data(NULL) , sz(0) , cap(0) { growTo(size); } - vec(int size, const T& pad) : data(NULL) , sz(0) , cap(0) { growTo(size, pad); } - vec(T* array, int size) : data(array), sz(size), cap(size) { } // (takes ownership of array -- will be deallocated with 'xfree()') - ~vec(void) { clear(true); } - - // Ownership of underlying array: - T* release (void) { T* ret = data; data = NULL; sz = 0; cap = 0; return ret; } - operator T* (void) { return data; } // (unsafe but convenient) - operator const T* (void) const { return data; } - - // Size operations: - int size (void) const { return sz; } - void shrink (int nelems) { assert(nelems <= sz); for (int i = 0; i < nelems; i++) sz--, data[sz].~T(); } - void pop (void) { sz--, data[sz].~T(); } - void growTo (int size); - void growTo (int size, const T& pad); - void clear (bool dealloc = false); - void capacity (int size) { grow(size); } - - // Stack interface: - void push (void) { if (sz == cap) grow(sz+1); new (&data[sz]) T() ; sz++; } - void push (const T& elem) { if (sz == cap) grow(sz+1); new (&data[sz]) T(elem); sz++; } - const T& last (void) const { return data[sz-1]; } - T& last (void) { return data[sz-1]; } - - // Vector interface: - const T& operator [] (int index) const { return data[index]; } - T& operator [] (int index) { return data[index]; } - - // Don't allow copying (error prone): - vec& operator = (vec& other) { TEMPLATE_FAIL; } - vec (vec& other) { TEMPLATE_FAIL; } - - // Duplicatation (preferred instead): - void copyTo(vec& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) new (©[i]) T(data[i]); } - void moveTo(vec& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; } -}; - -template -void vec::grow(int min_cap) { - if (min_cap <= cap) return; - if (cap == 0) cap = (min_cap >= 2) ? min_cap : 2; - else do cap = (cap*3+1) >> 1; while (cap < min_cap); - data = xrealloc(data, cap); } - -template -void vec::growTo(int size, const T& pad) { - if (sz >= size) return; - grow(size); - for (int i = sz; i < size; i++) new (&data[i]) T(pad); - sz = size; } - -template -void vec::growTo(int size) { - if (sz >= size) return; - grow(size); - for (int i = sz; i < size; i++) new (&data[i]) T(); - sz = size; } - -template -void vec::clear(bool dealloc) { - if (data != NULL){ - for (int i = 0; i < sz; i++) data[i].~T(); - sz = 0; - if (dealloc) xfree(data), data = NULL, cap = 0; } } - - -//================================================================================================= -// Lifted booleans: - - -class lbool { - int value; - explicit lbool(int v) : value(v) { } - -public: - lbool() : value(0) { } - lbool(bool x) : value((int)x*2-1) { } - int toInt(void) const { return value; } - - bool operator == (const lbool& other) const { return value == other.value; } - bool operator != (const lbool& other) const { return value != other.value; } - lbool operator ~ (void) const { return lbool(-value); } - - friend int toInt (lbool l); - friend lbool toLbool(int v); -}; -inline int toInt (lbool l) { return l.toInt(); } -inline lbool toLbool(int v) { return lbool(v); } - -const lbool l_True = toLbool( 1); -const lbool l_False = toLbool(-1); -const lbool l_Undef = toLbool( 0); - - -//================================================================================================= -// Relation operators -- extend definitions from '==' and '<' - - -#ifndef __SGI_STL_INTERNAL_RELOPS // (be aware of SGI's STL implementation...) -#define __SGI_STL_INTERNAL_RELOPS -template static inline bool operator != (const T& x, const T& y) { return !(x == y); } -template static inline bool operator > (const T& x, const T& y) { return y < x; } -template static inline bool operator <= (const T& x, const T& y) { return !(y < x); } -template static inline bool operator >= (const T& x, const T& y) { return !(x < y); } -#endif - - -//================================================================================================= -#endif diff --git a/src/sat/NO_USE/sat.h b/src/sat/NO_USE/sat.h deleted file mode 100644 index be3af770..00000000 --- a/src/sat/NO_USE/sat.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** - FileName [ sat.h ] - PackageName [ sat ] - Synopsis [ Encapsulation of solver engines for inheritance. ] - Author [ Cheng-Yin Wu, Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2010 LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#ifndef SAT_H -#define SAT_H - -#include "verifyDefine.h" -#include "verifyStream.h" -#include "cktCell.h" - -// Base solver engine class, cannot be directly used! -class satSolver -{ - public : - satSolver(const satType); - virtual ~satSolver(); - - // Solver Interface Functions -* virtual bool setOutputFile(const string); - virtual void initialize(); -* virtual void assumeInit(); -* virtual void assertInit(); -* virtual void assumeRelease(); -* virtual void assumeProperty(CktOutPin*, bool); - virtual void assertProperty(CktOutPin*, bool); -* virtual void allProperty(CktOutPin*, bool); -* virtual void increaseBound(); - virtual bool solve(); -* virtual bool assump_solve(); -* virtual void printInfo() const; -* virtual void printSolver() const; -* virtual bool admitListSize(const unsigned&) const; - virtual bool existVerifyData(CktOutPin*, const unsigned& = 0) const; - // Cell Formula to Solver Functions - virtual void add_PI_Formula(CktCell*, const unsigned&); // PI, PO, PIO - virtual void add_AND_Formula(CktCell*, const unsigned&); - virtual void add_CONST_Formula(CktCell*, const unsigned&); // RTL Model - // Solver Basic Function - void addVerifyData(CktCell*, const unsigned&); -* // Static Functions -* static VerifySolver* newVerifySolver(const SolverType); - - private : - vector _DFFList; -}; - -// User-Introduced Solver Engine -/********** MiniSAT_Solver **********/ -class MiniSAT_Solver : public VerifySolver -{ - public : - MiniSAT_Solver(); - ~MiniSAT_Solver(); - // Solver Interface Functions Realization - void initialize(); -* void assumeInit(); -* void assertInit(); -* void assumeRelease(); -* void assumeProperty(CktOutPin*, bool); - void assertProperty(CktOutPin*, bool); -* void allProperty(CktOutPin*, bool); -* void increaseBound(); - bool solve(); -* bool assump_solve(); -* void printInfo() const; -* void printSolver() const; -* bool admitListSize(const unsigned&) const; - bool existVerifyData(CktOutPin*, const unsigned& = 0) const; - // Cell Formula to Solver Functions Realization - void add_PI_Formula(CktCell*, const unsigned&); // PI, PO, PIO - void add_AND_Formula(CktCell*, const unsigned&); - void add_CONST_Formula(CktCell*, const unsigned&); // RTL Model - // Inline Functions - inline void resetVerifyData() { resetDFFList(); _init.clear(); _vars.clear(); _assump.clear(); _curVar = 0; } - // MiniSat Functions - Var newVar(const unsigned&); - Var getVerifyData(CktOutPin*, const unsigned&) const; - private : - Solver* _Solver; // Pointer to a Minisat solver - Var _curVar; // Variable currently - vec _assump; // Assumption List for assumption solve - SATVarVec _init; // Initial state Var storage - SATVarMap _vars; // Mapping from CktOutPin* to Var -}; - -#endif // SAT_H - diff --git a/src/sat/NO_USE/satMiniSat.cpp b/src/sat/NO_USE/satMiniSat.cpp deleted file mode 100644 index 0828c635..00000000 --- a/src/sat/NO_USE/satMiniSat.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** - FileName [ satMiniSat.cpp ] - PackageName [ sat ] - Synopsis [ Implementation of interface functions for MiniSat. ] - Author [ Cheng-Yin Wu, Chung-Yang (Ric) Huang ] - Copyright [ Copyleft(c) 2010 LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#include "satMiniSat.h" -#include "satCommon.h" - -Var -MiniSAT_Solver::newVar(const unsigned& width) { - Var cur_var = _curVar; - for (unsigned i = 0; i < width; ++i) _Solver->newVar(); - _curVar += width; - return cur_var; -} - -void -MiniSAT_Solver::add_PI_Formula(CktCell* cell, const unsigned& depth) { - check_PI_IO(cell); - CktOutPin* OutPin = cell->getOutPin(); - unsigned width = VLDesign.getBus(OutPin->getBusId())->getWidth(); - _vars[depth].insert(make_pair(OutPin, newVar(width))); // set SATVar -} - -void -MiniSAT_Solver::add_AND_Formula(CktCell* cell, const unsigned& depth) { - check_AND_IO(cell); - CktOutPin* OutPin = cell->getOutPin(); - unsigned width = VLDesign.getBus(OutPin->getBusId())->getWidth(); - Var var = _curVar; _vars[depth].insert(make_pair(OutPin, newVar(width))); // set SATVar - CktOutPin* aOutPin = cell->getInPin(0)->getOutPin(); - unsigned aWidth = VLDesign.getBus(aOutPin->getBusId())->getWidth(); - Var aVar = getVerifyData(aOutPin, depth); assert (aVar); - if (static_cast(cell)->getType() == CKT_RED) and_red(_Solver, aVar, var, aWidth); // Reduced - else { - CktOutPin* bOutPin = cell->getInPin(1)->getOutPin(); - Var bVar = getVerifyData(bOutPin, depth); assert (bVar); - if (static_cast(cell)->getType() == CKT_LOG) and_2(_Solver, aVar, bVar, var); // Logic - else for (unsigned i = 0; i < width; ++i) and_2(_Solver, aVar + i, bVar + i, var + i); // Bit-wise - } -} - diff --git a/src/sat/Proof.cpp b/src/sat/Proof.cpp deleted file mode 100644 index 9f5fedfe..00000000 --- a/src/sat/Proof.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/*****************************************************************************************[Proof.C] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#include "Proof.h" -#include "Sort.h" -#include - -//================================================================================================= -// Temporary files handling: - - -class TempFiles { - vec files; // For clean-up purposed on abnormal exit. - -public: - ~TempFiles() - { - for (int i = 0; i < files.size(); i++) - remove(files[i]); - //printf("Didn't delete:\n %s\n", files[i]); - } - - // Returns a read-only string with the filename of the temporary file. The pointer can be used to - // remove the file (which is otherwise done automatically upon program exit). - // - char* open(File& fp) - { -// char * name; -// char* name = "/tmp/fileXXXXXX"; - char* name = new char[64]; - strcpy(name, "/tmp/fileXXXXXX"); - for(;;){ -// name = tempnam(NULL, NULL); // (gcc complains about this... stupid gcc...) -// fp.open(name, "wx+"); - fp.open( mkstemp(name) , WRITE , true ); - assert(name != NULL); - if (fp.null()) - xfree(name); - else{ - files.push(name); - return name; - } - } - } -}; -static TempFiles temp_files; // (should be singleton) - - -//================================================================================================= -// Proof logging: - - -Proof::Proof() -{ - fp_name = temp_files.open(fp); - id_counter = 0; - trav = NULL; - TRA_INT = 0; - fpos =0 ; -} - - -Proof::Proof(ProofTraverser& t) -{ - id_counter = 0; - trav = &t; - TRA_INT = 0; - fpos = 0; -} - - -ClauseId Proof::addRoot(vec& cl, bool A) -{ - cl.copyTo(clause); - sortUnique(clause); - - if (trav != NULL) - trav->root(clause, A); - if (!fp.null()){ - putUInt(fp, index(clause[0]) << 1); - for (int i = 1; i < clause.size(); i++) - putUInt(fp, index(clause[i]) - index(clause[i-1])); - putUInt(fp, 0); // (0 is safe terminator since we removed duplicates) - if(A) putUInt(fp , 1); - else putUInt(fp , 2 ); - } - - return id_counter++; -} - - -void Proof::beginChain(ClauseId start) -{ - assert(start != ClauseId_NULL); - chain_id .clear(); - chain_lit.clear(); - chain_id.push(start); -} - - -void Proof::resolve(ClauseId next, Lit x) -{ - assert(next != ClauseId_NULL); - chain_id .push(next); - chain_lit.push(x); -} - - -ClauseId Proof::endChain() -{ - assert(chain_id.size() == chain_lit.size() + 1); - if (chain_id.size() == 1) - return chain_id[0]; - else{ - if (trav != NULL) - trav->chain(chain_id, chain_lit); - if (!fp.null()){ - putUInt(fp, ((id_counter - chain_id[0]) << 1) | 1); - for (int i = 0; i < chain_lit.size(); i++) - putUInt(fp, index(chain_lit[i])+1 ), - putUInt(fp, id_counter - chain_id[i+1]); - putUInt(fp, 0); - } - - return id_counter++; - } -} - - -void Proof::deleted(ClauseId gone) -{ - if (trav != NULL) - trav->deleted(gone); - if (!fp.null()){ - putUInt(fp, ((id_counter - gone) << 1) | 1); - putUInt(fp, 0); - } -} - - -//================================================================================================= -// Read-back methods: - - -void Proof::compress(Proof& dst, ClauseId goal) -{ - assert(!fp.null()); - assert(false); // Not yet! -} - - -bool Proof::save(cchar* filename) -{ - assert(!fp.null()); - - // Switch to read mode: - fp.setMode(READ); - fp.seek(0); - - // Copy file: - File out(filename, "wox"); - if (out.null()) - return false; - - while (!fp.eof()) - out.putChar(fp.getChar()); - - // Restore write (proof-logging) mode: - fp.seek(0, SEEK_END); - fp.setMode(WRITE); - return true; -} - - -void Proof::traverse(ProofTraverser& trav, ClauseId goal) -{ - assert(!fp.null()); - - // Switch to read mode: - fp.setMode(READ); - fp.seek( fpos ); - - // Traverse proof: - if (goal == ClauseId_NULL) - goal = last(); - - uint64 tmp; - int idx; - bool A; - - for(ClauseId id = TRA_INT ; id <= goal; id++){ - tmp = getUInt(fp); - if ((tmp & 1) == 0){ - // Root clause: - clause.clear(); - idx = tmp >> 1; - clause.push(toLit(idx)); - for(;;){ - tmp = getUInt(fp); - if (tmp == 0) break; - idx += tmp; - clause.push(toLit(idx)); - } - if( getUInt(fp) == 1 ) A = true; - else A = false; - //assert( false); - trav.root(clause ,A); - - - }else{ - // Derivation or Deletion: - - chain_id .clear(); - chain_lit.clear(); - chain_id.push(id - (tmp >> 1)); - for(;;){ - tmp = getUInt(fp); - if (tmp == 0) break; - chain_lit.push(toLit( tmp - 1)); - tmp = getUInt(fp); - chain_id.push(id - tmp); - } - - if (chain_lit.size() == 0) - id--, // (no new clause introduced) - trav.deleted(chain_id[0]); - else - trav.chain(chain_id, chain_lit); - } - } - TRA_INT = goal+1; - fpos = fp.tell(); - fp.seek(0, SEEK_END); - fp.setMode(WRITE); -} diff --git a/src/sat/Proof.h b/src/sat/Proof.h deleted file mode 100644 index b1dbe039..00000000 --- a/src/sat/Proof.h +++ /dev/null @@ -1,74 +0,0 @@ -/*****************************************************************************************[Proof.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Proof_h -#define Proof_h - -#include "SolverTypes.h" -#include "File.h" - - -//================================================================================================= - - -// A "listner" for the proof. Proof events will be passed onto (online mode) or replayed to -// (offline mode) this class. Each call to 'root()' or 'chain()' produces a new clause. The first -// clause has ID 0, the next 1 and so on. These are the IDs passed to 'chain()'s 'cs' parameter. -// -struct ProofTraverser { - virtual void root (const vec& c , bool A)=0;// {assert(false);}; - virtual void chain (const vec& cs, const vec& xs)=0;// {assert(false);}; - virtual void deleted(ClauseId c){} - virtual void done ()=0;//{assert(false);} - virtual ~ProofTraverser(){} -}; - - -class Proof { - File fp; - cchar* fp_name; - ClauseId id_counter; - ProofTraverser* trav; - - int TRA_INT; - int64 fpos; - - vec clause; - vec chain_id; - vec chain_lit; - -public: - Proof(); // Offline mode -- proof stored to a file, which can be saved, compressed, and/or traversed. - Proof(ProofTraverser& t); // Online mode -- proof will not be stored. - - ClauseId addRoot (vec& clause , bool A ); - void beginChain(ClauseId start); - void resolve (ClauseId next, Lit x); - ClauseId endChain (); - void deleted (ClauseId gone); - ClauseId last () { assert(id_counter != ClauseId_NULL); return id_counter - 1; } - - void compress (Proof& dst, ClauseId goal = ClauseId_NULL); // 'dst' should be a newly constructed, empty proof. - bool save (cchar* filename); - void traverse (ProofTraverser& trav, ClauseId goal = ClauseId_NULL) ; -}; - - -//================================================================================================= -#endif diff --git a/src/sat/README b/src/sat/README deleted file mode 100644 index 47c7b58e..00000000 --- a/src/sat/README +++ /dev/null @@ -1,76 +0,0 @@ -1. What can a SAT solver do? - - Given a circuit and a satisfiability target (e.g. a PO assignment), - SAT solver can find a PI assignemt to satisfy the target. If for all - input combinations such PI assignment does not exist, it will report - "unsatisfiable". - - -2. Why should we use SAT solver in this project? - - The FEC pairs identified by simulations are just "potential" - equivalent pairs of signals. We will use SAT solver to formally check - if they are indeed equivalent. - - -3. How to prove the equivalence of a FEC pair? - - We prove it by contraposition. That is, given a FEC pair (a, b), - we will create a new signal "f = a xor b" and use SAT solver to solve - "f = 1". If "f = 1" is satisfiable (i.e. an input assignment is found), - we will know that a and b are not equivalent and this assignment - is a counter-example. Otherwise (the proof returns "unsatisfiable"), we - can conclude that a and b must be equivalent. - - -4. What does a SAT solver look like? - - We will use the miniSat SAT solver (http://minisat.se/). The SAT - solver is defined as a C++ class and you don't really need to look into - it. When you want to use it, you need to first create a SAT solver - object, add clauses to the solver for the circuit under proof, specify - the target signal/value to prove, and call the solver to prove it. - - -5. What do we provide in the reference code? - - The miniSat SAT solver has been simplified and included in the "sat" - package. However, you don't need to study the code. All you need to - know and use is the interface functions defined in "sat.h". Just include - "sat.h" in the file you want to evoke SAT solver. - - -6. How to use the miniSat SAT solver? - -(1) Create a SAT solver object (e.g. SatSolver s;) -(2) Initialize it (by SatSolver::initialize()) -(3) Generate the proof model from the circuit. - - For each PI and AIG gate, assign a distinct "variable ID". - The var IDs for the POs should be the same as its single fanin. - - You should have a mechanism to record the mapping from your gates - to the variable IDs in the solver. The mapping can be stored as a - STL map (e.g. map), or recorded in a data member - in the class CirAigGate. - - For each AIG gate, construct the CNF formula for it and add to the - solver. You can use "SatSolver::addAndCNF(vf, va, fa, vb, fb)", - where vf, va and vb are the variable IDs for this gate and its two - fanins (f = a & b), and fa, fb are bool variables to indicate where - the inputs are inverted. - - Add the proof logic if necessary. For example, to prove "a == b", - you should add the clauses of "f = a xor b" to the solver, where - "f" is a new varaible and you can add the clauses by the function - "SatSolver::addXorCNF()". -(4) Add the SAT target as "assumption" to the solver instance. - - Call "SatSolver::assumeRelease()" to reset the assumptions. - - Add the SAT target(s) by "SatSolver::assumeProperty(varID, value)". - For example, "solver->assumeProperty(38, true)". - - Call "SatSolver::assumpSolve()" to solve. If it returns true, the - SAT target is satisfiable. You can get the input assignment by the - function "int SatSolver::getValue(Var)". - - If the above step returns unsatisfiable, we can conclude the FEC pair - must be equivalent and we can then merge them. -(5) Repeat (4) if you need to prove more SAT instances. - - -7. Please see "sat/test/satTest.cpp" for an example of using SAT. - diff --git a/src/sat/Solver.cpp b/src/sat/Solver.cpp deleted file mode 100644 index 7e6b34ba..00000000 --- a/src/sat/Solver.cpp +++ /dev/null @@ -1,854 +0,0 @@ -/****************************************************************************************[Solver.C] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#include "Solver.h" -#include "Sort.h" -#include - -int effLimit = INT_MAX; // 100000; // INT_MAX; - -//================================================================================================= -// Helper functions: - - -void removeWatch(vec& ws, Clause* elem) -{ - if (ws.size() == 0) return; // (skip lists that are already cleared) - int j = 0; - for (; ws[j] != elem ; j++) assert(j < ws.size()); - for (; j < ws.size()-1; j++) ws[j] = ws[j+1]; - ws.pop(); -} - - -//================================================================================================= -// Operations on clauses: - - -/*_________________________________________________________________________________________________ -| -| newClause : (ps : const vec&) (learnt : bool) (id : ClauseId) -> [void] -| -| Description: -| Allocate and add a new clause to the SAT solvers clause database. If a conflict is detected, -| the 'ok' flag is cleared and the solver is in an unusable state (must be disposed). -| -| Input: -| ps - The new clause as a vector of literals. -| learnt - Is the clause a learnt clause? For learnt clauses, 'ps[0]' is assumed to be the -| asserting literal. An appropriate 'enqueue()' operation will be performed on this -| literal. One of the watches will always be on this literal, the other will be set to -| the literal with the highest decision level. -| id - If logging proof, learnt clauses should be given an ID by caller. -| -| Effect: -| Activity heuristics are updated. -|________________________________________________________________________________________________@*/ -void Solver::newClause(const vec& ps_, bool learnt, ClauseId id , bool A) -{ - assert(learnt || id == ClauseId_NULL); - if (!ok) return; - - vec qs; - if (!learnt){ - assert(decisionLevel() == 0); - ps_.copyTo(qs); // Make a copy of the input vector. - - // Remove duplicates: - sortUnique(qs); - - // Check if clause is satisfied: - for (int i = 0; i < qs.size()-1; i++){ - if (qs[i] == ~qs[i+1]) - return; } - for (int i = 0; i < qs.size(); i++){ - if (value(qs[i]) == l_True) - return; } - - // Remove false literals: - int i, j; - if (proof != NULL) proof->beginChain(proof->addRoot(qs,A)); - for (i = j = 0; i < qs.size(); i++) - if (value(qs[i]) != l_False) - qs[j++] = qs[i]; - else - if (proof != NULL) proof->resolve(unit_id[var(qs[i])], qs[i]); - qs.shrink(i - j); - if (proof != NULL) id = proof->endChain(); - } - const vec& ps = learnt ? ps_ : qs; // 'ps' is now the (possibly) reduced vector of literals. - - if (ps.size() == 0){ - ok = false; - - }else if (ps.size() == 1){ - // NOTE: If enqueue takes place at root level, the assignment will be lost in incremental use (it doesn't seem to hurt much though). - if (id != ClauseId_NULL) - unit_id[var(ps[0])] = id; - if (!enqueue(ps[0])) - ok = false; - - }else{ - // Allocate clause: - Clause* c = Clause_new(learnt, ps, id); - - if (learnt){ - // Put the second watch on the literal with highest decision level: - int max_i = 1; - int max = level[var(ps[1])]; - for (int i = 2; i < ps.size(); i++) - if (level[var(ps[i])] > max) - max = level[var(ps[i])], - max_i = i; - (*c)[1] = ps[max_i]; - (*c)[max_i] = ps[1]; - - // Bumping: - claBumpActivity(c); // (newly learnt clauses should be considered active) - - // Enqueue asserting literal: - check(enqueue((*c)[0], c)); - - // Store clause: - watches[index(~(*c)[0])].push(c); - watches[index(~(*c)[1])].push(c); - learnts.push(c); - stats.learnts_literals += c->size(); - - }else{ - // Store clause: - watches[index(~(*c)[0])].push(c); - watches[index(~(*c)[1])].push(c); - clauses.push(c); - stats.clauses_literals += c->size(); - } - } -} - - -// Disposes a clauses and removes it from watcher lists. NOTE! Low-level; does NOT change the 'clauses' and 'learnts' vector. -// -void Solver::remove(Clause* c, bool just_dealloc) -{ - if (!just_dealloc){ - removeWatch(watches[index(~(*c)[0])], c), - removeWatch(watches[index(~(*c)[1])], c); - - if (c->learnt()) stats.learnts_literals -= c->size(); - else stats.clauses_literals -= c->size(); - - if (proof != NULL) proof->deleted(c->id()); - } - - xfree(c); -} - - -// Can assume everything has been propagated! (esp. the first two literals are != l_False, unless -// the clause is binary and satisfied, in which case the first literal is true) -// Returns True if clause is satisfied (will be removed), False otherwise. -// -bool Solver::simplify(Clause* c) const -{ - assert(decisionLevel() == 0); - for (int i = 0; i < c->size(); i++){ - if (value((*c)[i]) == l_True) - return true; - } - return false; -} - - -//================================================================================================= -// Minor methods: - - -// Creates a new SAT variable in the solver. If 'decision_var' is cleared, variable will not be -// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result). -// -Var Solver::newVar() { - int index; - index = nVars(); - watches .push(); // (list for positive literal) - watches .push(); // (list for negative literal) - reason .push(NULL); - assigns .push(toInt(l_Undef)); - level .push(-1); - trail_pos .push(-1); - activity .push(0); - order .newVar(); - analyze_seen.push(0); - if (proof != NULL) unit_id.push(ClauseId_NULL); - return index; } - - -// Returns FALSE if immediate conflict. -bool Solver::assume(Lit p) { - trail_lim.push(trail.size()); - return enqueue(p); } - - -// Revert to the state at given level. -void Solver::cancelUntil(int level) { - if (decisionLevel() > level){ - for (int c = trail.size()-1; c >= trail_lim[level]; c--){ - Var x = var(trail[c]); - assigns[x] = toInt(l_Undef); - reason [x] = NULL; - order.undo(x); } - trail.shrink(trail.size() - trail_lim[level]); - trail_lim.shrink(trail_lim.size() - level); - qhead = trail.size(); } } - - -//================================================================================================= -// Major methods: - - -/*_________________________________________________________________________________________________ -| -| analyze : (confl : Clause*) (out_learnt : vec&) (out_btlevel : int&) -> [void] -| -| Description: -| Analyze conflict and produce a reason clause ('out_learnt') and a backtracking level -| ('out_btlevel'). -| -| Pre-conditions: -| * 'out_learnt' is assumed to be cleared. -| * Current decision level must be greater than root level. -| -| Post-conditions: -| * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'. -| * If performing proof-logging, the last derived clause in the proof is the reason clause. -|________________________________________________________________________________________________@*/ - -class lastToFirst_lt { // Helper class to 'analyze' -- order literals from last to first occurance in 'trail[]'. - const vec& trail_pos; -public: - lastToFirst_lt(const vec& t) : trail_pos(t) {} - bool operator () (Lit p, Lit q) { return trail_pos[var(p)] > trail_pos[var(q)]; } -}; -void Solver::analyze(Clause* confl, vec& out_learnt, int& out_btlevel) -{ - vec& seen = analyze_seen; - int pathC = 0; - Lit p = lit_Undef; - - // Generate conflict clause: - // - if (proof != NULL) proof->beginChain(confl->id()); - out_learnt.push(); // (leave room for the asserting literal) - out_btlevel = 0; - int index = trail.size()-1; - for(;;){ - assert(confl != NULL); // (otherwise should be UIP) - - Clause& c = *confl; - if (c.learnt()) - claBumpActivity(&c); - - for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){ - Lit q = c[j]; - if (!seen[var(q)]){ - if (level[var(q)] > 0){ - varBumpActivity(q); - seen[var(q)] = 1; - if (level[var(q)] == decisionLevel()) - pathC++; - else{ - out_learnt.push(q); - out_btlevel = max(out_btlevel, level[var(q)]); - } - }else - if (proof != NULL) proof->resolve(unit_id[var(q)], q); - } - } - - // Select next clause to look at: - while (!seen[var(trail[index--])]); - p = trail[index+1]; - confl = reason[var(p)]; - seen[var(p)] = 0; - pathC--; - if (pathC == 0) break; - - if (proof != NULL) proof->resolve(confl->id(), ~p); - } - out_learnt[0] = ~p; - - // Conflict clause minimization: - // - int i=0 , j=0 ; - if (expensive_ccmin == 2){ - // Simplify conflict clause (a lot): - // - uint min_level = 0; - for (i = 1; i < out_learnt.size(); i++) - min_level |= 1 << (level[var(out_learnt[i])] & 31); // (maintain an abstraction of levels involved in conflict) - - analyze_toclear.clear(); - for (i = j = 1; i < out_learnt.size(); i++) - if (reason[var(out_learnt[i])] == NULL || !analyze_removable(out_learnt[i], min_level)) - out_learnt[j++] = out_learnt[i]; - }else if(expensive_ccmin == 1){ - // Simplify conflict clause (a little): - // - analyze_toclear.clear(); - for (i = j = 1; i < out_learnt.size(); i++){ - Clause* r = reason[var(out_learnt[i])]; - if (r == NULL) - out_learnt[j++] = out_learnt[i]; - else{ - Clause& c = *r; - for (int k = 1; k < c.size(); k++) - if (!seen[var(c[k])] && level[var(c[k])] != 0){ - out_learnt[j++] = out_learnt[i]; - goto Keep; - } - analyze_toclear.push(out_learnt[i]); - Keep:; - } - } - } - - // Finilize proof logging with conflict clause minimization steps: - // - if (proof != NULL){ - sort(analyze_toclear, lastToFirst_lt(trail_pos)); - for (int k = 0; k < analyze_toclear.size(); k++){ - Var v = var(analyze_toclear[k]); assert(level[v] > 0); - Lit l = analyze_toclear[k]; - Clause& c = *reason[v]; - proof->resolve(c.id(), l); - for (int k = 1; k < c.size(); k++) - if (level[var(c[k])] == 0) - proof->resolve(unit_id[var(c[k])], c[k]); - } - proof->endChain(); - } - // Clean up: - // - for (int j = 0; j < out_learnt.size() ; j++) seen[var(out_learnt [j])] = 0; - for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared) - - stats.max_literals += out_learnt.size(); - out_learnt.shrink(i - j); - stats.tot_literals += out_learnt.size(); -} - - -// Check if 'p' can be removed. 'min_level' is used to abort early if visiting literals at a level that cannot be removed. -// -bool Solver::analyze_removable(Lit p, uint min_level) -{ - assert(reason[var(p)] != NULL); - analyze_stack.clear(); analyze_stack.push(p); - int top = analyze_toclear.size(); - while (analyze_stack.size() > 0){ - assert(reason[var(analyze_stack.last())] != NULL); - Clause& c = *reason[var(analyze_stack.last())]; - analyze_stack.pop(); - for (int i = 1; i < c.size(); i++){ - Lit p = c[i]; - if (!analyze_seen[var(p)] && level[var(p)] != 0){ - if (reason[var(p)] != NULL && ((1 << (level[var(p)] & 31)) & min_level) != 0){ - analyze_seen[var(p)] = 1; - analyze_stack.push(p); - analyze_toclear.push(p); - }else{ - for (int j = top; j < analyze_toclear.size(); j++) - analyze_seen[var(analyze_toclear[j])] = 0; - analyze_toclear.shrink(analyze_toclear.size() - top); - return false; - } - } - } - } - analyze_toclear.push(p); - - return true; -} - - -/*_________________________________________________________________________________________________ -| -| analyzeFinal : (confl : Clause*) (skip_first : bool) -> [void] -| -| Description: -| Specialized analysis procedure to express the final conflict in terms of assumptions. -| 'root_level' is allowed to point beyond end of trace (useful if called after conflict while -| making assumptions). If 'skip_first' is TRUE, the first literal of 'confl' is ignored (needed -| if conflict arose before search even started). -|________________________________________________________________________________________________@*/ -void Solver::analyzeFinal(Clause* confl, bool skip_first) -{ - // -- NOTE! This code is relatively untested. Please report bugs! - conflict.clear(); - if (root_level == 0){ - if (proof != NULL) conflict_id = proof->last(); - return; } - //assert(false); - vec& seen = analyze_seen; - if (proof != NULL) proof->beginChain(confl->id()); - for (int i = skip_first ? 1 : 0; i < confl->size(); i++){ - Var x = var((*confl)[i]); - Lit l = (*confl)[i]; - if (level[x] > 0) - seen[x] = 1; - else - if (proof != NULL) proof->resolve(unit_id[x], l); - } - - int start = (root_level >= trail_lim.size()) ? trail.size()-1 : trail_lim[root_level]; - for (int i = start; i >= trail_lim[0]; i--){ - Var x = var(trail[i]); - Lit l = trail[i]; - if (seen[x]){ - Clause* r = reason[x]; - if (r == NULL){ - assert(level[x] > 0); - conflict.push(~trail[i]); - }else{ - Clause& c = *r; - if (proof != NULL) proof->resolve(c.id(), l); - for (int j = 1; j < c.size(); j++) - if (level[var(c[j])] > 0) - seen[var(c[j])] = 1; - else - if (proof != NULL) proof->resolve(unit_id[var(c[j])], c[j]); - } - seen[x] = 0; - } - } - if (proof != NULL) conflict_id = proof->endChain(); -} - - -/*_________________________________________________________________________________________________ -| -| enqueue : (p : Lit) (from : Clause*) -> [bool] -| -| Description: -| Puts a new fact on the propagation queue as well as immediately updating the variable's value. -| Should a conflict arise, FALSE is returned. -| -| Input: -| p - The fact to enqueue -| from - [Optional] Fact propagated from this (currently) unit clause. Stored in 'reason[]'. -| Default value is NULL (no reason). -| -| Output: -| TRUE if fact was enqueued without conflict, FALSE otherwise. -|________________________________________________________________________________________________@*/ -bool Solver::enqueue(Lit p, Clause* from) -{ - if (value(p) != l_Undef) - return value(p) != l_False; - else{ - Var x = var(p); - assigns [x] = toInt(lbool(!sign(p))); - level [x] = decisionLevel(); - trail_pos[x] = trail.size(); - reason [x] = from; - trail.push(p); - return true; - } -} - - - -/*_________________________________________________________________________________________________ -| -| propagate : [void] -> [Clause*] -| -| Description: -| Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned, -| otherwise NULL. NOTE! This method has been optimized for speed rather than readability. -| -| Post-conditions: -| * The propagation queue is empty, even if there was a conflict. -|________________________________________________________________________________________________@*/ -Clause* Solver::propagate() -{ - Clause* confl = NULL; - while (qhead < trail.size()){ - stats.propagations++; - simpDB_props--; - - Lit p = trail[qhead++]; // 'p' is enqueued fact to propagate. - vec& ws = watches[index(p)]; - Clause** i,** j,** end; - - for (i = j = (Clause**)ws, end = i + ws.size(); i != end;){ - Clause& c = **i; i++; - // Make sure the false literal is data[1]: - Lit false_lit = ~p; - if (c[0] == false_lit) - c[0] = c[1], c[1] = false_lit; - - assert(c[1] == false_lit); - - // If 0th watch is true, then clause is already satisfied. - Lit first = c[0]; - lbool val = value(first); - if (val == l_True){ - *j++ = &c; - }else{ - // Look for new watch: - for (int k = 2; k < c.size(); k++) - if (value(c[k]) != l_False){ - c[1] = c[k]; c[k] = false_lit; - watches[index(~c[1])].push(&c); - goto FoundWatch; } - - // Did not find watch -- clause is unit under assignment: - if (decisionLevel() == 0 && proof != NULL){ - // Log the production of this unit clause: - proof->beginChain(c.id()); - for (int k = 1; k < c.size(); k++) - proof->resolve(unit_id[var(c[k])], c[k]); - ClauseId id = proof->endChain(); - assert(unit_id[var(first)] == ClauseId_NULL || value(first) == l_False); // (if variable already has 'id', it must be with the other polarity and we should have derived the empty clause here) - if (value(first) != l_False) - unit_id[var(first)] = id; - else{ - // Empty clause derived: - proof->beginChain(unit_id[var(first)]); - proof->resolve(id, ~first); - proof->endChain(); - } - } - - *j++ = &c; - if (!enqueue(first, &c)){ - if (decisionLevel() == 0) - ok = false; - confl = &c; - qhead = trail.size(); - // Copy the remaining watches: - while (i < end) - *j++ = *i++; - } - FoundWatch:; - } - } - ws.shrink(i - j); - } - - return confl; -} - - -/*_________________________________________________________________________________________________ -| -| reduceDB : () -> [void] -| -| Description: -| Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked -| clauses are clauses that are reason to some assignment. Binary clauses are never removed. -|________________________________________________________________________________________________@*/ -struct reduceDB_lt { bool operator () (Clause* x, Clause* y) { return x->size() > 2 && (y->size() == 2 || x->activity() < y->activity()); } }; -void Solver::reduceDB() -{ - int i, j; - double extra_lim = cla_inc / learnts.size(); // Remove any clause below this activity - - sort(learnts, reduceDB_lt()); - for (i = j = 0; i < learnts.size() / 2; i++){ - if (learnts[i]->size() > 2 && !locked(learnts[i])) - remove(learnts[i]); - else - learnts[j++] = learnts[i]; - } - for (; i < learnts.size(); i++){ - if (learnts[i]->size() > 2 && !locked(learnts[i]) && learnts[i]->activity() < extra_lim) - remove(learnts[i]); - else - learnts[j++] = learnts[i]; - } - learnts.shrink(i - j); -} - - -/*_________________________________________________________________________________________________ -| -| simplifyDB : [void] -> [bool] -| -| Description: -| Simplify the clause database according to the current top-level assigment. Currently, the only -| thing done here is the removal of satisfied clauses, but more things can be put here. -|________________________________________________________________________________________________@*/ -void Solver::simplifyDB() -{ - if (!ok) return; // GUARD (public method) - assert(decisionLevel() == 0); - - if (propagate() != NULL){ - ok = false; - return; } - - if (nAssigns() == simpDB_assigns || simpDB_props > 0) // (nothing has changed or preformed a simplification too recently) - return; - - // Clear watcher lists: - for (int i = simpDB_assigns; i < nAssigns(); i++){ - Lit p = trail[i]; - watches[index( p)].clear(true); - watches[index(~p)].clear(true); - } - - // Remove satisfied clauses: - for (int type = 0; type < 2; type++){ - vec& cs = type ? learnts : clauses; - int j = 0; - for (int i = 0; i < cs.size(); i++){ - if (!locked(cs[i]) && simplify(cs[i])) - remove(cs[i]); - else - cs[j++] = cs[i]; - } - cs.shrink(cs.size()-j); - } - - simpDB_assigns = nAssigns(); - simpDB_props = stats.clauses_literals + stats.learnts_literals; // (shouldn't depend on 'stats' really, but it will do for now) -} - - -/*_________________________________________________________________________________________________ -| -| search : (nof_conflicts : int) (nof_learnts : int) (params : const SearchParams&) -> [lbool] -| -| Description: -| Search for a model the specified number of conflicts, keeping the number of learnt clauses -| below the provided limit. NOTE! Use negative value for 'nof_conflicts' or 'nof_learnts' to -| indicate infinity. -| -| Output: -| 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If -| all variables are decision variables, this means that the clause set is satisfiable. 'l_False' -| if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached. -|________________________________________________________________________________________________@*/ -lbool Solver::search(int nof_conflicts, int nof_learnts, const SearchParams& params) -{ - if (!ok) return l_False; // GUARD (public method) - assert(root_level == decisionLevel()); - - stats.starts++; - int conflictC = 0; - var_decay = 1 / params.var_decay; - cla_decay = 1 / params.clause_decay; - model.clear(); - - for (;;){ - Clause* confl = propagate(); - if (confl != NULL){ - // CONFLICT - - stats.conflicts++; conflictC++; - vec learnt_clause; - int backtrack_level; - if (decisionLevel() == root_level){ - // Contradiction found: - analyzeFinal(confl); - return l_False; } - analyze(confl, learnt_clause, backtrack_level); - cancelUntil(max(backtrack_level, root_level)); - newClause(learnt_clause, true, (proof != NULL) ? proof->last() : ClauseId_NULL); - if (learnt_clause.size() == 1) level[var(learnt_clause[0])] = 0; // (this is ugly (but needed for 'analyzeFinal()') -- in future versions, we will backtrack past the 'root_level' and redo the assumptions) - varDecayActivity(); - claDecayActivity(); - - }else{ - // NO CONFLICT - - if (nof_conflicts >= 0 && conflictC >= nof_conflicts){ - // Reached bound on number of conflicts: - progress_estimate = progressEstimate(); - cancelUntil(root_level); - return l_Undef; } - - if (decisionLevel() == 0) - // Simplify the set of problem clauses: - simplifyDB(), assert(ok); - - if (nof_learnts >= 0 && learnts.size()-nAssigns() >= nof_learnts) - // Reduce the set of learnt clauses: - reduceDB(); - - // New variable decision: - stats.decisions++; - Var next = order.select(params.random_var_freq); - - if (next == var_Undef){ - // Model found: - model.growTo(nVars()); - for (int i = 0; i < nVars(); i++) model[i] = value(i); - cancelUntil(root_level); - return l_True; - } - - check(assume(~Lit(next))); - } - } -} - - -// Return search-space coverage. Not extremely reliable. -// -double Solver::progressEstimate() -{ - double progress = 0; - double F = 1.0 / nVars(); - for (int i = 0; i < nVars(); i++) - if (value(i) != l_Undef) - progress += pow(F, level[i]); - return progress / nVars(); -} - - -// Divide all variable activities by 1e100. -// -void Solver::varRescaleActivity() -{ - for (int i = 0; i < nVars(); i++) - activity[i] *= 1e-100; - var_inc *= 1e-100; -} - - -// Divide all constraint activities by 1e100. -// -void Solver::claRescaleActivity() -{ - for (int i = 0; i < learnts.size(); i++) - learnts[i]->activity() *= 1e-20; - cla_inc *= 1e-20; -} - - -/*_________________________________________________________________________________________________ -| -| solve : (assumps : const vec&) -> [bool] -| -| Description: -| Top-level solve. If using assumptions (non-empty 'assumps' vector), you must call -| 'simplifyDB()' first to see that no top-level conflict is present (which would put the solver -| in an undefined state). -| -| Input: -| A list of assumptions (unit clauses coded as literals). Pre-condition: The assumptions must -| not contain both 'x' and '~x' for any variable 'x'. -|________________________________________________________________________________________________@*/ -lbool Solver::solve(const vec& assumps) -{ - simplifyDB(); - if (!ok) return l_False; // false; - - SearchParams params(default_params); - double nof_conflicts = 100; - double nof_learnts = nClauses() / 3; - lbool status = l_Undef; - - // Perform assumptions: - root_level = assumps.size(); - for (int i = 0; i < assumps.size(); i++){ - Lit p = assumps[i]; - assert(var(p) < nVars()); - if (!assume(p)){ - if (reason[var(p)] != NULL){ - analyzeFinal(reason[var(p)], true); - conflict.push(~p); - }else{ - assert(proof == NULL || unit_id[var(p)] != ClauseId_NULL); // (this is the pre-condition above) - conflict.clear(); - conflict.push(~p); - if (proof != NULL) conflict_id = unit_id[var(p)]; - } - cancelUntil(0); - return l_False; } // false; } - Clause* confl = propagate(); - if (confl != NULL){ - analyzeFinal(confl), assert(conflict.size() > 0); - cancelUntil(0); - return l_False; } // false; } - } - assert(root_level == decisionLevel()); - - // Search: - if (verbosity >= 1){ - reportf("==================================[MINISAT]"); - reportf("===================================\n"); - reportf("| Conflicts | ORIGINAL | "); - reportf("LEARNT | Progress |\n"); - reportf("| | Clauses Literals | Limit Clauses "); - reportf("Literals Lit/Cl | |\n"); - reportf("==========================================="); - reportf("===================================\n"); - } - - while (status == l_Undef){ - if (verbosity >= 1){ - printStats(); - reportf("| %9d | %7d %8d | %7d %7d %8d %7.1f | %6.3f %% |\n", - (int)stats.conflicts, nClauses(), - (int)stats.clauses_literals, - (int)nof_learnts, nLearnts(), - (int)stats.learnts_literals, - (double)stats.learnts_literals/nLearnts(), - progress_estimate*100); - fflush(stdout); - } - status = search((int)nof_conflicts, (int)nof_learnts, params); - nof_conflicts *= 1.5; - nof_learnts *= 1.1; - -if ((int)stats.conflicts >= effLimit) { - cancelUntil(0); - return l_Undef; // status == l_True; -// return status == l_True; -} - } - if (verbosity >= 1) { - reportf("==========================================="); - reportf("===================================\n"); - } - - cancelUntil(0); - return status; -// return status == l_True; -} - -void Solver::printStats() -{ - reportf("==============================[MINISAT]"); - reportf("===============================\n"); - reportf("| Conflicts | ORIGINAL | "); - reportf("LEARNT | Progress |\n"); - reportf("| | Clauses Literals | Clauses "); - reportf("Literals Lit/Cl | |\n"); - reportf("======================================="); - reportf("===============================\n"); - reportf("| %9d | %7d %8d | %7d %8d %7.1f | %6.3f %% |\n", - (int)stats.conflicts, nClauses(), (int)stats.clauses_literals, - nLearnts(), (int)stats.learnts_literals, - (double)stats.learnts_literals/nLearnts(), progress_estimate*100); - reportf("======================================="); - reportf("===============================\n"); -} diff --git a/src/sat/Solver.h b/src/sat/Solver.h deleted file mode 100644 index b5343760..00000000 --- a/src/sat/Solver.h +++ /dev/null @@ -1,219 +0,0 @@ -/****************************************************************************************[Solver.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Solver_h -#define Solver_h - -#include "SolverTypes.h" -#include "VarOrder.h" -#include "Proof.h" - -// Redfine if you want output to go somewhere else: -#define reportf(format, args...) ( printf(format , ## args), fflush(stdout) ) - - -//================================================================================================= -// Solver -- the main class: - - -struct SolverStats { - int64 starts, decisions, propagations, conflicts; - int64 clauses_literals, learnts_literals, max_literals, tot_literals; - SolverStats() : starts(0), decisions(0), propagations(0), conflicts(0) - , clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0) { } -}; - - -struct SearchParams { - double var_decay, clause_decay, random_var_freq; // (reasonable values are: 0.95, 0.999, 0.02) - SearchParams(double v = 1, double c = 1, double r = 0) : var_decay(v), clause_decay(c), random_var_freq(r) { } -}; - - -class Solver { -protected: - // Solver state: - // - bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used! - vec clauses; // List of problem clauses. - vec learnts; // List of learnt clauses. - vec unit_id; // 'unit_id[var]' is the clause ID for the unit literal 'var' or '~var' (if set at toplevel). - double cla_inc; // Amount to bump next clause with. - double cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. - - vec activity; // A heuristic measurement of the activity of a variable. - double var_inc; // Amount to bump next variable with. - double var_decay; // INVERSE decay factor for variable activity: stores 1/decay. Use negative value for static variable order. - VarOrder order; // Keeps track of the decision variable order. - - vec > watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true). - vec assigns; // The current assignments (lbool:s stored as char:s). - vec trail; // Assignment stack; stores all assigments made in the order they were made. - vec trail_lim; // Separator indices for different decision levels in 'trail[]'. - vec reason; // 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none. - vec level; // 'level[var]' is the decision level at which assignment was made. - vec trail_pos; // 'trail_pos[var]' is the variable's position in 'trail[]'. This supersedes 'level[]' in some sense, and 'level[]' will probably be removed in future releases. - int root_level; // Level of first proper decision. - int qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat). - int simpDB_assigns; // Number of top-level assignments since last execution of 'simplifyDB()'. - int64 simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplifyDB()'. - - // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which is used: - // - vec analyze_seen; - vec analyze_stack; - vec analyze_toclear; - Clause* propagate_tmpbin; - Clause* analyze_tmpbin; - vec addUnit_tmp; - vec addBinary_tmp; - vec addTernary_tmp; - - // Main internal methods: - // - bool assume (Lit p); - void cancelUntil (int level); - void record (const vec& clause); - - void analyze (Clause* confl, vec& out_learnt, int& out_btlevel); // (bt = backtrack) - bool analyze_removable(Lit p, uint min_level); // (helper method for 'analyze()') - void analyzeFinal (Clause* confl, bool skip_first = false); - bool enqueue (Lit fact, Clause* from = NULL); - Clause* propagate (); - void reduceDB (); - Lit pickBranchLit (const SearchParams& params); - lbool search (int nof_conflicts, int nof_learnts, const SearchParams& params); - double progressEstimate (); - - // Activity: - // - void varBumpActivity(Lit p) { - if (var_decay < 0) return; // (negative decay means static variable order -- don't bump) - if ( (activity[var(p)] += var_inc) > 1e100 ) varRescaleActivity(); - order.update(var(p)); } - void varDecayActivity () { if (var_decay >= 0) var_inc *= var_decay; } - void varRescaleActivity(); - void claDecayActivity () { cla_inc *= cla_decay; } - void claRescaleActivity(); - - // Operations on clauses: - // - void newClause(const vec& ps, bool learnt = false, ClauseId id = ClauseId_NULL, bool A = true); - void claBumpActivity (Clause* c) { if ( (c->activity() += cla_inc) > 1e20 ) claRescaleActivity(); } - void remove (Clause* c, bool just_dealloc = false); - bool locked (const Clause* c) const { return reason[var((*c)[0])] == c; } - bool simplify (Clause* c) const; - - int decisionLevel() const { return trail_lim.size(); } - -public: - Solver() : ok (true) - , cla_inc (1) - , cla_decay (1) - , var_inc (1) - , var_decay (1) - , order (assigns, activity) - , qhead (0) - , simpDB_assigns (0) - , simpDB_props (0) - , default_params (SearchParams(0.95, 0.999, 0.02)) - , expensive_ccmin (2) - , proof (NULL) - , verbosity (0) - , progress_estimate(0) - , conflict_id (ClauseId_NULL) - { - vec dummy(2,lit_Undef); - propagate_tmpbin = Clause_new(false, dummy); - analyze_tmpbin = Clause_new(false, dummy); - addUnit_tmp .growTo(1); - addBinary_tmp .growTo(2); - addTernary_tmp.growTo(3); - } - - ~Solver() { - for (int i = 0; i < learnts.size(); i++) remove(learnts[i], true); - for (int i = 0; i < clauses.size(); i++) if (clauses[i] != NULL) remove(clauses[i], true); - remove(propagate_tmpbin, true); - remove(analyze_tmpbin, true); - } - - // Helpers: (semi-internal) - // - lbool value(Var x) const { return toLbool(assigns[x]); } - lbool value(Lit p) const { return sign(p) ? ~toLbool(assigns[var(p)]) : toLbool(assigns[var(p)]); } - lbool modelValue(Var x) const { return model[x]; } -// lbool modelValue(Lit p) const { return model[var(p)] ^ sign(p); } - - int nAssigns() { return trail.size(); } - int nClauses() { return clauses.size(); } - int nLearnts() { return learnts.size(); } - - // Statistics: (read-only member variable) - // - SolverStats stats; - - // Mode of operation: - // - SearchParams default_params; // Restart frequency etc. - int expensive_ccmin; // Controls conflict clause minimization. TRUE by default. - Proof* proof; // Set this directly after constructing 'Solver' to enable proof logging. Initialized to NULL. - int verbosity; // Verbosity level. 0=silent, 1=some progress report, 2=everything - - // Problem specification: - // - Var newVar (); - int nVars () { return assigns.size(); } - void addUnit (Lit p) { addUnit_tmp [0] = p; addClause(addUnit_tmp); } - void addBinary (Lit p, Lit q) { addBinary_tmp [0] = p; addBinary_tmp [1] = q; addClause(addBinary_tmp); } - void addTernary(Lit p, Lit q, Lit r) { addTernary_tmp[0] = p; addTernary_tmp[1] = q; addTernary_tmp[2] = r; addClause(addTernary_tmp); } - void addClause (const vec& ps , bool A = true) { newClause(ps , false , ClauseId_NULL , A); } - // (used to be a difference between internal and external method...) - - // Solving: - // - bool okay() { return ok; } // FALSE means solver is in an conflicting state (must never be used again!) - void simplifyDB(); - lbool solve(const vec& assumps); - lbool solve() { vec tmp; return solve(tmp); } - - double progress_estimate; // Set by 'search()'. - vec model; // If problem is satisfiable, this vector contains the model (if any). - vec conflict; // If problem is unsatisfiable under assumptions, this vector represent the conflict clause expressed in the assumptions. - ClauseId conflict_id; // (In proof logging mode only.) ID for the clause 'conflict' (for proof traverseral). NOTE! The empty clause is always the last clause derived, but for conflicts under assumption, this is not necessarly true. - - // Printing: - // - void printStats(); -}; - - -//================================================================================================= -// Debug: - - -#define L_LIT "%s%d" -#define L_lit(p) sign(p)?"-":"", var(p)+1 - -// Just like 'assert()' but expression will be evaluated in the release version as well. -inline void check(bool expr) { assert(expr); } - - -//================================================================================================= -#endif diff --git a/src/sat/SolverTypes.h b/src/sat/SolverTypes.h deleted file mode 100644 index 74df73a8..00000000 --- a/src/sat/SolverTypes.h +++ /dev/null @@ -1,141 +0,0 @@ -/***********************************************************************************[SolverTypes.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - - -#ifndef SolverTypes_h -#define SolverTypes_h - -#ifndef Global_h -#include "Global.h" -#endif - - -//================================================================================================= -// Variables, literals, clause IDs: - - -// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N, -// so that they can be used as array indices. - -typedef int Var; -#define var_Undef (-1) - - -class Lit { - int x; -public: - Lit() : x(2*var_Undef) {} // (lit_Undef) - explicit Lit(Var var, bool sgn = false) : x((var+var) + (int)sgn) {} - friend Lit operator ~ (Lit p); - - friend bool sign (Lit p); - friend int var (Lit p); - friend int index (Lit p); - friend Lit toLit (int i); - friend Lit unsign(Lit p); - friend Lit id (Lit p, bool sgn); - - friend bool operator == (Lit p, Lit q); - friend bool operator < (Lit p, Lit q); - - uint hash() const { return (uint)x; } -}; -inline Lit operator ~ (Lit p) { Lit q; q.x = p.x ^ 1; return q; } -inline bool sign (Lit p) { return p.x & 1; } -inline int var (Lit p) { return p.x >> 1; } -inline int index (Lit p) { return p.x; } // A "toInt" method that guarantees small, positive integers suitable for array indexing. -inline Lit toLit (int i) { Lit p; p.x = i; return p; } // Inverse of 'index()'. -inline Lit unsign(Lit p) { Lit q; q.x = p.x & ~1; return q; } -inline Lit id (Lit p, bool sgn) { Lit q; q.x = p.x ^ (int)sgn; return q; } -inline bool operator == (Lit p, Lit q) { return index(p) == index(q); } -inline bool operator < (Lit p, Lit q) { return index(p) < index(q); } // '<' guarantees that p, ~p are adjacent in the ordering. - -const Lit lit_Undef(var_Undef, false); // }- Useful special constants. -const Lit lit_Error(var_Undef, true ); // } - -inline int toDimacs(Lit p) { return sign(p) ? -var(p) - 1 : var(p) + 1; } - - -//================================================================================================= -// Clause -- a simple class for representing a clause: - - -typedef int ClauseId; // (might have to use uint64 one day...) -const int ClauseId_NULL = INT_MIN; - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class Clause { - uint size_learnt; - Lit data[1]; -public: - // NOTE: This constructor cannot be used directly (doesn't allocate enough memory). - Clause(bool learnt, const vec& ps, ClauseId id_ = ClauseId_NULL) { - size_learnt = (ps.size() << 1) | (int)learnt; - for (int i = 0; i < ps.size(); i++) data[i] = ps[i]; - if (learnt) activity() = 0; - if (id_ != ClauseId_NULL) id() = id_; } - - // -- use this function instead: - friend Clause* Clause_new(bool, const vec&, ClauseId); - - int size () const { return size_learnt >> 1; } - bool learnt () const { return size_learnt & 1; } - Lit operator [] (int i) const { return data[i]; } - Lit& operator [] (int i) { return data[i]; } - float& activity () const { - void *p = const_cast(&data[size()]); return *((float *)p); - } // return *((float*)&data[size()]); } - ClauseId& id () const { return *((ClauseId*)&data[size() + (int)learnt()]); } -}; - -inline Clause* Clause_new(bool learnt, const vec& ps, ClauseId id = ClauseId_NULL) { - assert(sizeof(Lit) == sizeof(uint)); - assert(sizeof(float) == sizeof(uint)); - assert(sizeof(ClauseId) == sizeof(uint)); - void* mem = xmalloc(sizeof(Clause) + sizeof(uint)*(ps.size() + (int)learnt + (int)(id != ClauseId_NULL))); - return new (mem) Clause(learnt, ps, id); } - - -//================================================================================================= -// GClause -- Generalize clause: - - -// Either a pointer to a clause or a literal. -class GClause { - void* data; - GClause(void* d) : data(d) {} -public: - friend GClause GClause_new(Lit p); - friend GClause GClause_new(Clause* c); - - bool isLit () const { return ((uintp)data & 1) == 1; } - Lit lit () const { return toLit(((intp)data) >> 1); } - Clause* clause () const { return (Clause*)data; } - bool operator == (GClause c) const { return data == c.data; } - bool operator != (GClause c) const { return data != c.data; } -}; -inline GClause GClause_new(Lit p) { return GClause((void*)(((intp)index(p) << 1) + 1)); } -inline GClause GClause_new(Clause* c) { assert(((uintp)c & 1) == 0); return GClause((void*)c); } - -#define GClause_NULL GClause_new((Clause*)NULL) - - -//================================================================================================= -#endif diff --git a/src/sat/VarOrder.h b/src/sat/VarOrder.h deleted file mode 100644 index ad6c77ce..00000000 --- a/src/sat/VarOrder.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************************[VarOrder.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef VarOrder_h -#define VarOrder_h - -#include "SolverTypes.h" -#include "Heap.h" - - -//================================================================================================= - - -struct VarOrder_lt { - const vec& activity; - bool operator () (Var x, Var y) { return activity[x] > activity[y]; } - VarOrder_lt(const vec& act) : activity(act) { } -}; - -class VarOrder { - const vec& assigns; // var->val. Pointer to external assignment table. -// const vec& activity; // var->act. Pointer to external activity table. - Heap heap; - double random_seed; // For the internal random number generator - -public: - VarOrder(const vec& ass, const vec& act) : -// assigns(ass), activity(act), heap(VarOrder_lt(act)), random_seed(91648253) - assigns(ass), heap(VarOrder_lt(act)), random_seed(91648253) - { } - - inline void newVar(void); - inline void update(Var x); // Called when variable increased in activity. - inline void undo(Var x); // Called when variable is unassigned and may be selected again. - inline Var select(double random_freq =.0); // Selects a new, unassigned variable (or 'var_Undef' if none exists). -}; - - -void VarOrder::newVar(void) -{ - heap.setBounds(assigns.size()); - heap.insert(assigns.size()-1); -} - - -void VarOrder::update(Var x) -{ - if (heap.inHeap(x)) - heap.increase(x); -} - - -void VarOrder::undo(Var x) -{ - if (!heap.inHeap(x)) - heap.insert(x); -} - - -Var VarOrder::select(double random_var_freq) -{ - // Random decision: - if (drand(random_seed) < random_var_freq && !heap.empty()){ - Var next = irand(random_seed,assigns.size()); - if (toLbool(assigns[next]) == l_Undef) - return next; - } - - // Activity based decision: - while (!heap.empty()){ - Var next = heap.getmin(); - if (toLbool(assigns[next]) == l_Undef) - return next; - } - - return var_Undef; -} - - -//================================================================================================= -#endif diff --git a/src/sat/glucoseMgr.cpp b/src/sat/glucoseMgr.cpp new file mode 100644 index 00000000..9f83ee6e --- /dev/null +++ b/src/sat/glucoseMgr.cpp @@ -0,0 +1,175 @@ +#include "glucoseMgr.h" + +#include "core/Solver.h" +#include "core/SolverTypes.h" +#include "satMgr.h" + +using namespace gv::cir; +using gv::sat::GlucoseMgr; + +GlucoseMgr::GlucoseMgr(CirMgr* c) : SatSolverMgr(c), _solver(new Glucose::Solver()), _cirMgr(c) { + _assump.clear(); + _solver->newVar(); + _solver->verbosity = 1; + _curVar = 0; + ++_curVar; + _ntkData = new vector[_cirMgr->getNumTots()]; + for (uint32_t i = 0; i < _cirMgr->getNumTots(); ++i) _ntkData[i].clear(); +} + +GlucoseMgr::~GlucoseMgr() { + delete _solver; + assumeRelease(); + // Delete the Circuit Data +} + +const bool GlucoseMgr::simplify() { + return _solver->simplify(); +} + +const bool GlucoseMgr::solve() { + _solver->solve(); + return _solver->okay(); +} + +const bool GlucoseMgr::assump_solve() { + bool result = _solver->solve(_assump); + return result; +} + +void GlucoseMgr::assumeRelease() { + _assump.clear(); +} +void GlucoseMgr::assumeProperty(const CirGate* gate, const bool& invert, const uint32_t& depth) { + const Glucose::Var var = getVerifyData(gate, depth); + _assump.push(Glucose::mkLit(var, invert)); +} + +void GlucoseMgr::assertProperty(const CirGate* gate, const bool& invert, const uint32_t& depth) { + const Glucose::Var var = getVerifyData(gate, depth); + _solver->addClause(Glucose::mkLit(var, invert)); +} + +const Glucose::Var GlucoseMgr::newVar() { + Glucose::Var cur_var = _curVar; + _solver->newVar(); + _curVar++; + return cur_var; +} + +const Glucose::Var GlucoseMgr::getVerifyData(const CirGate* gate, const uint32_t& depth) const { + if (depth >= _ntkData[gate->getGid()].size()) + return 0; + else + return _ntkData[gate->getGid()][depth]; +} + +void GlucoseMgr::add_FALSE_Formula(const CirGate* gate, const uint32_t& depth) { + const uint32_t index = gate->getGid(); + _ntkData[index].push_back(newVar()); + _solver->addClause(Glucose::mkLit(_ntkData[index].back(), true)); +} + +void GlucoseMgr::add_PI_Formula(const CirGate* gate, const uint32_t& depth) { + const uint32_t index = gate->getGid(); + _ntkData[index].push_back(newVar()); +} + +void GlucoseMgr::add_FF_Formula(const CirGate* gate, const uint32_t& depth) { + const uint32_t index = gate->getGid(); + if (depth) { + // Build FF I/O Relation + CirGateV in0 = gate->getIn0(); + const Glucose::Var var1 = getVerifyData(in0.gate(), depth - 1); + + if (in0.isInv()) { + // a <-> b + _ntkData[index].push_back(newVar()); + Glucose::Lit a = Glucose::mkLit(_ntkData[index].back()); + Glucose::Lit b = Glucose::mkLit(var1, true); + Glucose::vec lits; + lits.clear(); + lits.push(~a); + lits.push(b); + _solver->addClause(lits); + lits.clear(); + lits.push(a); + lits.push(~b); + _solver->addClause(lits); + lits.clear(); + } else + _ntkData[index].push_back(var1); + } else { // Timeframe 0 + _ntkData[index].push_back(newVar()); + } +} + +void GlucoseMgr::add_AND_Formula(const CirGate* gate, const uint32_t& depth) { + // const uint32_t index = getGVNetIndex(out); + + const uint32_t index = gate->getGid(); + _ntkData[index].push_back(newVar()); + + const Glucose::Var& var = _ntkData[index].back(); + // Build AND I/O Relation + const CirGateV in0 = gate->getIn0(); + const CirGateV in1 = gate->getIn1(); + const Glucose::Var var0 = getVerifyData(in0.gate(), depth); + const Glucose::Var var1 = getVerifyData(in1.gate(), depth); + + Glucose::Lit y = Glucose::mkLit(var); + Glucose::Lit a = Glucose::mkLit(var0, in0.isInv()); + Glucose::Lit b = Glucose::mkLit(var1, in1.isInv()); + + Glucose::vec lits; + lits.clear(); + lits.push(a); + lits.push(~y); + _solver->addClause(lits); + lits.clear(); + lits.push(b); + lits.push(~y); + _solver->addClause(lits); + lits.clear(); + lits.push(~a); + lits.push(~b); + lits.push(y); + _solver->addClause(lits); + lits.clear(); +} + +void GlucoseMgr::addBoundedVerifyData(const CirGate* gate, const uint32_t& depth) { + if (existVerifyData(gate, depth)) return; + addBoundedVerifyDataRecursively(gate, depth); +} + +void GlucoseMgr::addBoundedVerifyDataRecursively(const CirGate* gate, const uint32_t& depth) { + GateType type = gate->getType(); + if (existVerifyData(gate, depth)) return; + if (type == PI_GATE) + add_PI_Formula(gate, depth); + else if (RO_GATE == type || RI_GATE == type) { + uint32_t newDepth = depth; + if (depth) { + if (type == RI_GATE) newDepth -= 1; + addBoundedVerifyDataRecursively(gate->getIn0Gate(), newDepth); + } + add_FF_Formula(gate, depth); + } else { + if (type == PO_GATE) { + addBoundedVerifyDataRecursively(gate->getIn0Gate(), depth); + add_FF_Formula(gate, depth); + } else if (type == AIG_GATE) { + addBoundedVerifyDataRecursively(gate->getIn0Gate(), depth); + addBoundedVerifyDataRecursively(gate->getIn1Gate(), depth); + add_AND_Formula(gate, depth); + } else { + // CONST_GATE + add_FALSE_Formula(gate, depth); + } + } +} + +const bool GlucoseMgr::existVerifyData(const CirGate* gate, const uint32_t& depth) { + return getVerifyData(gate, depth); +} diff --git a/src/sat/glucoseMgr.h b/src/sat/glucoseMgr.h new file mode 100644 index 00000000..7616d05e --- /dev/null +++ b/src/sat/glucoseMgr.h @@ -0,0 +1,52 @@ +#pragma once + +#include "cirGate.h" +#include "cirMgr.h" +#include "core/Solver.h" +#include "core/SolverTypes.h" +#include "mtl/Vec.h" +#include "satMgr.h" + +namespace gv { +namespace sat { + +class GlucoseMgr : SatSolverMgr { +public: + GlucoseMgr(gv::cir::CirMgr*); + ~GlucoseMgr(); + + void assumeRelease(); + void assumeProperty(const gv::cir::CirGate* gate, const bool& invert, const uint32_t& depth); + void assertProperty(const gv::cir::CirGate* gate, const bool& invert, const uint32_t& depth); + const bool simplify(); + const bool solve(); + const bool assump_solve(); + + // Gate Formula to Solver Functions + void add_FALSE_Formula(const gv::cir::CirGate*, const uint32_t&); + void add_PI_Formula(const gv::cir::CirGate*, const uint32_t&); + void add_FF_Formula(const gv::cir::CirGate*, const uint32_t&); + void add_AND_Formula(const gv::cir::CirGate*, const uint32_t&); + + void addBoundedVerifyData(const gv::cir::CirGate*, const uint32_t&); + const bool existVerifyData(const gv::cir::CirGate*, const uint32_t&); + /*void resizeNtkData(const uint32_t& num);*/ + +private: + const Glucose::Var newVar(); + const Glucose::Var getVerifyData(const gv::cir::CirGate*, const uint32_t&) const; + void addBoundedVerifyDataRecursively(const gv::cir::CirGate*, const uint32_t&); + + inline const Glucose::Var getOriVar(const size_t& v) const { return (Glucose::Var)(v >> 1ul); } + inline const size_t getPosVar(const Glucose::Var& v) const { return (((size_t)v) << 1ul); } + inline const size_t getNegVar(const Glucose::Var& v) const { return ((getPosVar(v)) | 1ul); } + + Glucose::Solver* _solver; + Glucose::vec _assump; + Glucose::Var _curVar; + gv::cir::CirMgr* const _cirMgr; + vector* _ntkData; // Mapping between GVNetId and Solver Data +}; + +} // namespace sat +} // namespace gv diff --git a/src/sat/make.sat b/src/sat/make.sat deleted file mode 100644 index 756bc512..00000000 --- a/src/sat/make.sat +++ /dev/null @@ -1,7 +0,0 @@ -PKGFLAG = -EXTHDRS = sat.h Solver.h SolverTypes.h VarOrder.h Proof.h Global.h \ - File.h Heap.h Sort.h - - -include ../Makefile.in -include ../Makefile.lib diff --git a/src/sat/minisat/LICENSE b/src/sat/minisat/LICENSE deleted file mode 100644 index 22816ff3..00000000 --- a/src/sat/minisat/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson - Copyright (c) 2007-2010 Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/sat/minisat/README b/src/sat/minisat/README deleted file mode 100644 index e5e5617d..00000000 --- a/src/sat/minisat/README +++ /dev/null @@ -1,24 +0,0 @@ -================================================================================ -DIRECTORY OVERVIEW: - -mtl/ Mini Template Library -utils/ Generic helper code (I/O, Parsing, CPU-time, etc) -core/ A core version of the solver -simp/ An extended solver with simplification capabilities -README -LICENSE - -================================================================================ -BUILDING: (release version: without assertions, statically linked, etc) - -export MROOT= (or setenv in cshell) -cd { core | simp } -gmake rs -cp minisat_static /minisat - -================================================================================ -EXAMPLES: - -Run minisat with same heuristics as version 2.0: - -> minisat -no-luby -rinc=1.5 -phase-saving=0 -rnd-freq=0.02 diff --git a/src/sat/minisat/core/Dimacs.h b/src/sat/minisat/core/Dimacs.h deleted file mode 100644 index a05e900c..00000000 --- a/src/sat/minisat/core/Dimacs.h +++ /dev/null @@ -1,89 +0,0 @@ -/****************************************************************************************[Dimacs.h] -Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_Dimacs_h -#define Minisat_Dimacs_h - -#include - -#include "utils/ParseUtils.h" -#include "core/SolverTypes.h" - -namespace Minisat { - -//================================================================================================= -// DIMACS Parser: - -template -static void readClause(B& in, Solver& S, vec& lits) { - int parsed_lit, var; - lits.clear(); - for (;;){ - parsed_lit = parseInt(in); - if (parsed_lit == 0) break; - var = abs(parsed_lit)-1; - while (var >= S.nVars()) S.newVar(); - lits.push( (parsed_lit > 0) ? mkLit(var) : ~mkLit(var) ); - } -} - -template -static void parse_DIMACS_main(B& in, Solver& S) { - vec lits; - int vars = 0; - int clauses = 0; - int cnt = 0; - for (;;){ - skipWhitespace(in); - if (*in == EOF) break; - else if (*in == 'p'){ - if (eagerMatch(in, "p cnf")){ - vars = parseInt(in); - clauses = parseInt(in); - // SATRACE'06 hack - // if (clauses > 4000000) - // S.eliminate(true); - }else{ - printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3); - } - } else if (*in == 'c' || *in == 'p') - skipLine(in); - else{ - cnt++; - readClause(in, S, lits); - S.addClause_(lits); } - } - if (vars != S.nVars()) - fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of variables.\n"); - if (cnt != clauses) - fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of clauses.\n"); -} - -// Inserts problem into solver. -// -template -static void parse_DIMACS(gzFile input_stream, Solver& S) { - StreamBuffer in(input_stream); - parse_DIMACS_main(in, S); } - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/core/Main.cc b/src/sat/minisat/core/Main.cc deleted file mode 100644 index 4388c3e0..00000000 --- a/src/sat/minisat/core/Main.cc +++ /dev/null @@ -1,192 +0,0 @@ -/*****************************************************************************************[Main.cc] -Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#include - -#include -#include - -#include "utils/System.h" -#include "utils/ParseUtils.h" -#include "utils/Options.h" -#include "core/Dimacs.h" -#include "core/Solver.h" - -using namespace Minisat; - -//================================================================================================= - - -void printStats(Solver& solver) -{ - double cpu_time = cpuTime(); - double mem_used = memUsedPeak(); - printf("restarts : %"PRIu64"\n", solver.starts); - printf("conflicts : %-12"PRIu64" (%.0f /sec)\n", solver.conflicts , solver.conflicts /cpu_time); - printf("decisions : %-12"PRIu64" (%4.2f %% random) (%.0f /sec)\n", solver.decisions, (float)solver.rnd_decisions*100 / (float)solver.decisions, solver.decisions /cpu_time); - printf("propagations : %-12"PRIu64" (%.0f /sec)\n", solver.propagations, solver.propagations/cpu_time); - printf("conflict literals : %-12"PRIu64" (%4.2f %% deleted)\n", solver.tot_literals, (solver.max_literals - solver.tot_literals)*100 / (double)solver.max_literals); - if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used); - printf("CPU time : %g s\n", cpu_time); -} - - -static Solver* solver; -// Terminate by notifying the solver and back out gracefully. This is mainly to have a test-case -// for this feature of the Solver as it may take longer than an immediate call to '_exit()'. -static void SIGINT_interrupt(int signum) { solver->interrupt(); } - -// Note that '_exit()' rather than 'exit()' has to be used. The reason is that 'exit()' calls -// destructors and may cause deadlocks if a malloc/free function happens to be running (these -// functions are guarded by locks for multithreaded use). -static void SIGINT_exit(int signum) { - printf("\n"); printf("*** INTERRUPTED ***\n"); - if (solver->verbosity > 0){ - printStats(*solver); - printf("\n"); printf("*** INTERRUPTED ***\n"); } - _exit(1); } - - -//================================================================================================= -// Main: - - -int main(int argc, char** argv) -{ - try { - setUsageHelp("USAGE: %s [options] \n\n where input may be either in plain or gzipped DIMACS.\n"); - // printf("This is MiniSat 2.0 beta\n"); - -#if defined(__linux__) - fpu_control_t oldcw, newcw; - _FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(newcw); - printf("WARNING: for repeatability, setting FPU to use double precision\n"); -#endif - // Extra options: - // - IntOption verb ("MAIN", "verb", "Verbosity level (0=silent, 1=some, 2=more).", 1, IntRange(0, 2)); - IntOption cpu_lim("MAIN", "cpu-lim","Limit on CPU time allowed in seconds.\n", INT32_MAX, IntRange(0, INT32_MAX)); - IntOption mem_lim("MAIN", "mem-lim","Limit on memory usage in megabytes.\n", INT32_MAX, IntRange(0, INT32_MAX)); - - parseOptions(argc, argv, true); - - Solver S; - double initial_time = cpuTime(); - - S.verbosity = verb; - - solver = &S; - // Use signal handlers that forcibly quit until the solver will be able to respond to - // interrupts: - signal(SIGINT, SIGINT_exit); - signal(SIGXCPU,SIGINT_exit); - - // Set limit on CPU-time: - if (cpu_lim != INT32_MAX){ - rlimit rl; - getrlimit(RLIMIT_CPU, &rl); - if (rl.rlim_max == RLIM_INFINITY || (rlim_t)cpu_lim < rl.rlim_max){ - rl.rlim_cur = cpu_lim; - if (setrlimit(RLIMIT_CPU, &rl) == -1) - printf("WARNING! Could not set resource limit: CPU-time.\n"); - } } - - // Set limit on virtual memory: - if (mem_lim != INT32_MAX){ - rlim_t new_mem_lim = (rlim_t)mem_lim * 1024*1024; - rlimit rl; - getrlimit(RLIMIT_AS, &rl); - if (rl.rlim_max == RLIM_INFINITY || new_mem_lim < rl.rlim_max){ - rl.rlim_cur = new_mem_lim; - if (setrlimit(RLIMIT_AS, &rl) == -1) - printf("WARNING! Could not set resource limit: Virtual memory.\n"); - } } - - if (argc == 1) - printf("Reading from standard input... Use '--help' for help.\n"); - - gzFile in = (argc == 1) ? gzdopen(0, "rb") : gzopen(argv[1], "rb"); - if (in == NULL) - printf("ERROR! Could not open file: %s\n", argc == 1 ? "" : argv[1]), exit(1); - - if (S.verbosity > 0){ - printf("============================[ Problem Statistics ]=============================\n"); - printf("| |\n"); } - - parse_DIMACS(in, S); - gzclose(in); - FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL; - - if (S.verbosity > 0){ - printf("| Number of variables: %12d |\n", S.nVars()); - printf("| Number of clauses: %12d |\n", S.nClauses()); } - - double parsed_time = cpuTime(); - if (S.verbosity > 0){ - printf("| Parse time: %12.2f s |\n", parsed_time - initial_time); - printf("| |\n"); } - - // Change to signal-handlers that will only notify the solver and allow it to terminate - // voluntarily: - signal(SIGINT, SIGINT_interrupt); - signal(SIGXCPU,SIGINT_interrupt); - - if (!S.simplify()){ - if (res != NULL) fprintf(res, "UNSAT\n"), fclose(res); - if (S.verbosity > 0){ - printf("===============================================================================\n"); - printf("Solved by unit propagation\n"); - printStats(S); - printf("\n"); } - printf("UNSATISFIABLE\n"); - exit(20); - } - - vec dummy; - lbool ret = S.solveLimited(dummy); - if (S.verbosity > 0){ - printStats(S); - printf("\n"); } - printf(ret == l_True ? "SATISFIABLE\n" : ret == l_False ? "UNSATISFIABLE\n" : "INDETERMINATE\n"); - if (res != NULL){ - if (ret == l_True){ - fprintf(res, "SAT\n"); - for (int i = 0; i < S.nVars(); i++) - if (S.model[i] != l_Undef) - fprintf(res, "%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1); - fprintf(res, " 0\n"); - }else if (ret == l_False) - fprintf(res, "UNSAT\n"); - else - fprintf(res, "INDET\n"); - fclose(res); - } - -#ifdef NDEBUG - exit(ret == l_True ? 10 : ret == l_False ? 20 : 0); // (faster than "return", which will invoke the destructor for 'Solver') -#else - return (ret == l_True ? 10 : ret == l_False ? 20 : 0); -#endif - } catch (OutOfMemoryException&){ - printf("===============================================================================\n"); - printf("INDETERMINATE\n"); - exit(0); - } -} diff --git a/src/sat/minisat/core/Main.or b/src/sat/minisat/core/Main.or deleted file mode 100644 index e586ee83..00000000 Binary files a/src/sat/minisat/core/Main.or and /dev/null differ diff --git a/src/sat/minisat/core/Makefile b/src/sat/minisat/core/Makefile deleted file mode 100644 index 5de1f729..00000000 --- a/src/sat/minisat/core/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -EXEC = minisat -DEPDIR = mtl utils - -include $(MROOT)/mtl/template.mk diff --git a/src/sat/minisat/core/Solver.cc b/src/sat/minisat/core/Solver.cc deleted file mode 100644 index 7da7f189..00000000 --- a/src/sat/minisat/core/Solver.cc +++ /dev/null @@ -1,923 +0,0 @@ -/***************************************************************************************[Solver.cc] -Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#include - -#include "mtl/Sort.h" -#include "core/Solver.h" - -using namespace Minisat; - -//================================================================================================= -// Options: - - -static const char* _cat = "CORE"; - -static DoubleOption opt_var_decay (_cat, "var-decay", "The variable activity decay factor", 0.95, DoubleRange(0, false, 1, false)); -static DoubleOption opt_clause_decay (_cat, "cla-decay", "The clause activity decay factor", 0.999, DoubleRange(0, false, 1, false)); -static DoubleOption opt_random_var_freq (_cat, "rnd-freq", "The frequency with which the decision heuristic tries to choose a random variable", 0, DoubleRange(0, true, 1, true)); -static DoubleOption opt_random_seed (_cat, "rnd-seed", "Used by the random variable selection", 91648253, DoubleRange(0, false, HUGE_VAL, false)); -static IntOption opt_ccmin_mode (_cat, "ccmin-mode", "Controls conflict clause minimization (0=none, 1=basic, 2=deep)", 2, IntRange(0, 2)); -static IntOption opt_phase_saving (_cat, "phase-saving", "Controls the level of phase saving (0=none, 1=limited, 2=full)", 2, IntRange(0, 2)); -static BoolOption opt_rnd_init_act (_cat, "rnd-init", "Randomize the initial activity", false); -static BoolOption opt_luby_restart (_cat, "luby", "Use the Luby restart sequence", true); -static IntOption opt_restart_first (_cat, "rfirst", "The base restart interval", 100, IntRange(1, INT32_MAX)); -static DoubleOption opt_restart_inc (_cat, "rinc", "Restart interval increase factor", 2, DoubleRange(1, false, HUGE_VAL, false)); -static DoubleOption opt_garbage_frac (_cat, "gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered", 0.20, DoubleRange(0, false, HUGE_VAL, false)); - - -//================================================================================================= -// Constructor/Destructor: - - -Solver::Solver() : - - // Parameters (user settable): - // - verbosity (0) - , var_decay (opt_var_decay) - , clause_decay (opt_clause_decay) - , random_var_freq (opt_random_var_freq) - , random_seed (opt_random_seed) - , luby_restart (opt_luby_restart) - , ccmin_mode (opt_ccmin_mode) - , phase_saving (opt_phase_saving) - , rnd_pol (false) - , rnd_init_act (opt_rnd_init_act) - , garbage_frac (opt_garbage_frac) - , restart_first (opt_restart_first) - , restart_inc (opt_restart_inc) - - // Parameters (the rest): - // - , learntsize_factor((double)1/(double)3), learntsize_inc(1.1) - - // Parameters (experimental): - // - , learntsize_adjust_start_confl (100) - , learntsize_adjust_inc (1.5) - - // Statistics: (formerly in 'SolverStats') - // - , solves(0), starts(0), decisions(0), rnd_decisions(0), propagations(0), conflicts(0) - , dec_vars(0), clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0) - - , ok (true) - , cla_inc (1) - , var_inc (1) - , watches (WatcherDeleted(ca)) - , qhead (0) - , simpDB_assigns (-1) - , simpDB_props (0) - , order_heap (VarOrderLt(activity)) - , progress_estimate (0) - , remove_satisfied (true) - - // Resource constraints: - // - , conflict_budget (-1) - , propagation_budget (-1) - , asynch_interrupt (false) -{} - - -Solver::~Solver() -{ -} - - -//================================================================================================= -// Minor methods: - - -// Creates a new SAT variable in the solver. If 'decision' is cleared, variable will not be -// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result). -// -Var Solver::newVar(bool sign, bool dvar) -{ - int v = nVars(); - watches .init(mkLit(v, false)); - watches .init(mkLit(v, true )); - assigns .push(l_Undef); - vardata .push(mkVarData(CRef_Undef, 0)); - //activity .push(0); - activity .push(rnd_init_act ? drand(random_seed) * 0.00001 : 0); - seen .push(0); - polarity .push(sign); - decision .push(); - trail .capacity(v+1); - setDecisionVar(v, dvar); - return v; -} - - -bool Solver::addClause_(vec& ps) -{ - assert(decisionLevel() == 0); - if (!ok) return false; - - // Check if clause is satisfied and remove false/duplicate literals: - sort(ps); - Lit p; int i, j; - for (i = j = 0, p = lit_Undef; i < ps.size(); i++) - if (value(ps[i]) == l_True || ps[i] == ~p) - return true; - else if (value(ps[i]) != l_False && ps[i] != p) - ps[j++] = p = ps[i]; - ps.shrink(i - j); - - if (ps.size() == 0) - return ok = false; - else if (ps.size() == 1){ - uncheckedEnqueue(ps[0]); - return ok = (propagate() == CRef_Undef); - }else{ - CRef cr = ca.alloc(ps, false); - clauses.push(cr); - attachClause(cr); - } - - return true; -} - - -void Solver::attachClause(CRef cr) { - const Clause& c = ca[cr]; - assert(c.size() > 1); - watches[~c[0]].push(Watcher(cr, c[1])); - watches[~c[1]].push(Watcher(cr, c[0])); - if (c.learnt()) learnts_literals += c.size(); - else clauses_literals += c.size(); } - - -void Solver::detachClause(CRef cr, bool strict) { - const Clause& c = ca[cr]; - assert(c.size() > 1); - - if (strict){ - remove(watches[~c[0]], Watcher(cr, c[1])); - remove(watches[~c[1]], Watcher(cr, c[0])); - }else{ - // Lazy detaching: (NOTE! Must clean all watcher lists before garbage collecting this clause) - watches.smudge(~c[0]); - watches.smudge(~c[1]); - } - - if (c.learnt()) learnts_literals -= c.size(); - else clauses_literals -= c.size(); } - - -void Solver::removeClause(CRef cr) { - Clause& c = ca[cr]; - detachClause(cr); - // Don't leave pointers to free'd memory! - if (locked(c)) vardata[var(c[0])].reason = CRef_Undef; - c.mark(1); - ca.free(cr); -} - - -bool Solver::satisfied(const Clause& c) const { - for (int i = 0; i < c.size(); i++) - if (value(c[i]) == l_True) - return true; - return false; } - - -// Revert to the state at given level (keeping all assignment at 'level' but not beyond). -// -void Solver::cancelUntil(int level) { - if (decisionLevel() > level){ - for (int c = trail.size()-1; c >= trail_lim[level]; c--){ - Var x = var(trail[c]); - assigns [x] = l_Undef; - if (phase_saving > 1 || (phase_saving == 1) && c > trail_lim.last()) - polarity[x] = sign(trail[c]); - insertVarOrder(x); } - qhead = trail_lim[level]; - trail.shrink(trail.size() - trail_lim[level]); - trail_lim.shrink(trail_lim.size() - level); - } } - - -//================================================================================================= -// Major methods: - - -Lit Solver::pickBranchLit() -{ - Var next = var_Undef; - - // Random decision: - if (drand(random_seed) < random_var_freq && !order_heap.empty()){ - next = order_heap[irand(random_seed,order_heap.size())]; - if (value(next) == l_Undef && decision[next]) - rnd_decisions++; } - - // Activity based decision: - while (next == var_Undef || value(next) != l_Undef || !decision[next]) - if (order_heap.empty()){ - next = var_Undef; - break; - }else - next = order_heap.removeMin(); - - return next == var_Undef ? lit_Undef : mkLit(next, rnd_pol ? drand(random_seed) < 0.5 : polarity[next]); -} - - -/*_________________________________________________________________________________________________ -| -| analyze : (confl : Clause*) (out_learnt : vec&) (out_btlevel : int&) -> [void] -| -| Description: -| Analyze conflict and produce a reason clause. -| -| Pre-conditions: -| * 'out_learnt' is assumed to be cleared. -| * Current decision level must be greater than root level. -| -| Post-conditions: -| * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'. -| * If out_learnt.size() > 1 then 'out_learnt[1]' has the greatest decision level of the -| rest of literals. There may be others from the same level though. -| -|________________________________________________________________________________________________@*/ -void Solver::analyze(CRef confl, vec& out_learnt, int& out_btlevel) -{ - int pathC = 0; - Lit p = lit_Undef; - - // Generate conflict clause: - // - out_learnt.push(); // (leave room for the asserting literal) - int index = trail.size() - 1; - - do{ - assert(confl != CRef_Undef); // (otherwise should be UIP) - Clause& c = ca[confl]; - - if (c.learnt()) - claBumpActivity(c); - - for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){ - Lit q = c[j]; - - if (!seen[var(q)] && level(var(q)) > 0){ - varBumpActivity(var(q)); - seen[var(q)] = 1; - if (level(var(q)) >= decisionLevel()) - pathC++; - else - out_learnt.push(q); - } - } - - // Select next clause to look at: - while (!seen[var(trail[index--])]); - p = trail[index+1]; - confl = reason(var(p)); - seen[var(p)] = 0; - pathC--; - - }while (pathC > 0); - out_learnt[0] = ~p; - - // Simplify conflict clause: - // - int i, j; - out_learnt.copyTo(analyze_toclear); - if (ccmin_mode == 2){ - uint32_t abstract_level = 0; - for (i = 1; i < out_learnt.size(); i++) - abstract_level |= abstractLevel(var(out_learnt[i])); // (maintain an abstraction of levels involved in conflict) - - for (i = j = 1; i < out_learnt.size(); i++) - if (reason(var(out_learnt[i])) == CRef_Undef || !litRedundant(out_learnt[i], abstract_level)) - out_learnt[j++] = out_learnt[i]; - - }else if (ccmin_mode == 1){ - for (i = j = 1; i < out_learnt.size(); i++){ - Var x = var(out_learnt[i]); - - if (reason(x) == CRef_Undef) - out_learnt[j++] = out_learnt[i]; - else{ - Clause& c = ca[reason(var(out_learnt[i]))]; - for (int k = 1; k < c.size(); k++) - if (!seen[var(c[k])] && level(var(c[k])) > 0){ - out_learnt[j++] = out_learnt[i]; - break; } - } - } - }else - i = j = out_learnt.size(); - - max_literals += out_learnt.size(); - out_learnt.shrink(i - j); - tot_literals += out_learnt.size(); - - // Find correct backtrack level: - // - if (out_learnt.size() == 1) - out_btlevel = 0; - else{ - int max_i = 1; - // Find the first literal assigned at the next-highest level: - for (int i = 2; i < out_learnt.size(); i++) - if (level(var(out_learnt[i])) > level(var(out_learnt[max_i]))) - max_i = i; - // Swap-in this literal at index 1: - Lit p = out_learnt[max_i]; - out_learnt[max_i] = out_learnt[1]; - out_learnt[1] = p; - out_btlevel = level(var(p)); - } - - for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared) -} - - -// Check if 'p' can be removed. 'abstract_levels' is used to abort early if the algorithm is -// visiting literals at levels that cannot be removed later. -bool Solver::litRedundant(Lit p, uint32_t abstract_levels) -{ - analyze_stack.clear(); analyze_stack.push(p); - int top = analyze_toclear.size(); - while (analyze_stack.size() > 0){ - assert(reason(var(analyze_stack.last())) != CRef_Undef); - Clause& c = ca[reason(var(analyze_stack.last()))]; analyze_stack.pop(); - - for (int i = 1; i < c.size(); i++){ - Lit p = c[i]; - if (!seen[var(p)] && level(var(p)) > 0){ - if (reason(var(p)) != CRef_Undef && (abstractLevel(var(p)) & abstract_levels) != 0){ - seen[var(p)] = 1; - analyze_stack.push(p); - analyze_toclear.push(p); - }else{ - for (int j = top; j < analyze_toclear.size(); j++) - seen[var(analyze_toclear[j])] = 0; - analyze_toclear.shrink(analyze_toclear.size() - top); - return false; - } - } - } - } - - return true; -} - - -/*_________________________________________________________________________________________________ -| -| analyzeFinal : (p : Lit) -> [void] -| -| Description: -| Specialized analysis procedure to express the final conflict in terms of assumptions. -| Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and -| stores the result in 'out_conflict'. -|________________________________________________________________________________________________@*/ -void Solver::analyzeFinal(Lit p, vec& out_conflict) -{ - out_conflict.clear(); - out_conflict.push(p); - - if (decisionLevel() == 0) - return; - - seen[var(p)] = 1; - - for (int i = trail.size()-1; i >= trail_lim[0]; i--){ - Var x = var(trail[i]); - if (seen[x]){ - if (reason(x) == CRef_Undef){ - assert(level(x) > 0); - out_conflict.push(~trail[i]); - }else{ - Clause& c = ca[reason(x)]; - for (int j = 1; j < c.size(); j++) - if (level(var(c[j])) > 0) - seen[var(c[j])] = 1; - } - seen[x] = 0; - } - } - - seen[var(p)] = 0; -} - - -void Solver::uncheckedEnqueue(Lit p, CRef from) -{ - assert(value(p) == l_Undef); - assigns[var(p)] = lbool(!sign(p)); - vardata[var(p)] = mkVarData(from, decisionLevel()); - trail.push_(p); -} - - -/*_________________________________________________________________________________________________ -| -| propagate : [void] -> [Clause*] -| -| Description: -| Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned, -| otherwise CRef_Undef. -| -| Post-conditions: -| * the propagation queue is empty, even if there was a conflict. -|________________________________________________________________________________________________@*/ -CRef Solver::propagate() -{ - CRef confl = CRef_Undef; - int num_props = 0; - watches.cleanAll(); - - while (qhead < trail.size()){ - Lit p = trail[qhead++]; // 'p' is enqueued fact to propagate. - vec& ws = watches[p]; - Watcher *i, *j, *end; - num_props++; - - for (i = j = (Watcher*)ws, end = i + ws.size(); i != end;){ - // Try to avoid inspecting the clause: - Lit blocker = i->blocker; - if (value(blocker) == l_True){ - *j++ = *i++; continue; } - - // Make sure the false literal is data[1]: - CRef cr = i->cref; - Clause& c = ca[cr]; - Lit false_lit = ~p; - if (c[0] == false_lit) - c[0] = c[1], c[1] = false_lit; - assert(c[1] == false_lit); - i++; - - // If 0th watch is true, then clause is already satisfied. - Lit first = c[0]; - Watcher w = Watcher(cr, first); - if (first != blocker && value(first) == l_True){ - *j++ = w; continue; } - - // Look for new watch: - for (int k = 2; k < c.size(); k++) - if (value(c[k]) != l_False){ - c[1] = c[k]; c[k] = false_lit; - watches[~c[1]].push(w); - goto NextClause; } - - // Did not find watch -- clause is unit under assignment: - *j++ = w; - if (value(first) == l_False){ - confl = cr; - qhead = trail.size(); - // Copy the remaining watches: - while (i < end) - *j++ = *i++; - }else - uncheckedEnqueue(first, cr); - - NextClause:; - } - ws.shrink(i - j); - } - propagations += num_props; - simpDB_props -= num_props; - - return confl; -} - - -/*_________________________________________________________________________________________________ -| -| reduceDB : () -> [void] -| -| Description: -| Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked -| clauses are clauses that are reason to some assignment. Binary clauses are never removed. -|________________________________________________________________________________________________@*/ -struct reduceDB_lt { - ClauseAllocator& ca; - reduceDB_lt(ClauseAllocator& ca_) : ca(ca_) {} - bool operator () (CRef x, CRef y) { - return ca[x].size() > 2 && (ca[y].size() == 2 || ca[x].activity() < ca[y].activity()); } -}; -void Solver::reduceDB() -{ - int i, j; - double extra_lim = cla_inc / learnts.size(); // Remove any clause below this activity - - sort(learnts, reduceDB_lt(ca)); - // Don't delete binary or locked clauses. From the rest, delete clauses from the first half - // and clauses with activity smaller than 'extra_lim': - for (i = j = 0; i < learnts.size(); i++){ - Clause& c = ca[learnts[i]]; - if (c.size() > 2 && !locked(c) && (i < learnts.size() / 2 || c.activity() < extra_lim)) - removeClause(learnts[i]); - else - learnts[j++] = learnts[i]; - } - learnts.shrink(i - j); - checkGarbage(); -} - - -void Solver::removeSatisfied(vec& cs) -{ - int i, j; - for (i = j = 0; i < cs.size(); i++){ - Clause& c = ca[cs[i]]; - if (satisfied(c)) - removeClause(cs[i]); - else - cs[j++] = cs[i]; - } - cs.shrink(i - j); -} - - -void Solver::rebuildOrderHeap() -{ - vec vs; - for (Var v = 0; v < nVars(); v++) - if (decision[v] && value(v) == l_Undef) - vs.push(v); - order_heap.build(vs); -} - - -/*_________________________________________________________________________________________________ -| -| simplify : [void] -> [bool] -| -| Description: -| Simplify the clause database according to the current top-level assigment. Currently, the only -| thing done here is the removal of satisfied clauses, but more things can be put here. -|________________________________________________________________________________________________@*/ -bool Solver::simplify() -{ - assert(decisionLevel() == 0); - - if (!ok || propagate() != CRef_Undef) - return ok = false; - - if (nAssigns() == simpDB_assigns || (simpDB_props > 0)) - return true; - - // Remove satisfied clauses: - removeSatisfied(learnts); - if (remove_satisfied) // Can be turned off. - removeSatisfied(clauses); - checkGarbage(); - rebuildOrderHeap(); - - simpDB_assigns = nAssigns(); - simpDB_props = clauses_literals + learnts_literals; // (shouldn't depend on stats really, but it will do for now) - - return true; -} - - -/*_________________________________________________________________________________________________ -| -| search : (nof_conflicts : int) (params : const SearchParams&) -> [lbool] -| -| Description: -| Search for a model the specified number of conflicts. -| NOTE! Use negative value for 'nof_conflicts' indicate infinity. -| -| Output: -| 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If -| all variables are decision variables, this means that the clause set is satisfiable. 'l_False' -| if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached. -|________________________________________________________________________________________________@*/ -lbool Solver::search(int nof_conflicts) -{ - assert(ok); - int backtrack_level; - int conflictC = 0; - vec learnt_clause; - starts++; - - for (;;){ - CRef confl = propagate(); - if (confl != CRef_Undef){ - // CONFLICT - conflicts++; conflictC++; - if (decisionLevel() == 0) return l_False; - - learnt_clause.clear(); - analyze(confl, learnt_clause, backtrack_level); - cancelUntil(backtrack_level); - - if (learnt_clause.size() == 1){ - uncheckedEnqueue(learnt_clause[0]); - }else{ - CRef cr = ca.alloc(learnt_clause, true); - learnts.push(cr); - attachClause(cr); - claBumpActivity(ca[cr]); - uncheckedEnqueue(learnt_clause[0], cr); - } - - varDecayActivity(); - claDecayActivity(); - - if (--learntsize_adjust_cnt == 0){ - learntsize_adjust_confl *= learntsize_adjust_inc; - learntsize_adjust_cnt = (int)learntsize_adjust_confl; - max_learnts *= learntsize_inc; - - if (verbosity >= 1) - printf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n", - (int)conflicts, - (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]), nClauses(), (int)clauses_literals, - (int)max_learnts, nLearnts(), (double)learnts_literals/nLearnts(), progressEstimate()*100); - } - - }else{ - // NO CONFLICT - if (nof_conflicts >= 0 && conflictC >= nof_conflicts || !withinBudget()){ - // Reached bound on number of conflicts: - progress_estimate = progressEstimate(); - cancelUntil(0); - return l_Undef; } - - // Simplify the set of problem clauses: - if (decisionLevel() == 0 && !simplify()) - return l_False; - - if (learnts.size()-nAssigns() >= max_learnts) - // Reduce the set of learnt clauses: - reduceDB(); - - Lit next = lit_Undef; - while (decisionLevel() < assumptions.size()){ - // Perform user provided assumption: - Lit p = assumptions[decisionLevel()]; - if (value(p) == l_True){ - // Dummy decision level: - newDecisionLevel(); - }else if (value(p) == l_False){ - analyzeFinal(~p, conflict); - return l_False; - }else{ - next = p; - break; - } - } - - if (next == lit_Undef){ - // New variable decision: - decisions++; - next = pickBranchLit(); - - if (next == lit_Undef) - // Model found: - return l_True; - } - - // Increase decision level and enqueue 'next' - newDecisionLevel(); - uncheckedEnqueue(next); - } - } -} - - -double Solver::progressEstimate() const -{ - double progress = 0; - double F = 1.0 / nVars(); - - for (int i = 0; i <= decisionLevel(); i++){ - int beg = i == 0 ? 0 : trail_lim[i - 1]; - int end = i == decisionLevel() ? trail.size() : trail_lim[i]; - progress += pow(F, i) * (end - beg); - } - - return progress / nVars(); -} - -/* - Finite subsequences of the Luby-sequence: - - 0: 1 - 1: 1 1 2 - 2: 1 1 2 1 1 2 4 - 3: 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8 - ... - - - */ - -static double luby(double y, int x){ - - // Find the finite subsequence that contains index 'x', and the - // size of that subsequence: - int size, seq; - for (size = 1, seq = 0; size < x+1; seq++, size = 2*size+1); - - while (size-1 != x){ - size = (size-1)>>1; - seq--; - x = x % size; - } - - return pow(y, seq); -} - -// NOTE: assumptions passed in member-variable 'assumptions'. -lbool Solver::solve_() -{ - model.clear(); - conflict.clear(); - if (!ok) return l_False; - - solves++; - - max_learnts = nClauses() * learntsize_factor; - learntsize_adjust_confl = learntsize_adjust_start_confl; - learntsize_adjust_cnt = (int)learntsize_adjust_confl; - lbool status = l_Undef; - - if (verbosity >= 1){ - printf("============================[ Search Statistics ]==============================\n"); - printf("| Conflicts | ORIGINAL | LEARNT | Progress |\n"); - printf("| | Vars Clauses Literals | Limit Clauses Lit/Cl | |\n"); - printf("===============================================================================\n"); - } - - // Search: - int curr_restarts = 0; - while (status == l_Undef){ - double rest_base = luby_restart ? luby(restart_inc, curr_restarts) : pow(restart_inc, curr_restarts); - status = search(rest_base * restart_first); - if (!withinBudget()) break; - curr_restarts++; - } - - if (verbosity >= 1) - printf("===============================================================================\n"); - - - if (status == l_True){ - // Extend & copy model: - model.growTo(nVars()); - for (int i = 0; i < nVars(); i++) model[i] = value(i); - }else if (status == l_False && conflict.size() == 0) - ok = false; - - cancelUntil(0); - return status; -} - -//================================================================================================= -// Writing CNF to DIMACS: -// -// FIXME: this needs to be rewritten completely. - -static Var mapVar(Var x, vec& map, Var& max) -{ - if (map.size() <= x || map[x] == -1){ - map.growTo(x+1, -1); - map[x] = max++; - } - return map[x]; -} - - -void Solver::toDimacs(FILE* f, Clause& c, vec& map, Var& max) -{ - if (satisfied(c)) return; - - for (int i = 0; i < c.size(); i++) - if (value(c[i]) != l_False) - fprintf(f, "%s%d ", sign(c[i]) ? "-" : "", mapVar(var(c[i]), map, max)+1); - fprintf(f, "0\n"); -} - - -void Solver::toDimacs(const char *file, const vec& assumps) -{ - FILE* f = fopen(file, "wr"); - if (f == NULL) - fprintf(stderr, "could not open file %s\n", file), exit(1); - toDimacs(f, assumps); - fclose(f); -} - - -void Solver::toDimacs(FILE* f, const vec& assumps) -{ - // Handle case when solver is in contradictory state: - if (!ok){ - fprintf(f, "p cnf 1 2\n1 0\n-1 0\n"); - return; } - - vec map; Var max = 0; - - // Cannot use removeClauses here because it is not safe - // to deallocate them at this point. Could be improved. - int cnt = 0; - for (int i = 0; i < clauses.size(); i++) - if (!satisfied(ca[clauses[i]])) - cnt++; - - for (int i = 0; i < clauses.size(); i++) - if (!satisfied(ca[clauses[i]])){ - Clause& c = ca[clauses[i]]; - for (int j = 0; j < c.size(); j++) - if (value(c[j]) != l_False) - mapVar(var(c[j]), map, max); - } - - // Assumptions are added as unit clauses: - cnt += assumptions.size(); - - fprintf(f, "p cnf %d %d\n", max, cnt); - - for (int i = 0; i < assumptions.size(); i++){ - assert(value(assumptions[i]) != l_False); - fprintf(f, "%s%d 0\n", sign(assumptions[i]) ? "-" : "", mapVar(var(assumptions[i]), map, max)+1); - } - - for (int i = 0; i < clauses.size(); i++) - toDimacs(f, ca[clauses[i]], map, max); - - if (verbosity > 0) - printf("Wrote %d clauses with %d variables.\n", cnt, max); -} - - -//================================================================================================= -// Garbage Collection methods: - -void Solver::relocAll(ClauseAllocator& to) -{ - // All watchers: - // - // for (int i = 0; i < watches.size(); i++) - watches.cleanAll(); - for (int v = 0; v < nVars(); v++) - for (int s = 0; s < 2; s++){ - Lit p = mkLit(v, s); - // printf(" >>> RELOCING: %s%d\n", sign(p)?"-":"", var(p)+1); - vec& ws = watches[p]; - for (int j = 0; j < ws.size(); j++) - ca.reloc(ws[j].cref, to); - } - - // All reasons: - // - for (int i = 0; i < trail.size(); i++){ - Var v = var(trail[i]); - - if (reason(v) != CRef_Undef && (ca[reason(v)].reloced() || locked(ca[reason(v)]))) - ca.reloc(vardata[v].reason, to); - } - - // All learnt: - // - for (int i = 0; i < learnts.size(); i++) - ca.reloc(learnts[i], to); - - // All original: - // - for (int i = 0; i < clauses.size(); i++) - ca.reloc(clauses[i], to); -} - - -void Solver::garbageCollect() -{ - // Initialize the next region to a size corresponding to the estimated utilization degree. This - // is not precise but should avoid some unnecessary reallocations for the new region: - ClauseAllocator to(ca.size() - ca.wasted()); - - relocAll(to); - if (verbosity >= 2) - printf("| Garbage collection: %12d bytes => %12d bytes |\n", - ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size); - to.moveTo(ca); -} diff --git a/src/sat/minisat/core/Solver.h b/src/sat/minisat/core/Solver.h deleted file mode 100644 index 90119e58..00000000 --- a/src/sat/minisat/core/Solver.h +++ /dev/null @@ -1,373 +0,0 @@ -/****************************************************************************************[Solver.h] -Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_Solver_h -#define Minisat_Solver_h - -#include "mtl/Vec.h" -#include "mtl/Heap.h" -#include "mtl/Alg.h" -#include "utils/Options.h" -#include "core/SolverTypes.h" - - -namespace Minisat { - -//================================================================================================= -// Solver -- the main class: - -class Solver { -public: - - // Constructor/Destructor: - // - Solver(); - virtual ~Solver(); - - // Problem specification: - // - Var newVar (bool polarity = true, bool dvar = true); // Add a new variable with parameters specifying variable mode. - - bool addClause (const vec& ps); // Add a clause to the solver. - bool addEmptyClause(); // Add the empty clause, making the solver contradictory. - bool addClause (Lit p); // Add a unit clause to the solver. - bool addClause (Lit p, Lit q); // Add a binary clause to the solver. - bool addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver. - bool addClause_( vec& ps); // Add a clause to the solver without making superflous internal copy. Will - // change the passed vector 'ps'. - - // Solving: - // - bool simplify (); // Removes already satisfied clauses. - bool solve (const vec& assumps); // Search for a model that respects a given set of assumptions. - lbool solveLimited (const vec& assumps); // Search for a model that respects a given set of assumptions (With resource constraints). - bool solve (); // Search without assumptions. - bool solve (Lit p); // Search for a model that respects a single assumption. - bool solve (Lit p, Lit q); // Search for a model that respects two assumptions. - bool solve (Lit p, Lit q, Lit r); // Search for a model that respects three assumptions. - bool okay () const; // FALSE means solver is in a conflicting state - - void toDimacs (FILE* f, const vec& assumps); // Write CNF to file in DIMACS-format. - void toDimacs (const char *file, const vec& assumps); - void toDimacs (FILE* f, Clause& c, vec& map, Var& max); - - // Convenience versions of 'toDimacs()': - void toDimacs (const char* file); - void toDimacs (const char* file, Lit p); - void toDimacs (const char* file, Lit p, Lit q); - void toDimacs (const char* file, Lit p, Lit q, Lit r); - - // Variable mode: - // - void setPolarity (Var v, bool b); // Declare which polarity the decision heuristic should use for a variable. Requires mode 'polarity_user'. - void setDecisionVar (Var v, bool b); // Declare if a variable should be eligible for selection in the decision heuristic. - - // Read state: - // - lbool value (Var x) const; // The current value of a variable. - lbool value (Lit p) const; // The current value of a literal. - lbool modelValue (Var x) const; // The value of a variable in the last model. The last call to solve must have been satisfiable. - lbool modelValue (Lit p) const; // The value of a literal in the last model. The last call to solve must have been satisfiable. - int nAssigns () const; // The current number of assigned literals. - int nClauses () const; // The current number of original clauses. - int nLearnts () const; // The current number of learnt clauses. - int nVars () const; // The current number of variables. - int nFreeVars () const; - - // Resource contraints: - // - void setConfBudget(int64_t x); - void setPropBudget(int64_t x); - void budgetOff(); - void interrupt(); // Trigger a (potentially asynchronous) interruption of the solver. - void clearInterrupt(); // Clear interrupt indicator flag. - - // Memory managment: - // - virtual void garbageCollect(); - void checkGarbage(double gf); - void checkGarbage(); - - // Extra results: (read-only member variable) - // - vec model; // If problem is satisfiable, this vector contains the model (if any). - vec conflict; // If problem is unsatisfiable (possibly under assumptions), - // this vector represent the final conflict clause expressed in the assumptions. - - // Mode of operation: - // - int verbosity; - double var_decay; - double clause_decay; - double random_var_freq; - double random_seed; - bool luby_restart; - int ccmin_mode; // Controls conflict clause minimization (0=none, 1=basic, 2=deep). - int phase_saving; // Controls the level of phase saving (0=none, 1=limited, 2=full). - bool rnd_pol; // Use random polarities for branching heuristics. - bool rnd_init_act; // Initialize variable activities with a small random value. - double garbage_frac; // The fraction of wasted memory allowed before a garbage collection is triggered. - - int restart_first; // The initial restart limit. (default 100) - double restart_inc; // The factor with which the restart limit is multiplied in each restart. (default 1.5) - double learntsize_factor; // The intitial limit for learnt clauses is a factor of the original clauses. (default 1 / 3) - double learntsize_inc; // The limit for learnt clauses is multiplied with this factor each restart. (default 1.1) - - int learntsize_adjust_start_confl; - double learntsize_adjust_inc; - - // Statistics: (read-only member variable) - // - uint64_t solves, starts, decisions, rnd_decisions, propagations, conflicts; - uint64_t dec_vars, clauses_literals, learnts_literals, max_literals, tot_literals; - -protected: - - // Helper structures: - // - struct VarData { CRef reason; int level; }; - static inline VarData mkVarData(CRef cr, int l){ VarData d = {cr, l}; return d; } - - struct Watcher { - CRef cref; - Lit blocker; - Watcher(CRef cr, Lit p) : cref(cr), blocker(p) {} - bool operator==(const Watcher& w) const { return cref == w.cref; } - bool operator!=(const Watcher& w) const { return cref != w.cref; } - }; - - struct WatcherDeleted - { - const ClauseAllocator& ca; - WatcherDeleted(const ClauseAllocator& _ca) : ca(_ca) {} - bool operator()(const Watcher& w) const { return ca[w.cref].mark() == 1; } - }; - - struct VarOrderLt { - const vec& activity; - bool operator () (Var x, Var y) const { return activity[x] > activity[y]; } - VarOrderLt(const vec& act) : activity(act) { } - }; - - // Solver state: - // - bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used! - vec clauses; // List of problem clauses. - vec learnts; // List of learnt clauses. - double cla_inc; // Amount to bump next clause with. - vec activity; // A heuristic measurement of the activity of a variable. - double var_inc; // Amount to bump next variable with. - OccLists, WatcherDeleted> - watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true). - vec assigns; // The current assignments. - vec polarity; // The preferred polarity of each variable. - vec decision; // Declares if a variable is eligible for selection in the decision heuristic. - vec trail; // Assignment stack; stores all assigments made in the order they were made. - vec trail_lim; // Separator indices for different decision levels in 'trail'. - vec vardata; // Stores reason and level for each variable. - int qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat). - int simpDB_assigns; // Number of top-level assignments since last execution of 'simplify()'. - int64_t simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplify()'. - vec assumptions; // Current set of assumptions provided to solve by the user. - Heap order_heap; // A priority queue of variables ordered with respect to the variable activity. - double progress_estimate;// Set by 'search()'. - bool remove_satisfied; // Indicates whether possibly inefficient linear scan for satisfied clauses should be performed in 'simplify'. - - ClauseAllocator ca; - - // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is - // used, exept 'seen' wich is used in several places. - // - vec seen; - vec analyze_stack; - vec analyze_toclear; - vec add_tmp; - - double max_learnts; - double learntsize_adjust_confl; - int learntsize_adjust_cnt; - - // Resource contraints: - // - int64_t conflict_budget; // -1 means no budget. - int64_t propagation_budget; // -1 means no budget. - bool asynch_interrupt; - - // Main internal methods: - // - void insertVarOrder (Var x); // Insert a variable in the decision order priority queue. - Lit pickBranchLit (); // Return the next decision variable. - void newDecisionLevel (); // Begins a new decision level. - void uncheckedEnqueue (Lit p, CRef from = CRef_Undef); // Enqueue a literal. Assumes value of literal is undefined. - bool enqueue (Lit p, CRef from = CRef_Undef); // Test if fact 'p' contradicts current state, enqueue otherwise. - CRef propagate (); // Perform unit propagation. Returns possibly conflicting clause. - void cancelUntil (int level); // Backtrack until a certain level. - void analyze (CRef confl, vec& out_learnt, int& out_btlevel); // (bt = backtrack) - void analyzeFinal (Lit p, vec& out_conflict); // COULD THIS BE IMPLEMENTED BY THE ORDINARIY "analyze" BY SOME REASONABLE GENERALIZATION? - bool litRedundant (Lit p, uint32_t abstract_levels); // (helper method for 'analyze()') - lbool search (int nof_conflicts); // Search for a given number of conflicts. - lbool solve_ (); // Main solve method (assumptions given in 'assumptions'). - void reduceDB (); // Reduce the set of learnt clauses. - void removeSatisfied (vec& cs); // Shrink 'cs' to contain only non-satisfied clauses. - void rebuildOrderHeap (); - - // Maintaining Variable/Clause activity: - // - void varDecayActivity (); // Decay all variables with the specified factor. Implemented by increasing the 'bump' value instead. - void varBumpActivity (Var v, double inc); // Increase a variable with the current 'bump' value. - void varBumpActivity (Var v); // Increase a variable with the current 'bump' value. - void claDecayActivity (); // Decay all clauses with the specified factor. Implemented by increasing the 'bump' value instead. - void claBumpActivity (Clause& c); // Increase a clause with the current 'bump' value. - - // Operations on clauses: - // - void attachClause (CRef cr); // Attach a clause to watcher lists. - void detachClause (CRef cr, bool strict = false); // Detach a clause to watcher lists. - void removeClause (CRef cr); // Detach and free a clause. - bool locked (const Clause& c) const; // Returns TRUE if a clause is a reason for some implication in the current state. - bool satisfied (const Clause& c) const; // Returns TRUE if a clause is satisfied in the current state. - - void relocAll (ClauseAllocator& to); - - // Misc: - // - int decisionLevel () const; // Gives the current decisionlevel. - uint32_t abstractLevel (Var x) const; // Used to represent an abstraction of sets of decision levels. - CRef reason (Var x) const; - int level (Var x) const; - double progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ... - bool withinBudget () const; - - // Static helpers: - // - - // Returns a random float 0 <= x < 1. Seed must never be 0. - static inline double drand(double& seed) { - seed *= 1389796; - int q = (int)(seed / 2147483647); - seed -= (double)q * 2147483647; - return seed / 2147483647; } - - // Returns a random integer 0 <= x < size. Seed must never be 0. - static inline int irand(double& seed, int size) { - return (int)(drand(seed) * size); } -}; - - -//================================================================================================= -// Implementation of inline methods: - -inline CRef Solver::reason(Var x) const { return vardata[x].reason; } -inline int Solver::level (Var x) const { return vardata[x].level; } - -inline void Solver::insertVarOrder(Var x) { - if (!order_heap.inHeap(x) && decision[x]) order_heap.insert(x); } - -inline void Solver::varDecayActivity() { var_inc *= (1 / var_decay); } -inline void Solver::varBumpActivity(Var v) { varBumpActivity(v, var_inc); } -inline void Solver::varBumpActivity(Var v, double inc) { - if ( (activity[v] += inc) > 1e100 ) { - // Rescale: - for (int i = 0; i < nVars(); i++) - activity[i] *= 1e-100; - var_inc *= 1e-100; } - - // Update order_heap with respect to new activity: - if (order_heap.inHeap(v)) - order_heap.decrease(v); } - -inline void Solver::claDecayActivity() { cla_inc *= (1 / clause_decay); } -inline void Solver::claBumpActivity (Clause& c) { - if ( (c.activity() += cla_inc) > 1e20 ) { - // Rescale: - for (int i = 0; i < learnts.size(); i++) - ca[learnts[i]].activity() *= 1e-20; - cla_inc *= 1e-20; } } - -inline void Solver::checkGarbage(void){ return checkGarbage(garbage_frac); } -inline void Solver::checkGarbage(double gf){ - if (ca.wasted() > ca.size() * gf) - garbageCollect(); } - -// NOTE: enqueue does not set the ok flag! (only public methods do) -inline bool Solver::enqueue (Lit p, CRef from) { return value(p) != l_Undef ? value(p) != l_False : (uncheckedEnqueue(p, from), true); } -inline bool Solver::addClause (const vec& ps) { ps.copyTo(add_tmp); return addClause_(add_tmp); } -inline bool Solver::addEmptyClause () { add_tmp.clear(); return addClause_(add_tmp); } -inline bool Solver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); } -inline bool Solver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); } -inline bool Solver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); } -inline bool Solver::locked (const Clause& c) const { return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c; } -inline void Solver::newDecisionLevel() { trail_lim.push(trail.size()); } - -inline int Solver::decisionLevel () const { return trail_lim.size(); } -inline uint32_t Solver::abstractLevel (Var x) const { return 1 << (level(x) & 31); } -inline lbool Solver::value (Var x) const { return assigns[x]; } -inline lbool Solver::value (Lit p) const { return assigns[var(p)] ^ sign(p); } -inline lbool Solver::modelValue (Var x) const { return model[x]; } -inline lbool Solver::modelValue (Lit p) const { return model[var(p)] ^ sign(p); } -inline int Solver::nAssigns () const { return trail.size(); } -inline int Solver::nClauses () const { return clauses.size(); } -inline int Solver::nLearnts () const { return learnts.size(); } -inline int Solver::nVars () const { return vardata.size(); } -inline int Solver::nFreeVars () const { return (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]); } -inline void Solver::setPolarity (Var v, bool b) { polarity[v] = b; } -inline void Solver::setDecisionVar(Var v, bool b) -{ - if ( b && !decision[v]) dec_vars++; - else if (!b && decision[v]) dec_vars--; - - decision[v] = b; - insertVarOrder(v); -} -inline void Solver::setConfBudget(int64_t x){ conflict_budget = conflicts + x; } -inline void Solver::setPropBudget(int64_t x){ propagation_budget = propagations + x; } -inline void Solver::interrupt(){ asynch_interrupt = true; } -inline void Solver::clearInterrupt(){ asynch_interrupt = false; } -inline void Solver::budgetOff(){ conflict_budget = propagation_budget = -1; } -inline bool Solver::withinBudget() const { - return !asynch_interrupt && - (conflict_budget < 0 || conflicts < (uint64_t)conflict_budget) && - (propagation_budget < 0 || propagations < (uint64_t)propagation_budget); } - -// FIXME: after the introduction of asynchronous interrruptions the solve-versions that return a -// pure bool do not give a safe interface. Either interrupts must be possible to turn off here, or -// all calls to solve must return an 'lbool'. I'm not yet sure which I prefer. -inline bool Solver::solve () { budgetOff(); assumptions.clear(); return solve_() == l_True; } -inline bool Solver::solve (Lit p) { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_() == l_True; } -inline bool Solver::solve (Lit p, Lit q) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_() == l_True; } -inline bool Solver::solve (Lit p, Lit q, Lit r) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_() == l_True; } -inline bool Solver::solve (const vec& assumps){ budgetOff(); assumps.copyTo(assumptions); return solve_() == l_True; } -inline lbool Solver::solveLimited (const vec& assumps){ assumps.copyTo(assumptions); return solve_(); } -inline bool Solver::okay () const { return ok; } - -inline void Solver::toDimacs (const char* file){ vec as; toDimacs(file, as); } -inline void Solver::toDimacs (const char* file, Lit p){ vec as; as.push(p); toDimacs(file, as); } -inline void Solver::toDimacs (const char* file, Lit p, Lit q){ vec as; as.push(p); as.push(q); toDimacs(file, as); } -inline void Solver::toDimacs (const char* file, Lit p, Lit q, Lit r){ vec as; as.push(p); as.push(q); as.push(r); toDimacs(file, as); } - - -//================================================================================================= -// Debug etc: - - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/core/Solver.or b/src/sat/minisat/core/Solver.or deleted file mode 100644 index aa7f6114..00000000 Binary files a/src/sat/minisat/core/Solver.or and /dev/null differ diff --git a/src/sat/minisat/core/SolverTypes.h b/src/sat/minisat/core/SolverTypes.h deleted file mode 100644 index 1ebcc737..00000000 --- a/src/sat/minisat/core/SolverTypes.h +++ /dev/null @@ -1,407 +0,0 @@ -/***********************************************************************************[SolverTypes.h] -Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - - -#ifndef Minisat_SolverTypes_h -#define Minisat_SolverTypes_h - -#include - -#include "mtl/IntTypes.h" -#include "mtl/Alg.h" -#include "mtl/Vec.h" -#include "mtl/Map.h" -#include "mtl/Alloc.h" - -namespace Minisat { - -//================================================================================================= -// Variables, literals, lifted booleans, clauses: - - -// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N, -// so that they can be used as array indices. - -typedef int Var; -#define var_Undef (-1) - - -struct Lit { - int x; - - // Use this as a constructor: - friend Lit mkLit(Var var, bool sign = false); - - bool operator == (Lit p) const { return x == p.x; } - bool operator != (Lit p) const { return x != p.x; } - bool operator < (Lit p) const { return x < p.x; } // '<' makes p, ~p adjacent in the ordering. -}; - - -inline Lit mkLit (Var var, bool sign) { Lit p; p.x = var + var + (int)sign; return p; } -inline Lit operator ~(Lit p) { Lit q; q.x = p.x ^ 1; return q; } -inline Lit operator ^(Lit p, bool b) { Lit q; q.x = p.x ^ (unsigned int)b; return q; } -inline bool sign (Lit p) { return p.x & 1; } -inline int var (Lit p) { return p.x >> 1; } - -// Mapping Literals to and from compact integers suitable for array indexing: -inline int toInt (Var v) { return v; } -inline int toInt (Lit p) { return p.x; } -inline Lit toLit (int i) { Lit p; p.x = i; return p; } - -//const Lit lit_Undef = mkLit(var_Undef, false); // }- Useful special constants. -//const Lit lit_Error = mkLit(var_Undef, true ); // } - -const Lit lit_Undef = { -2 }; // }- Useful special constants. -const Lit lit_Error = { -1 }; // } - - -//================================================================================================= -// Lifted booleans: -// -// NOTE: this implementation is optimized for the case when comparisons between values are mostly -// between one variable and one constant. Some care had to be taken to make sure that gcc -// does enough constant propagation to produce sensible code, and this appears to be somewhat -// fragile unfortunately. - -#define l_True (lbool((uint8_t)0)) // gcc does not do constant propagation if these are real constants. -#define l_False (lbool((uint8_t)1)) -#define l_Undef (lbool((uint8_t)2)) - -class lbool { - uint8_t value; - -public: - explicit lbool(uint8_t v) : value(v) { } - - lbool() : value(0) { } - explicit lbool(bool x) : value(!x) { } - - bool operator == (lbool b) const { return ((b.value&2) & (value&2)) | (!(b.value&2)&(value == b.value)); } - bool operator != (lbool b) const { return !(*this == b); } - lbool operator ^ (bool b) const { return lbool((uint8_t)(value^(uint8_t)b)); } - - lbool operator && (lbool b) const { - uint8_t sel = (this->value << 1) | (b.value << 3); - uint8_t v = (0xF7F755F4 >> sel) & 3; - return lbool(v); } - - lbool operator || (lbool b) const { - uint8_t sel = (this->value << 1) | (b.value << 3); - uint8_t v = (0xFCFCF400 >> sel) & 3; - return lbool(v); } - - friend int toInt (lbool l); - friend lbool toLbool(int v); -}; -inline int toInt (lbool l) { return l.value; } -inline lbool toLbool(int v) { return lbool((uint8_t)v); } - -//================================================================================================= -// Clause -- a simple class for representing a clause: - -class Clause; -typedef RegionAllocator::Ref CRef; - -class Clause { - struct { - unsigned mark : 2; - unsigned learnt : 1; - unsigned has_extra : 1; - unsigned reloced : 1; - unsigned size : 27; } header; - union { Lit lit; float act; uint32_t abs; CRef rel; } data[0]; - - friend class ClauseAllocator; - - // NOTE: This constructor cannot be used directly (doesn't allocate enough memory). - template - Clause(const V& ps, bool use_extra, bool learnt) { - header.mark = 0; - header.learnt = learnt; - header.has_extra = use_extra; - header.reloced = 0; - header.size = ps.size(); - - for (int i = 0; i < ps.size(); i++) - data[i].lit = ps[i]; - - if (header.has_extra){ - if (header.learnt) - data[header.size].act = 0; - else - calcAbstraction(); } - } - -public: - void calcAbstraction() { - assert(header.has_extra); - uint32_t abstraction = 0; - for (int i = 0; i < size(); i++) - abstraction |= 1 << (var(data[i].lit) & 31); - data[header.size].abs = abstraction; } - - - int size () const { return header.size; } - void shrink (int i) { assert(i <= size()); if (header.has_extra) data[header.size-i] = data[header.size]; header.size -= i; } - void pop () { shrink(1); } - bool learnt () const { return header.learnt; } - bool has_extra () const { return header.has_extra; } - uint32_t mark () const { return header.mark; } - void mark (uint32_t m) { header.mark = m; } - const Lit& last () const { return data[header.size-1].lit; } - - bool reloced () const { return header.reloced; } - CRef relocation () const { return data[0].rel; } - void relocate (CRef c) { header.reloced = 1; data[0].rel = c; } - - // NOTE: somewhat unsafe to change the clause in-place! Must manually call 'calcAbstraction' afterwards for - // subsumption operations to behave correctly. - Lit& operator [] (int i) { return data[i].lit; } - Lit operator [] (int i) const { return data[i].lit; } - operator const Lit* (void) const { return (Lit*)data; } - - float& activity () { assert(header.has_extra); return data[header.size].act; } - uint32_t abstraction () const { assert(header.has_extra); return data[header.size].abs; } - - Lit subsumes (const Clause& other) const; - void strengthen (Lit p); -}; - - -//================================================================================================= -// ClauseAllocator -- a simple class for allocating memory for clauses: - - -const CRef CRef_Undef = RegionAllocator::Ref_Undef; -class ClauseAllocator : public RegionAllocator -{ - static int clauseWord32Size(int size, bool has_extra){ - return (sizeof(Clause) + (sizeof(Lit) * (size + (int)has_extra))) / sizeof(uint32_t); } - public: - bool extra_clause_field; - - ClauseAllocator(uint32_t start_cap) : RegionAllocator(start_cap), extra_clause_field(false){} - ClauseAllocator() : extra_clause_field(false){} - - void moveTo(ClauseAllocator& to){ - to.extra_clause_field = extra_clause_field; - RegionAllocator::moveTo(to); } - - template - CRef alloc(const Lits& ps, bool learnt = false) - { - assert(sizeof(Lit) == sizeof(uint32_t)); - assert(sizeof(float) == sizeof(uint32_t)); - bool use_extra = learnt | extra_clause_field; - - CRef cid = RegionAllocator::alloc(clauseWord32Size(ps.size(), use_extra)); - new (lea(cid)) Clause(ps, use_extra, learnt); - - return cid; - } - - // Deref, Load Effective Address (LEA), Inverse of LEA (AEL): - Clause& operator[](Ref r) { return (Clause&)RegionAllocator::operator[](r); } - const Clause& operator[](Ref r) const { return (Clause&)RegionAllocator::operator[](r); } - Clause* lea (Ref r) { return (Clause*)RegionAllocator::lea(r); } - const Clause* lea (Ref r) const { return (Clause*)RegionAllocator::lea(r); } - Ref ael (const Clause* t){ return RegionAllocator::ael((uint32_t*)t); } - - void free(CRef cid) - { - Clause& c = operator[](cid); - RegionAllocator::free(clauseWord32Size(c.size(), c.has_extra())); - } - - void reloc(CRef& cr, ClauseAllocator& to) - { - Clause& c = operator[](cr); - - if (c.reloced()) { cr = c.relocation(); return; } - - cr = to.alloc(c, c.learnt()); - c.relocate(cr); - - // Copy extra data-fields: - // (This could be cleaned-up. Generalize Clause-constructor to be applicable here instead?) - to[cr].mark(c.mark()); - if (to[cr].learnt()) to[cr].activity() = c.activity(); - else if (to[cr].has_extra()) to[cr].calcAbstraction(); - } -}; - - -//================================================================================================= -// OccLists -- a class for maintaining occurence lists with lazy deletion: - -template -class OccLists -{ - vec occs; - vec dirty; - vec dirties; - Deleted deleted; - - public: - OccLists(const Deleted& d) : deleted(d) {} - - void init (const Idx& idx){ occs.growTo(toInt(idx)+1); dirty.growTo(toInt(idx)+1, 0); } - // Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; } - Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; } - Vec& lookup (const Idx& idx){ if (dirty[toInt(idx)]) clean(idx); return occs[toInt(idx)]; } - - void cleanAll (); - void clean (const Idx& idx); - void smudge (const Idx& idx){ - if (dirty[toInt(idx)] == 0){ - dirty[toInt(idx)] = 1; - dirties.push(idx); - } - } - - void clear(bool free = true){ - occs .clear(free); - dirty .clear(free); - dirties.clear(free); - } -}; - - -template -void OccLists::cleanAll() -{ - for (int i = 0; i < dirties.size(); i++) - // Dirties may contain duplicates so check here if a variable is already cleaned: - if (dirty[toInt(dirties[i])]) - clean(dirties[i]); - dirties.clear(); -} - - -template -void OccLists::clean(const Idx& idx) -{ - Vec& vec = occs[toInt(idx)]; - int i, j; - for (i = j = 0; i < vec.size(); i++) - if (!deleted(vec[i])) - vec[j++] = vec[i]; - vec.shrink(i - j); - dirty[toInt(idx)] = 0; -} - - -//================================================================================================= -// CMap -- a class for mapping clauses to values: - - -template -class CMap -{ - struct CRefHash { - uint32_t operator()(CRef cr) const { return (uint32_t)cr; } }; - - typedef Map HashTable; - HashTable map; - - public: - // Size-operations: - void clear () { map.clear(); } - int size () const { return map.elems(); } - - - // Insert/Remove/Test mapping: - void insert (CRef cr, const T& t){ map.insert(cr, t); } - void growTo (CRef cr, const T& t){ map.insert(cr, t); } // NOTE: for compatibility - void remove (CRef cr) { map.remove(cr); } - bool has (CRef cr, T& t) { return map.peek(cr, t); } - - // Vector interface (the clause 'c' must already exist): - const T& operator [] (CRef cr) const { return map[cr]; } - T& operator [] (CRef cr) { return map[cr]; } - - // Iteration (not transparent at all at the moment): - int bucket_count() const { return map.bucket_count(); } - const vec& bucket(int i) const { return map.bucket(i); } - - // Move contents to other map: - void moveTo(CMap& other){ map.moveTo(other.map); } - - // TMP debug: - void debug(){ - printf(" --- size = %d, bucket_count = %d\n", size(), map.bucket_count()); } -}; - - -/*_________________________________________________________________________________________________ -| -| subsumes : (other : const Clause&) -> Lit -| -| Description: -| Checks if clause subsumes 'other', and at the same time, if it can be used to simplify 'other' -| by subsumption resolution. -| -| Result: -| lit_Error - No subsumption or simplification -| lit_Undef - Clause subsumes 'other' -| p - The literal p can be deleted from 'other' -|________________________________________________________________________________________________@*/ -inline Lit Clause::subsumes(const Clause& other) const -{ - //if (other.size() < size() || (extra.abst & ~other.extra.abst) != 0) - //if (other.size() < size() || (!learnt() && !other.learnt() && (extra.abst & ~other.extra.abst) != 0)) - assert(!header.learnt); assert(!other.header.learnt); - assert(header.has_extra); assert(other.header.has_extra); - if (other.header.size < header.size || (data[header.size].abs & ~other.data[other.header.size].abs) != 0) - return lit_Error; - - Lit ret = lit_Undef; - const Lit* c = (const Lit*)(*this); - const Lit* d = (const Lit*)other; - - for (unsigned i = 0; i < header.size; i++) { - // search for c[i] or ~c[i] - for (unsigned j = 0; j < other.header.size; j++) - if (c[i] == d[j]) - goto ok; - else if (ret == lit_Undef && c[i] == ~d[j]){ - ret = c[i]; - goto ok; - } - - // did not find it - return lit_Error; - ok:; - } - - return ret; -} - -inline void Clause::strengthen(Lit p) -{ - remove(*this, p); - calcAbstraction(); -} - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/core/depend.mk b/src/sat/minisat/core/depend.mk deleted file mode 100644 index 26302da5..00000000 --- a/src/sat/minisat/core/depend.mk +++ /dev/null @@ -1,37 +0,0 @@ -/home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Main.o /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Main.or /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Main.od /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Main.op: /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Main.cc \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/utils/System.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/IntTypes.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/utils/ParseUtils.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/utils/Options.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Vec.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/IntTypes.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/XAlloc.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/utils/ParseUtils.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Dimacs.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/SolverTypes.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/IntTypes.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Alg.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Vec.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Vec.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Map.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Alloc.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Solver.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Heap.h -/home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Solver.o /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Solver.or /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Solver.od /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Solver.op: \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Solver.cc \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Sort.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Vec.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/IntTypes.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/XAlloc.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/Solver.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Vec.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Heap.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Alg.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/utils/Options.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/IntTypes.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Vec.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/utils/ParseUtils.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/core/SolverTypes.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/IntTypes.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Map.h \ - /home/ric/class/dspf10/fraig/sol/src/sat/minisat/mtl/Alloc.h diff --git a/src/sat/minisat/doc/ReleaseNotes-2.2.0.txt b/src/sat/minisat/doc/ReleaseNotes-2.2.0.txt deleted file mode 100644 index 7f084de2..00000000 --- a/src/sat/minisat/doc/ReleaseNotes-2.2.0.txt +++ /dev/null @@ -1,79 +0,0 @@ -Release Notes for MiniSat 2.2.0 -=============================== - -Changes since version 2.0: - - * Started using a more standard release numbering. - - * Includes some now well-known heuristics: phase-saving and luby - restarts. The old heuristics are still present and can be activated - if needed. - - * Detection/Handling of out-of-memory and vector capacity - overflow. This is fairly new and relatively untested. - - * Simple resource controls: CPU-time, memory, number of - conflicts/decisions. - - * CPU-time limiting is implemented by a more general, but simple, - asynchronous interruption feature. This means that the solving - procedure can be interrupted from another thread or in a signal - handler. - - * Improved portability with respect to building on Solaris and with - Visual Studio. This is not regularly tested and chances are that - this have been broken since, but should be fairly easy to fix if - so. - - * Changed C++ file-extention to the less problematic ".cc". - - * Source code is now namespace-protected - - * Introducing a new Clause Memory Allocator that brings reduced - memory consumption on 64-bit architechtures and improved - performance (to some extent). The allocator uses a region-based - approach were all references to clauses are represented as a 32-bit - index into a global memory region that contains all clauses. To - free up and compact memory it uses a simple copying garbage - collector. - - * Improved unit-propagation by Blocking Literals. For each entry in - the watcher lists, pair the pointer to a clause with some - (arbitrary) literal from the clause. The idea is that if the - literal is currently true (i.e. the clause is satisfied) the - watchers of the clause does not need to be altered. This can thus - be detected without touching the clause's memory at all. As often - as can be done cheaply, the blocking literal for entries to the - watcher list of a literal 'p' is set to the other literal watched - in the corresponding clause. - - * Basic command-line/option handling system. Makes it easy to specify - options in the class that they affect, and whenever that class is - used in an executable, parsing of options and help messages are - brought in automatically. - - * General clean-up and various minor bug-fixes. - - * Changed implementation of variable-elimination/model-extension: - - - The interface is changed so that arbitrary remembering is no longer - possible. If you need to mention some variable again in the future, - this variable has to be frozen. - - - When eliminating a variable, only clauses that contain the variable - with one sign is necessary to store. Thereby making the other sign - a "default" value when extending models. - - - The memory consumption for eliminated clauses is further improved - by storing all eliminated clauses in a single contiguous vector. - - * Some common utility code (I/O, Parsing, CPU-time, etc) is ripped - out and placed in a separate "utils" directory. - - * The DIMACS parse is refactored so that it can be reused in other - applications (not very elegant, but at least possible). - - * Some simple improvements to scalability of preprocessing, using - more lazy clause removal from data-structures and a couple of - ad-hoc limits (the longest clause that can be produced in variable - elimination, and the longest clause used in backward subsumption). diff --git a/src/sat/minisat/mtl/Alg.h b/src/sat/minisat/mtl/Alg.h deleted file mode 100644 index bb1ee5ad..00000000 --- a/src/sat/minisat/mtl/Alg.h +++ /dev/null @@ -1,84 +0,0 @@ -/*******************************************************************************************[Alg.h] -Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_Alg_h -#define Minisat_Alg_h - -#include "mtl/Vec.h" - -namespace Minisat { - -//================================================================================================= -// Useful functions on vector-like types: - -//================================================================================================= -// Removing and searching for elements: -// - -template -static inline void remove(V& ts, const T& t) -{ - int j = 0; - for (; j < ts.size() && ts[j] != t; j++); - assert(j < ts.size()); - for (; j < ts.size()-1; j++) ts[j] = ts[j+1]; - ts.pop(); -} - - -template -static inline bool find(V& ts, const T& t) -{ - int j = 0; - for (; j < ts.size() && ts[j] != t; j++); - return j < ts.size(); -} - - -//================================================================================================= -// Copying vectors with support for nested vector types: -// - -// Base case: -template -static inline void copy(const T& from, T& to) -{ - to = from; -} - -// Recursive case: -template -static inline void copy(const vec& from, vec& to, bool append = false) -{ - if (!append) - to.clear(); - for (int i = 0; i < from.size(); i++){ - to.push(); - copy(from[i], to.last()); - } -} - -template -static inline void append(const vec& from, vec& to){ copy(from, to, true); } - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/mtl/Alloc.h b/src/sat/minisat/mtl/Alloc.h deleted file mode 100644 index 76322b8b..00000000 --- a/src/sat/minisat/mtl/Alloc.h +++ /dev/null @@ -1,131 +0,0 @@ -/*****************************************************************************************[Alloc.h] -Copyright (c) 2008-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - - -#ifndef Minisat_Alloc_h -#define Minisat_Alloc_h - -#include "mtl/XAlloc.h" -#include "mtl/Vec.h" - -namespace Minisat { - -//================================================================================================= -// Simple Region-based memory allocator: - -template -class RegionAllocator -{ - T* memory; - uint32_t sz; - uint32_t cap; - uint32_t wasted_; - - void capacity(uint32_t min_cap); - - public: - // TODO: make this a class for better type-checking? - typedef uint32_t Ref; - enum { Ref_Undef = UINT32_MAX }; - enum { Unit_Size = sizeof(uint32_t) }; - - explicit RegionAllocator(uint32_t start_cap = 1024*1024) : memory(NULL), sz(0), cap(0), wasted_(0){ capacity(start_cap); } - ~RegionAllocator() - { - if (memory != NULL) - ::free(memory); - } - - - uint32_t size () const { return sz; } - uint32_t wasted () const { return wasted_; } - - Ref alloc (int size); - void free (int size) { wasted_ += size; } - - // Deref, Load Effective Address (LEA), Inverse of LEA (AEL): - T& operator[](Ref r) { assert(r >= 0 && r < sz); return memory[r]; } - const T& operator[](Ref r) const { assert(r >= 0 && r < sz); return memory[r]; } - - T* lea (Ref r) { assert(r >= 0 && r < sz); return &memory[r]; } - const T* lea (Ref r) const { assert(r >= 0 && r < sz); return &memory[r]; } - Ref ael (const T* t) { assert((void*)t >= (void*)&memory[0] && (void*)t < (void*)&memory[sz-1]); - return (Ref)(t - &memory[0]); } - - void moveTo(RegionAllocator& to) { - if (to.memory != NULL) ::free(to.memory); - to.memory = memory; - to.sz = sz; - to.cap = cap; - to.wasted_ = wasted_; - - memory = NULL; - sz = cap = wasted_ = 0; - } - - -}; - -template -void RegionAllocator::capacity(uint32_t min_cap) -{ - if (cap >= min_cap) return; - - uint32_t prev_cap = cap; - while (cap < min_cap){ - // NOTE: Multiply by a factor (13/8) without causing overflow, then add 2 and make the - // result even by clearing the least significant bit. The resulting sequence of capacities - // is carefully chosen to hit a maximum capacity that is close to the '2^32-1' limit when - // using 'uint32_t' as indices so that as much as possible of this space can be used. - uint32_t delta = ((cap >> 1) + (cap >> 3) + 2) & ~1; - cap += delta; - - if (cap <= prev_cap) - throw OutOfMemoryException(); - } - // printf(" .. (%p) cap = %u\n", this, cap); - - assert(cap > 0); - memory = (T*)xrealloc(memory, sizeof(T)*cap); -} - - -template -typename RegionAllocator::Ref -RegionAllocator::alloc(int size) -{ - // printf("ALLOC called (this = %p, size = %d)\n", this, size); fflush(stdout); - assert(size > 0); - capacity(sz + size); - - uint32_t prev_sz = sz; - sz += size; - - // Handle overflow: - if (sz < prev_sz) - throw OutOfMemoryException(); - - return prev_sz; -} - - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/mtl/Heap.h b/src/sat/minisat/mtl/Heap.h deleted file mode 100644 index 226407e7..00000000 --- a/src/sat/minisat/mtl/Heap.h +++ /dev/null @@ -1,148 +0,0 @@ -/******************************************************************************************[Heap.h] -Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_Heap_h -#define Minisat_Heap_h - -#include "mtl/Vec.h" - -namespace Minisat { - -//================================================================================================= -// A heap implementation with support for decrease/increase key. - - -template -class Heap { - Comp lt; // The heap is a minimum-heap with respect to this comparator - vec heap; // Heap of integers - vec indices; // Each integers position (index) in the Heap - - // Index "traversal" functions - static inline int left (int i) { return i*2+1; } - static inline int right (int i) { return (i+1)*2; } - static inline int parent(int i) { return (i-1) >> 1; } - - - void percolateUp(int i) - { - int x = heap[i]; - int p = parent(i); - - while (i != 0 && lt(x, heap[p])){ - heap[i] = heap[p]; - indices[heap[p]] = i; - i = p; - p = parent(p); - } - heap [i] = x; - indices[x] = i; - } - - - void percolateDown(int i) - { - int x = heap[i]; - while (left(i) < heap.size()){ - int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i); - if (!lt(heap[child], x)) break; - heap[i] = heap[child]; - indices[heap[i]] = i; - i = child; - } - heap [i] = x; - indices[x] = i; - } - - - public: - Heap(const Comp& c) : lt(c) { } - - int size () const { return heap.size(); } - bool empty () const { return heap.size() == 0; } - bool inHeap (int n) const { return n < indices.size() && indices[n] >= 0; } - int operator[](int index) const { assert(index < heap.size()); return heap[index]; } - - - void decrease (int n) { assert(inHeap(n)); percolateUp (indices[n]); } - void increase (int n) { assert(inHeap(n)); percolateDown(indices[n]); } - - - // Safe variant of insert/decrease/increase: - void update(int n) - { - if (!inHeap(n)) - insert(n); - else { - percolateUp(indices[n]); - percolateDown(indices[n]); } - } - - - void insert(int n) - { - indices.growTo(n+1, -1); - assert(!inHeap(n)); - - indices[n] = heap.size(); - heap.push(n); - percolateUp(indices[n]); - } - - - int removeMin() - { - int x = heap[0]; - heap[0] = heap.last(); - indices[heap[0]] = 0; - indices[x] = -1; - heap.pop(); - if (heap.size() > 1) percolateDown(0); - return x; - } - - - // Rebuild the heap from scratch, using the elements in 'ns': - void build(vec& ns) { - for (int i = 0; i < heap.size(); i++) - indices[heap[i]] = -1; - heap.clear(); - - for (int i = 0; i < ns.size(); i++){ - indices[ns[i]] = i; - heap.push(ns[i]); } - - for (int i = heap.size() / 2 - 1; i >= 0; i--) - percolateDown(i); - } - - void clear(bool dealloc = false) - { - for (int i = 0; i < heap.size(); i++) - indices[heap[i]] = -1; - heap.clear(dealloc); - } -}; - - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/mtl/IntTypes.h b/src/sat/minisat/mtl/IntTypes.h deleted file mode 100644 index c4881628..00000000 --- a/src/sat/minisat/mtl/IntTypes.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************************[IntTypes.h] -Copyright (c) 2009-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_IntTypes_h -#define Minisat_IntTypes_h - -#ifdef __sun - // Not sure if there are newer versions that support C99 headers. The - // needed features are implemented in the headers below though: - -# include -# include -# include - -#else - -# include -# include - -#endif - -#include - -//================================================================================================= - -#endif diff --git a/src/sat/minisat/mtl/Map.h b/src/sat/minisat/mtl/Map.h deleted file mode 100644 index 8a82d0e2..00000000 --- a/src/sat/minisat/mtl/Map.h +++ /dev/null @@ -1,193 +0,0 @@ -/*******************************************************************************************[Map.h] -Copyright (c) 2006-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_Map_h -#define Minisat_Map_h - -#include "mtl/IntTypes.h" -#include "mtl/Vec.h" - -namespace Minisat { - -//================================================================================================= -// Default hash/equals functions -// - -template struct Hash { uint32_t operator()(const K& k) const { return hash(k); } }; -template struct Equal { bool operator()(const K& k1, const K& k2) const { return k1 == k2; } }; - -template struct DeepHash { uint32_t operator()(const K* k) const { return hash(*k); } }; -template struct DeepEqual { bool operator()(const K* k1, const K* k2) const { return *k1 == *k2; } }; - -static inline uint32_t hash(uint32_t x){ return x; } -static inline uint32_t hash(uint64_t x){ return (uint32_t)x; } -static inline uint32_t hash(int32_t x) { return (uint32_t)x; } -static inline uint32_t hash(int64_t x) { return (uint32_t)x; } - - -//================================================================================================= -// Some primes -// - -static const int nprimes = 25; -static const int primes [nprimes] = { 31, 73, 151, 313, 643, 1291, 2593, 5233, 10501, 21013, 42073, 84181, 168451, 337219, 674701, 1349473, 2699299, 5398891, 10798093, 21596719, 43193641, 86387383, 172775299, 345550609, 691101253 }; - -//================================================================================================= -// Hash table implementation of Maps -// - -template, class E = Equal > -class Map { - public: - struct Pair { K key; D data; }; - - private: - H hash; - E equals; - - vec* table; - int cap; - int size; - - // Don't allow copying (error prone): - Map& operator = (Map& other) { assert(0); } - Map (Map& other) { assert(0); } - - bool checkCap(int new_size) const { return new_size > cap; } - - int32_t index (const K& k) const { return hash(k) % cap; } - void _insert (const K& k, const D& d) { - vec& ps = table[index(k)]; - ps.push(); ps.last().key = k; ps.last().data = d; } - - void rehash () { - const vec* old = table; - - int old_cap = cap; - int newsize = primes[0]; - for (int i = 1; newsize <= cap && i < nprimes; i++) - newsize = primes[i]; - - table = new vec[newsize]; - cap = newsize; - - for (int i = 0; i < old_cap; i++){ - for (int j = 0; j < old[i].size(); j++){ - _insert(old[i][j].key, old[i][j].data); }} - - delete [] old; - - // printf(" --- rehashing, old-cap=%d, new-cap=%d\n", cap, newsize); - } - - - public: - - Map () : table(NULL), cap(0), size(0) {} - Map (const H& h, const E& e) : hash(h), equals(e), table(NULL), cap(0), size(0){} - ~Map () { delete [] table; } - - // PRECONDITION: the key must already exist in the map. - const D& operator [] (const K& k) const - { - assert(size != 0); - const D* res = NULL; - const vec& ps = table[index(k)]; - for (int i = 0; i < ps.size(); i++) - if (equals(ps[i].key, k)) - res = &ps[i].data; - assert(res != NULL); - return *res; - } - - // PRECONDITION: the key must already exist in the map. - D& operator [] (const K& k) - { - assert(size != 0); - D* res = NULL; - vec& ps = table[index(k)]; - for (int i = 0; i < ps.size(); i++) - if (equals(ps[i].key, k)) - res = &ps[i].data; - assert(res != NULL); - return *res; - } - - // PRECONDITION: the key must *NOT* exist in the map. - void insert (const K& k, const D& d) { if (checkCap(size+1)) rehash(); _insert(k, d); size++; } - bool peek (const K& k, D& d) const { - if (size == 0) return false; - const vec& ps = table[index(k)]; - for (int i = 0; i < ps.size(); i++) - if (equals(ps[i].key, k)){ - d = ps[i].data; - return true; } - return false; - } - - bool has (const K& k) const { - if (size == 0) return false; - const vec& ps = table[index(k)]; - for (int i = 0; i < ps.size(); i++) - if (equals(ps[i].key, k)) - return true; - return false; - } - - // PRECONDITION: the key must exist in the map. - void remove(const K& k) { - assert(table != NULL); - vec& ps = table[index(k)]; - int j = 0; - for (; j < ps.size() && !equals(ps[j].key, k); j++); - assert(j < ps.size()); - ps[j] = ps.last(); - ps.pop(); - size--; - } - - void clear () { - cap = size = 0; - delete [] table; - table = NULL; - } - - int elems() const { return size; } - int bucket_count() const { return cap; } - - // NOTE: the hash and equality objects are not moved by this method: - void moveTo(Map& other){ - delete [] other.table; - - other.table = table; - other.cap = cap; - other.size = size; - - table = NULL; - size = cap = 0; - } - - // NOTE: given a bit more time, I could make a more C++-style iterator out of this: - const vec& bucket(int i) const { return table[i]; } -}; - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/mtl/Queue.h b/src/sat/minisat/mtl/Queue.h deleted file mode 100644 index 17567d69..00000000 --- a/src/sat/minisat/mtl/Queue.h +++ /dev/null @@ -1,69 +0,0 @@ -/*****************************************************************************************[Queue.h] -Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_Queue_h -#define Minisat_Queue_h - -#include "mtl/Vec.h" - -namespace Minisat { - -//================================================================================================= - -template -class Queue { - vec buf; - int first; - int end; - -public: - typedef T Key; - - Queue() : buf(1), first(0), end(0) {} - - void clear (bool dealloc = false) { buf.clear(dealloc); buf.growTo(1); first = end = 0; } - int size () const { return (end >= first) ? end - first : end - first + buf.size(); } - - const T& operator [] (int index) const { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; } - T& operator [] (int index) { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; } - - T peek () const { assert(first != end); return buf[first]; } - void pop () { assert(first != end); first++; if (first == buf.size()) first = 0; } - void insert(T elem) { // INVARIANT: buf[end] is always unused - buf[end++] = elem; - if (end == buf.size()) end = 0; - if (first == end){ // Resize: - vec tmp((buf.size()*3 + 1) >> 1); - //**/printf("queue alloc: %d elems (%.1f MB)\n", tmp.size(), tmp.size() * sizeof(T) / 1000000.0); - int i = 0; - for (int j = first; j < buf.size(); j++) tmp[i++] = buf[j]; - for (int j = 0 ; j < end ; j++) tmp[i++] = buf[j]; - first = 0; - end = buf.size(); - tmp.moveTo(buf); - } - } -}; - - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/mtl/Sort.h b/src/sat/minisat/mtl/Sort.h deleted file mode 100644 index e9313ef8..00000000 --- a/src/sat/minisat/mtl/Sort.h +++ /dev/null @@ -1,98 +0,0 @@ -/******************************************************************************************[Sort.h] -Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_Sort_h -#define Minisat_Sort_h - -#include "mtl/Vec.h" - -//================================================================================================= -// Some sorting algorithms for vec's - - -namespace Minisat { - -template -struct LessThan_default { - bool operator () (T x, T y) { return x < y; } -}; - - -template -void selectionSort(T* array, int size, LessThan lt) -{ - int i, j, best_i; - T tmp; - - for (i = 0; i < size-1; i++){ - best_i = i; - for (j = i+1; j < size; j++){ - if (lt(array[j], array[best_i])) - best_i = j; - } - tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp; - } -} -template static inline void selectionSort(T* array, int size) { - selectionSort(array, size, LessThan_default()); } - -template -void sort(T* array, int size, LessThan lt) -{ - if (size <= 15) - selectionSort(array, size, lt); - - else{ - T pivot = array[size / 2]; - T tmp; - int i = -1; - int j = size; - - for(;;){ - do i++; while(lt(array[i], pivot)); - do j--; while(lt(pivot, array[j])); - - if (i >= j) break; - - tmp = array[i]; array[i] = array[j]; array[j] = tmp; - } - - sort(array , i , lt); - sort(&array[i], size-i, lt); - } -} -template static inline void sort(T* array, int size) { - sort(array, size, LessThan_default()); } - - -//================================================================================================= -// For 'vec's: - - -template void sort(vec& v, LessThan lt) { - sort((T*)v, v.size(), lt); } -template void sort(vec& v) { - sort(v, LessThan_default()); } - - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/mtl/Vec.h b/src/sat/minisat/mtl/Vec.h deleted file mode 100644 index 9e220852..00000000 --- a/src/sat/minisat/mtl/Vec.h +++ /dev/null @@ -1,130 +0,0 @@ -/*******************************************************************************************[Vec.h] -Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_Vec_h -#define Minisat_Vec_h - -#include -#include - -#include "mtl/IntTypes.h" -#include "mtl/XAlloc.h" - -namespace Minisat { - -//================================================================================================= -// Automatically resizable arrays -// -// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc) - -template -class vec { - T* data; - int sz; - int cap; - - // Don't allow copying (error prone): - vec& operator = (vec& other) { assert(0); return *this; } - vec (vec& other) { assert(0); } - - // Helpers for calculating next capacity: - static inline int imax (int x, int y) { int mask = (y-x) >> (sizeof(int)*8-1); return (x&mask) + (y&(~mask)); } - //static inline void nextCap(int& cap){ cap += ((cap >> 1) + 2) & ~1; } - static inline void nextCap(int& cap){ cap += ((cap >> 1) + 2) & ~1; } - -public: - // Constructors: - vec() : data(NULL) , sz(0) , cap(0) { } - explicit vec(int size) : data(NULL) , sz(0) , cap(0) { growTo(size); } - vec(int size, const T& pad) : data(NULL) , sz(0) , cap(0) { growTo(size, pad); } - ~vec() { clear(true); } - - // Pointer to first element: - operator T* (void) { return data; } - - // Size operations: - int size (void) const { return sz; } - void shrink (int nelems) { assert(nelems <= sz); for (int i = 0; i < nelems; i++) sz--, data[sz].~T(); } - void shrink_ (int nelems) { assert(nelems <= sz); sz -= nelems; } - int capacity (void) const { return cap; } - void capacity (int min_cap); - void growTo (int size); - void growTo (int size, const T& pad); - void clear (bool dealloc = false); - - // Stack interface: - void push (void) { if (sz == cap) capacity(sz+1); new (&data[sz]) T(); sz++; } - void push (const T& elem) { if (sz == cap) capacity(sz+1); data[sz++] = elem; } - void push_ (const T& elem) { assert(sz < cap); data[sz++] = elem; } - void pop (void) { assert(sz > 0); sz--, data[sz].~T(); } - // NOTE: it seems possible that overflow can happen in the 'sz+1' expression of 'push()', but - // in fact it can not since it requires that 'cap' is equal to INT_MAX. This in turn can not - // happen given the way capacities are calculated (below). Essentially, all capacities are - // even, but INT_MAX is odd. - - const T& last (void) const { return data[sz-1]; } - T& last (void) { return data[sz-1]; } - - // Vector interface: - const T& operator [] (int index) const { return data[index]; } - T& operator [] (int index) { return data[index]; } - - // Duplicatation (preferred instead): - void copyTo(vec& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; } - void moveTo(vec& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; } -}; - - -template -void vec::capacity(int min_cap) { - if (cap >= min_cap) return; - int add = imax((min_cap - cap + 1) & ~1, ((cap >> 1) + 2) & ~1); // NOTE: grow by approximately 3/2 - if (add > INT_MAX - cap || ((data = (T*)::realloc(data, (cap += add) * sizeof(T))) == NULL) && errno == ENOMEM) - throw OutOfMemoryException(); - } - - -template -void vec::growTo(int size, const T& pad) { - if (sz >= size) return; - capacity(size); - for (int i = sz; i < size; i++) data[i] = pad; - sz = size; } - - -template -void vec::growTo(int size) { - if (sz >= size) return; - capacity(size); - for (int i = sz; i < size; i++) new (&data[i]) T(); - sz = size; } - - -template -void vec::clear(bool dealloc) { - if (data != NULL){ - for (int i = 0; i < sz; i++) data[i].~T(); - sz = 0; - if (dealloc) free(data), data = NULL, cap = 0; } } - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/mtl/XAlloc.h b/src/sat/minisat/mtl/XAlloc.h deleted file mode 100644 index 1da17602..00000000 --- a/src/sat/minisat/mtl/XAlloc.h +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************[XAlloc.h] -Copyright (c) 2009-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - - -#ifndef Minisat_XAlloc_h -#define Minisat_XAlloc_h - -#include -#include - -namespace Minisat { - -//================================================================================================= -// Simple layer on top of malloc/realloc to catch out-of-memory situtaions and provide some typing: - -class OutOfMemoryException{}; -static inline void* xrealloc(void *ptr, size_t size) -{ - void* mem = realloc(ptr, size); - if (mem == NULL && errno == ENOMEM){ - throw OutOfMemoryException(); - }else - return mem; -} - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/mtl/config.mk b/src/sat/minisat/mtl/config.mk deleted file mode 100644 index b5c36fc6..00000000 --- a/src/sat/minisat/mtl/config.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## This file is for system specific configurations. For instance, on -## some systems the path to zlib needs to be added. Example: -## -## CFLAGS += -I/usr/local/include -## LFLAGS += -L/usr/local/lib diff --git a/src/sat/minisat/mtl/template.mk b/src/sat/minisat/mtl/template.mk deleted file mode 100644 index 3f443fc3..00000000 --- a/src/sat/minisat/mtl/template.mk +++ /dev/null @@ -1,107 +0,0 @@ -## -## Template makefile for Standard, Profile, Debug, Release, and Release-static versions -## -## eg: "make rs" for a statically linked release version. -## "make d" for a debug version (no optimizations). -## "make" for the standard version (optimized, but with debug information and assertions active) - -PWD = $(shell pwd) -EXEC ?= $(notdir $(PWD)) - -CSRCS = $(wildcard $(PWD)/*.cc) -DSRCS = $(foreach dir, $(DEPDIR), $(filter-out $(MROOT)/$(dir)/Main.cc, $(wildcard $(MROOT)/$(dir)/*.cc))) -CHDRS = $(wildcard $(PWD)/*.h) -COBJS = $(CSRCS:.cc=.o) $(DSRCS:.cc=.o) - -PCOBJS = $(addsuffix p, $(COBJS)) -DCOBJS = $(addsuffix d, $(COBJS)) -RCOBJS = $(addsuffix r, $(COBJS)) - - -CXX ?= g++ -CFLAGS ?= -Wall -Wno-parentheses -LFLAGS ?= -Wall - -COPTIMIZE ?= -O3 - -CFLAGS += -I$(MROOT) -D __STDC_LIMIT_MACROS -D __STDC_FORMAT_MACROS -LFLAGS += -lz - -.PHONY : s p d r rs clean - -s: $(EXEC) -p: $(EXEC)_profile -d: $(EXEC)_debug -r: $(EXEC)_release -rs: $(EXEC)_static - -libs: lib$(LIB)_standard.a -libp: lib$(LIB)_profile.a -libd: lib$(LIB)_debug.a -libr: lib$(LIB)_release.a - -## Compile options -%.o: CFLAGS +=$(COPTIMIZE) -g -D DEBUG -%.op: CFLAGS +=$(COPTIMIZE) -pg -g -D NDEBUG -%.od: CFLAGS +=-O0 -g -D DEBUG -%.or: CFLAGS +=$(COPTIMIZE) -g -D NDEBUG - -## Link options -$(EXEC): LFLAGS += -g -$(EXEC)_profile: LFLAGS += -g -pg -$(EXEC)_debug: LFLAGS += -g -#$(EXEC)_release: LFLAGS += ... -$(EXEC)_static: LFLAGS += --static - -## Dependencies -$(EXEC): $(COBJS) -$(EXEC)_profile: $(PCOBJS) -$(EXEC)_debug: $(DCOBJS) -$(EXEC)_release: $(RCOBJS) -$(EXEC)_static: $(RCOBJS) - -lib$(LIB)_standard.a: $(filter-out */Main.o, $(COBJS)) -lib$(LIB)_profile.a: $(filter-out */Main.op, $(PCOBJS)) -lib$(LIB)_debug.a: $(filter-out */Main.od, $(DCOBJS)) -lib$(LIB)_release.a: $(filter-out */Main.or, $(RCOBJS)) - - -## Build rule -%.o %.op %.od %.or: %.cc - @echo Compiling: $(subst $(MROOT)/,,$@) - @$(CXX) $(CFLAGS) -c -o $@ $< - -## Linking rules (standard/profile/debug/release) -$(EXEC) $(EXEC)_profile $(EXEC)_debug $(EXEC)_release $(EXEC)_static: - @echo Linking: "$@ ( $(foreach f,$^,$(subst $(MROOT)/,,$f)) )" - @$(CXX) $^ $(LFLAGS) -o $@ - -## Library rules (standard/profile/debug/release) -lib$(LIB)_standard.a lib$(LIB)_profile.a lib$(LIB)_release.a lib$(LIB)_debug.a: - @echo Making library: "$@ ( $(foreach f,$^,$(subst $(MROOT)/,,$f)) )" - @$(AR) -rcsv $@ $^ - -## Library Soft Link rule: -libs libp libd libr: - @echo "Making Soft Link: $^ -> lib$(LIB).a" - @ln -sf $^ lib$(LIB).a - -## Clean rule -clean: - @rm -f $(EXEC) $(EXEC)_profile $(EXEC)_debug $(EXEC)_release $(EXEC)_static \ - $(COBJS) $(PCOBJS) $(DCOBJS) $(RCOBJS) *.core depend.mk - -## Make dependencies -depend.mk: $(CSRCS) $(CHDRS) - @echo Making dependencies - @$(CXX) $(CFLAGS) -I$(MROOT) \ - $(CSRCS) -MM | sed 's|\(.*\):|$(PWD)/\1 $(PWD)/\1r $(PWD)/\1d $(PWD)/\1p:|' > depend.mk - @for dir in $(DEPDIR); do \ - if [ -r $(MROOT)/$${dir}/depend.mk ]; then \ - echo Depends on: $${dir}; \ - cat $(MROOT)/$${dir}/depend.mk >> depend.mk; \ - fi; \ - done - --include $(MROOT)/mtl/config.mk --include depend.mk diff --git a/src/sat/minisat/simp/Main.cc b/src/sat/minisat/simp/Main.cc deleted file mode 100644 index e59d73be..00000000 --- a/src/sat/minisat/simp/Main.cc +++ /dev/null @@ -1,211 +0,0 @@ -/*****************************************************************************************[Main.cc] -Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#include - -#include -#include -#include - -#include "utils/System.h" -#include "utils/ParseUtils.h" -#include "utils/Options.h" -#include "core/Dimacs.h" -#include "simp/SimpSolver.h" - -using namespace Minisat; - -//================================================================================================= - - -void printStats(Solver& solver) -{ - double cpu_time = cpuTime(); - double mem_used = memUsedPeak(); - printf("restarts : %"PRIu64"\n", solver.starts); - printf("conflicts : %-12"PRIu64" (%.0f /sec)\n", solver.conflicts , solver.conflicts /cpu_time); - printf("decisions : %-12"PRIu64" (%4.2f %% random) (%.0f /sec)\n", solver.decisions, (float)solver.rnd_decisions*100 / (float)solver.decisions, solver.decisions /cpu_time); - printf("propagations : %-12"PRIu64" (%.0f /sec)\n", solver.propagations, solver.propagations/cpu_time); - printf("conflict literals : %-12"PRIu64" (%4.2f %% deleted)\n", solver.tot_literals, (solver.max_literals - solver.tot_literals)*100 / (double)solver.max_literals); - if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used); - printf("CPU time : %g s\n", cpu_time); -} - - -static Solver* solver; -// Terminate by notifying the solver and back out gracefully. This is mainly to have a test-case -// for this feature of the Solver as it may take longer than an immediate call to '_exit()'. -static void SIGINT_interrupt(int signum) { solver->interrupt(); } - -// Note that '_exit()' rather than 'exit()' has to be used. The reason is that 'exit()' calls -// destructors and may cause deadlocks if a malloc/free function happens to be running (these -// functions are guarded by locks for multithreaded use). -static void SIGINT_exit(int signum) { - printf("\n"); printf("*** INTERRUPTED ***\n"); - if (solver->verbosity > 0){ - printStats(*solver); - printf("\n"); printf("*** INTERRUPTED ***\n"); } - _exit(1); } - - -//================================================================================================= -// Main: - -int main(int argc, char** argv) -{ - try { - setUsageHelp("USAGE: %s [options] \n\n where input may be either in plain or gzipped DIMACS.\n"); - // printf("This is MiniSat 2.0 beta\n"); - -#if defined(__linux__) - fpu_control_t oldcw, newcw; - _FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(newcw); - printf("WARNING: for repeatability, setting FPU to use double precision\n"); -#endif - // Extra options: - // - IntOption verb ("MAIN", "verb", "Verbosity level (0=silent, 1=some, 2=more).", 1, IntRange(0, 2)); - BoolOption pre ("MAIN", "pre", "Completely turn on/off any preprocessing.", true); - StringOption dimacs ("MAIN", "dimacs", "If given, stop after preprocessing and write the result to this file."); - IntOption cpu_lim("MAIN", "cpu-lim","Limit on CPU time allowed in seconds.\n", INT32_MAX, IntRange(0, INT32_MAX)); - IntOption mem_lim("MAIN", "mem-lim","Limit on memory usage in megabytes.\n", INT32_MAX, IntRange(0, INT32_MAX)); - - parseOptions(argc, argv, true); - - SimpSolver S; - double initial_time = cpuTime(); - - if (!pre) S.eliminate(true); - - S.verbosity = verb; - - solver = &S; - // Use signal handlers that forcibly quit until the solver will be able to respond to - // interrupts: - signal(SIGINT, SIGINT_exit); - signal(SIGXCPU,SIGINT_exit); - - // Set limit on CPU-time: - if (cpu_lim != INT32_MAX){ - rlimit rl; - getrlimit(RLIMIT_CPU, &rl); - if (rl.rlim_max == RLIM_INFINITY || (rlim_t)cpu_lim < rl.rlim_max){ - rl.rlim_cur = cpu_lim; - if (setrlimit(RLIMIT_CPU, &rl) == -1) - printf("WARNING! Could not set resource limit: CPU-time.\n"); - } } - - // Set limit on virtual memory: - if (mem_lim != INT32_MAX){ - rlim_t new_mem_lim = (rlim_t)mem_lim * 1024*1024; - rlimit rl; - getrlimit(RLIMIT_AS, &rl); - if (rl.rlim_max == RLIM_INFINITY || new_mem_lim < rl.rlim_max){ - rl.rlim_cur = new_mem_lim; - if (setrlimit(RLIMIT_AS, &rl) == -1) - printf("WARNING! Could not set resource limit: Virtual memory.\n"); - } } - - if (argc == 1) - printf("Reading from standard input... Use '--help' for help.\n"); - - gzFile in = (argc == 1) ? gzdopen(0, "rb") : gzopen(argv[1], "rb"); - if (in == NULL) - printf("ERROR! Could not open file: %s\n", argc == 1 ? "" : argv[1]), exit(1); - - if (S.verbosity > 0){ - printf("============================[ Problem Statistics ]=============================\n"); - printf("| |\n"); } - - parse_DIMACS(in, S); - gzclose(in); - FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL; - - if (S.verbosity > 0){ - printf("| Number of variables: %12d |\n", S.nVars()); - printf("| Number of clauses: %12d |\n", S.nClauses()); } - - double parsed_time = cpuTime(); - if (S.verbosity > 0) - printf("| Parse time: %12.2f s |\n", parsed_time - initial_time); - - // Change to signal-handlers that will only notify the solver and allow it to terminate - // voluntarily: - signal(SIGINT, SIGINT_interrupt); - signal(SIGXCPU,SIGINT_interrupt); - - S.eliminate(true); - double simplified_time = cpuTime(); - if (S.verbosity > 0){ - printf("| Simplification time: %12.2f s |\n", simplified_time - parsed_time); - printf("| |\n"); } - - if (!S.okay()){ - if (res != NULL) fprintf(res, "UNSAT\n"), fclose(res); - if (S.verbosity > 0){ - printf("===============================================================================\n"); - printf("Solved by simplification\n"); - printStats(S); - printf("\n"); } - printf("UNSATISFIABLE\n"); - exit(20); - } - - if (dimacs){ - if (S.verbosity > 0) - printf("==============================[ Writing DIMACS ]===============================\n"); - S.toDimacs((const char*)dimacs); - if (S.verbosity > 0) - printStats(S); - exit(0); - } - - vec dummy; - lbool ret = S.solveLimited(dummy); - - if (S.verbosity > 0){ - printStats(S); - printf("\n"); } - printf(ret == l_True ? "SATISFIABLE\n" : ret == l_False ? "UNSATISFIABLE\n" : "INDETERMINATE\n"); - if (res != NULL){ - if (ret == l_True){ - fprintf(res, "SAT\n"); - for (int i = 0; i < S.nVars(); i++) - if (S.model[i] != l_Undef) - fprintf(res, "%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1); - fprintf(res, " 0\n"); - }else if (ret == l_False) - fprintf(res, "UNSAT\n"); - else - fprintf(res, "INDET\n"); - fclose(res); - } - -#ifdef NDEBUG - exit(ret == l_True ? 10 : ret == l_False ? 20 : 0); // (faster than "return", which will invoke the destructor for 'Solver') -#else - return (ret == l_True ? 10 : ret == l_False ? 20 : 0); -#endif - } catch (OutOfMemoryException&){ - printf("===============================================================================\n"); - printf("INDETERMINATE\n"); - exit(0); - } -} diff --git a/src/sat/minisat/simp/Makefile b/src/sat/minisat/simp/Makefile deleted file mode 100644 index 27b45f49..00000000 --- a/src/sat/minisat/simp/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -EXEC = minisat -DEPDIR = mtl utils core - -include $(MROOT)/mtl/template.mk diff --git a/src/sat/minisat/simp/SimpSolver.cc b/src/sat/minisat/simp/SimpSolver.cc deleted file mode 100644 index a1dc16d3..00000000 --- a/src/sat/minisat/simp/SimpSolver.cc +++ /dev/null @@ -1,717 +0,0 @@ -/***********************************************************************************[SimpSolver.cc] -Copyright (c) 2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#include "mtl/Sort.h" -#include "simp/SimpSolver.h" -#include "utils/System.h" - -using namespace Minisat; - -//================================================================================================= -// Options: - - -static const char* _cat = "SIMP"; - -static BoolOption opt_use_asymm (_cat, "asymm", "Shrink clauses by asymmetric branching.", false); -static BoolOption opt_use_rcheck (_cat, "rcheck", "Check if a clause is already implied. (costly)", false); -static BoolOption opt_use_elim (_cat, "elim", "Perform variable elimination.", true); -static IntOption opt_grow (_cat, "grow", "Allow a variable elimination step to grow by a number of clauses.", 0); -static IntOption opt_clause_lim (_cat, "cl-lim", "Variables are not eliminated if it produces a resolvent with a length above this limit. -1 means no limit", 20, IntRange(-1, INT32_MAX)); -static IntOption opt_subsumption_lim (_cat, "sub-lim", "Do not check if subsumption against a clause larger than this. -1 means no limit.", 1000, IntRange(-1, INT32_MAX)); -static DoubleOption opt_simp_garbage_frac(_cat, "simp-gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered during simplification.", 0.5, DoubleRange(0, false, HUGE_VAL, false)); - - -//================================================================================================= -// Constructor/Destructor: - - -SimpSolver::SimpSolver() : - grow (opt_grow) - , clause_lim (opt_clause_lim) - , subsumption_lim (opt_subsumption_lim) - , simp_garbage_frac (opt_simp_garbage_frac) - , use_asymm (opt_use_asymm) - , use_rcheck (opt_use_rcheck) - , use_elim (opt_use_elim) - , merges (0) - , asymm_lits (0) - , eliminated_vars (0) - , elimorder (1) - , use_simplification (true) - , occurs (ClauseDeleted(ca)) - , elim_heap (ElimLt(n_occ)) - , bwdsub_assigns (0) - , n_touched (0) -{ - vec dummy(1,lit_Undef); - ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below. - bwdsub_tmpunit = ca.alloc(dummy); - remove_satisfied = false; -} - - -SimpSolver::~SimpSolver() -{ -} - - -Var SimpSolver::newVar(bool sign, bool dvar) { - Var v = Solver::newVar(sign, dvar); - - frozen .push((char)false); - eliminated.push((char)false); - - if (use_simplification){ - n_occ .push(0); - n_occ .push(0); - occurs .init(v); - touched .push(0); - elim_heap .insert(v); - } - return v; } - - - -lbool SimpSolver::solve_(bool do_simp, bool turn_off_simp) -{ - vec extra_frozen; - lbool result = l_True; - - do_simp &= use_simplification; - - if (do_simp){ - // Assumptions must be temporarily frozen to run variable elimination: - for (int i = 0; i < assumptions.size(); i++){ - Var v = var(assumptions[i]); - - // If an assumption has been eliminated, remember it. - assert(!isEliminated(v)); - - if (!frozen[v]){ - // Freeze and store. - setFrozen(v, true); - extra_frozen.push(v); - } } - - result = lbool(eliminate(turn_off_simp)); - } - - if (result == l_True) - result = Solver::solve_(); - else if (verbosity >= 1) - printf("===============================================================================\n"); - - if (result == l_True) - extendModel(); - - if (do_simp) - // Unfreeze the assumptions that were frozen: - for (int i = 0; i < extra_frozen.size(); i++) - setFrozen(extra_frozen[i], false); - - return result; -} - - - -bool SimpSolver::addClause_(vec& ps) -{ -#ifndef NDEBUG - for (int i = 0; i < ps.size(); i++) - assert(!isEliminated(var(ps[i]))); -#endif - - int nclauses = clauses.size(); - - if (use_rcheck && implied(ps)) - return true; - - if (!Solver::addClause_(ps)) - return false; - - if (use_simplification && clauses.size() == nclauses + 1){ - CRef cr = clauses.last(); - const Clause& c = ca[cr]; - - // NOTE: the clause is added to the queue immediately and then - // again during 'gatherTouchedClauses()'. If nothing happens - // in between, it will only be checked once. Otherwise, it may - // be checked twice unnecessarily. This is an unfortunate - // consequence of how backward subsumption is used to mimic - // forward subsumption. - subsumption_queue.insert(cr); - for (int i = 0; i < c.size(); i++){ - occurs[var(c[i])].push(cr); - n_occ[toInt(c[i])]++; - touched[var(c[i])] = 1; - n_touched++; - if (elim_heap.inHeap(var(c[i]))) - elim_heap.increase(var(c[i])); - } - } - - return true; -} - - -void SimpSolver::removeClause(CRef cr) -{ - const Clause& c = ca[cr]; - - if (use_simplification) - for (int i = 0; i < c.size(); i++){ - n_occ[toInt(c[i])]--; - updateElimHeap(var(c[i])); - occurs.smudge(var(c[i])); - } - - Solver::removeClause(cr); -} - - -bool SimpSolver::strengthenClause(CRef cr, Lit l) -{ - Clause& c = ca[cr]; - assert(decisionLevel() == 0); - assert(use_simplification); - - // FIX: this is too inefficient but would be nice to have (properly implemented) - // if (!find(subsumption_queue, &c)) - subsumption_queue.insert(cr); - - if (c.size() == 2){ - removeClause(cr); - c.strengthen(l); - }else{ - detachClause(cr, true); - c.strengthen(l); - attachClause(cr); - remove(occurs[var(l)], cr); - n_occ[toInt(l)]--; - updateElimHeap(var(l)); - } - - return c.size() == 1 ? enqueue(c[0]) && propagate() == CRef_Undef : true; -} - - -// Returns FALSE if clause is always satisfied ('out_clause' should not be used). -bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, vec& out_clause) -{ - merges++; - out_clause.clear(); - - bool ps_smallest = _ps.size() < _qs.size(); - const Clause& ps = ps_smallest ? _qs : _ps; - const Clause& qs = ps_smallest ? _ps : _qs; - - for (int i = 0; i < qs.size(); i++){ - if (var(qs[i]) != v){ - for (int j = 0; j < ps.size(); j++) - if (var(ps[j]) == var(qs[i])) - if (ps[j] == ~qs[i]) - return false; - else - goto next; - out_clause.push(qs[i]); - } - next:; - } - - for (int i = 0; i < ps.size(); i++) - if (var(ps[i]) != v) - out_clause.push(ps[i]); - - return true; -} - - -// Returns FALSE if clause is always satisfied. -bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, int& size) -{ - merges++; - - bool ps_smallest = _ps.size() < _qs.size(); - const Clause& ps = ps_smallest ? _qs : _ps; - const Clause& qs = ps_smallest ? _ps : _qs; - const Lit* __ps = (const Lit*)ps; - const Lit* __qs = (const Lit*)qs; - - size = ps.size()-1; - - for (int i = 0; i < qs.size(); i++){ - if (var(__qs[i]) != v){ - for (int j = 0; j < ps.size(); j++) - if (var(__ps[j]) == var(__qs[i])) - if (__ps[j] == ~__qs[i]) - return false; - else - goto next; - size++; - } - next:; - } - - return true; -} - - -void SimpSolver::gatherTouchedClauses() -{ - if (n_touched == 0) return; - - int i,j; - for (i = j = 0; i < subsumption_queue.size(); i++) - if (ca[subsumption_queue[i]].mark() == 0) - ca[subsumption_queue[i]].mark(2); - - for (i = 0; i < touched.size(); i++) - if (touched[i]){ - const vec& cs = occurs.lookup(i); - for (j = 0; j < cs.size(); j++) - if (ca[cs[j]].mark() == 0){ - subsumption_queue.insert(cs[j]); - ca[cs[j]].mark(2); - } - touched[i] = 0; - } - - for (i = 0; i < subsumption_queue.size(); i++) - if (ca[subsumption_queue[i]].mark() == 2) - ca[subsumption_queue[i]].mark(0); - - n_touched = 0; -} - - -bool SimpSolver::implied(const vec& c) -{ - assert(decisionLevel() == 0); - - trail_lim.push(trail.size()); - for (int i = 0; i < c.size(); i++) - if (value(c[i]) == l_True){ - cancelUntil(0); - return false; - }else if (value(c[i]) != l_False){ - assert(value(c[i]) == l_Undef); - uncheckedEnqueue(~c[i]); - } - - bool result = propagate() != CRef_Undef; - cancelUntil(0); - return result; -} - - -// Backward subsumption + backward subsumption resolution -bool SimpSolver::backwardSubsumptionCheck(bool verbose) -{ - int cnt = 0; - int subsumed = 0; - int deleted_literals = 0; - assert(decisionLevel() == 0); - - while (subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()){ - - // Empty subsumption queue and return immediately on user-interrupt: - if (asynch_interrupt){ - subsumption_queue.clear(); - bwdsub_assigns = trail.size(); - break; } - - // Check top-level assignments by creating a dummy clause and placing it in the queue: - if (subsumption_queue.size() == 0 && bwdsub_assigns < trail.size()){ - Lit l = trail[bwdsub_assigns++]; - ca[bwdsub_tmpunit][0] = l; - ca[bwdsub_tmpunit].calcAbstraction(); - subsumption_queue.insert(bwdsub_tmpunit); } - - CRef cr = subsumption_queue.peek(); subsumption_queue.pop(); - Clause& c = ca[cr]; - - if (c.mark()) continue; - - if (verbose && verbosity >= 2 && cnt++ % 1000 == 0) - printf("subsumption left: %10d (%10d subsumed, %10d deleted literals)\r", subsumption_queue.size(), subsumed, deleted_literals); - - assert(c.size() > 1 || value(c[0]) == l_True); // Unit-clauses should have been propagated before this point. - - // Find best variable to scan: - Var best = var(c[0]); - for (int i = 1; i < c.size(); i++) - if (occurs[var(c[i])].size() < occurs[best].size()) - best = var(c[i]); - - // Search all candidates: - vec& _cs = occurs.lookup(best); - CRef* cs = (CRef*)_cs; - - for (int j = 0; j < _cs.size(); j++) - if (c.mark()) - break; - else if (!ca[cs[j]].mark() && cs[j] != cr && (subsumption_lim == -1 || ca[cs[j]].size() < subsumption_lim)){ - Lit l = c.subsumes(ca[cs[j]]); - - if (l == lit_Undef) - subsumed++, removeClause(cs[j]); - else if (l != lit_Error){ - deleted_literals++; - - if (!strengthenClause(cs[j], ~l)) - return false; - - // Did current candidate get deleted from cs? Then check candidate at index j again: - if (var(l) == best) - j--; - } - } - } - - return true; -} - - -bool SimpSolver::asymm(Var v, CRef cr) -{ - Clause& c = ca[cr]; - assert(decisionLevel() == 0); - - if (c.mark() || satisfied(c)) return true; - - trail_lim.push(trail.size()); - Lit l = lit_Undef; - for (int i = 0; i < c.size(); i++) - if (var(c[i]) != v && value(c[i]) != l_False) - uncheckedEnqueue(~c[i]); - else - l = c[i]; - - if (propagate() != CRef_Undef){ - cancelUntil(0); - asymm_lits++; - if (!strengthenClause(cr, l)) - return false; - }else - cancelUntil(0); - - return true; -} - - -bool SimpSolver::asymmVar(Var v) -{ - assert(use_simplification); - - const vec& cls = occurs.lookup(v); - - if (value(v) != l_Undef || cls.size() == 0) - return true; - - for (int i = 0; i < cls.size(); i++) - if (!asymm(v, cls[i])) - return false; - - return backwardSubsumptionCheck(); -} - - -static void mkElimClause(vec& elimclauses, Lit x) -{ - elimclauses.push(toInt(x)); - elimclauses.push(1); -} - - -static void mkElimClause(vec& elimclauses, Var v, Clause& c) -{ - int first = elimclauses.size(); - int v_pos = -1; - - // Copy clause to elimclauses-vector. Remember position where the - // variable 'v' occurs: - for (int i = 0; i < c.size(); i++){ - elimclauses.push(toInt(c[i])); - if (var(c[i]) == v) - v_pos = i + first; - } - assert(v_pos != -1); - - // Swap the first literal with the 'v' literal, so that the literal - // containing 'v' will occur first in the clause: - uint32_t tmp = elimclauses[v_pos]; - elimclauses[v_pos] = elimclauses[first]; - elimclauses[first] = tmp; - - // Store the length of the clause last: - elimclauses.push(c.size()); -} - - - -bool SimpSolver::eliminateVar(Var v) -{ - assert(!frozen[v]); - assert(!isEliminated(v)); - assert(value(v) == l_Undef); - - // Split the occurrences into positive and negative: - // - const vec& cls = occurs.lookup(v); - vec pos, neg; - for (int i = 0; i < cls.size(); i++) - (find(ca[cls[i]], mkLit(v)) ? pos : neg).push(cls[i]); - - // Check wether the increase in number of clauses stays within the allowed ('grow'). Moreover, no - // clause must exceed the limit on the maximal clause size (if it is set): - // - int cnt = 0; - int clause_size = 0; - - for (int i = 0; i < pos.size(); i++) - for (int j = 0; j < neg.size(); j++) - if (merge(ca[pos[i]], ca[neg[j]], v, clause_size) && - (++cnt > cls.size() + grow || (clause_lim != -1 && clause_size > clause_lim))) - return true; - - // Delete and store old clauses: - eliminated[v] = true; - setDecisionVar(v, false); - eliminated_vars++; - - if (pos.size() > neg.size()){ - for (int i = 0; i < neg.size(); i++) - mkElimClause(elimclauses, v, ca[neg[i]]); - mkElimClause(elimclauses, mkLit(v)); - }else{ - for (int i = 0; i < pos.size(); i++) - mkElimClause(elimclauses, v, ca[pos[i]]); - mkElimClause(elimclauses, ~mkLit(v)); - } - - for (int i = 0; i < cls.size(); i++) - removeClause(cls[i]); - - // Produce clauses in cross product: - vec& resolvent = add_tmp; - for (int i = 0; i < pos.size(); i++) - for (int j = 0; j < neg.size(); j++) - if (merge(ca[pos[i]], ca[neg[j]], v, resolvent) && !addClause_(resolvent)) - return false; - - // Free occurs list for this variable: - occurs[v].clear(true); - - // Free watchers lists for this variable, if possible: - if (watches[ mkLit(v)].size() == 0) watches[ mkLit(v)].clear(true); - if (watches[~mkLit(v)].size() == 0) watches[~mkLit(v)].clear(true); - - return backwardSubsumptionCheck(); -} - - -bool SimpSolver::substitute(Var v, Lit x) -{ - assert(!frozen[v]); - assert(!isEliminated(v)); - assert(value(v) == l_Undef); - - if (!ok) return false; - - eliminated[v] = true; - setDecisionVar(v, false); - const vec& cls = occurs.lookup(v); - - vec& subst_clause = add_tmp; - for (int i = 0; i < cls.size(); i++){ - Clause& c = ca[cls[i]]; - - subst_clause.clear(); - for (int j = 0; j < c.size(); j++){ - Lit p = c[j]; - subst_clause.push(var(p) == v ? x ^ sign(p) : p); - } - - removeClause(cls[i]); - - if (!addClause_(subst_clause)) - return ok = false; - } - - return true; -} - - -void SimpSolver::extendModel() -{ - int i, j; - Lit x; - - for (i = elimclauses.size()-1; i > 0; i -= j){ - for (j = elimclauses[i--]; j > 1; j--, i--) - if (modelValue(toLit(elimclauses[i])) != l_False) - goto next; - - x = toLit(elimclauses[i]); - model[var(x)] = lbool(!sign(x)); - next:; - } -} - - -bool SimpSolver::eliminate(bool turn_off_elim) -{ - if (!simplify()) - return false; - else if (!use_simplification) - return true; - - // Main simplification loop: - // - while (n_touched > 0 || bwdsub_assigns < trail.size() || elim_heap.size() > 0){ - - gatherTouchedClauses(); - // printf(" ## (time = %6.2f s) BWD-SUB: queue = %d, trail = %d\n", cpuTime(), subsumption_queue.size(), trail.size() - bwdsub_assigns); - if ((subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()) && - !backwardSubsumptionCheck(true)){ - ok = false; goto cleanup; } - - // Empty elim_heap and return immediately on user-interrupt: - if (asynch_interrupt){ - assert(bwdsub_assigns == trail.size()); - assert(subsumption_queue.size() == 0); - assert(n_touched == 0); - elim_heap.clear(); - goto cleanup; } - - // printf(" ## (time = %6.2f s) ELIM: vars = %d\n", cpuTime(), elim_heap.size()); - for (int cnt = 0; !elim_heap.empty(); cnt++){ - Var elim = elim_heap.removeMin(); - - if (asynch_interrupt) break; - - if (isEliminated(elim) || value(elim) != l_Undef) continue; - - if (verbosity >= 2 && cnt % 100 == 0) - printf("elimination left: %10d\r", elim_heap.size()); - - if (use_asymm){ - // Temporarily freeze variable. Otherwise, it would immediately end up on the queue again: - bool was_frozen = frozen[elim]; - frozen[elim] = true; - if (!asymmVar(elim)){ - ok = false; goto cleanup; } - frozen[elim] = was_frozen; } - - // At this point, the variable may have been set by assymetric branching, so check it - // again. Also, don't eliminate frozen variables: - if (use_elim && value(elim) == l_Undef && !frozen[elim] && !eliminateVar(elim)){ - ok = false; goto cleanup; } - - checkGarbage(simp_garbage_frac); - } - - assert(subsumption_queue.size() == 0); - } - cleanup: - - // If no more simplification is needed, free all simplification-related data structures: - if (turn_off_elim){ - touched .clear(true); - occurs .clear(true); - n_occ .clear(true); - elim_heap.clear(true); - subsumption_queue.clear(true); - - use_simplification = false; - remove_satisfied = true; - ca.extra_clause_field = false; - - // Force full cleanup (this is safe and desirable since it only happens once): - rebuildOrderHeap(); - garbageCollect(); - }else{ - // Cheaper cleanup: - cleanUpClauses(); // TODO: can we make 'cleanUpClauses()' not be linear in the problem size somehow? - checkGarbage(); - } - - if (verbosity >= 1 && elimclauses.size() > 0) - printf("| Eliminated clauses: %10.2f Mb |\n", - double(elimclauses.size() * sizeof(uint32_t)) / (1024*1024)); - - return ok; -} - - -void SimpSolver::cleanUpClauses() -{ - occurs.cleanAll(); - int i,j; - for (i = j = 0; i < clauses.size(); i++) - if (ca[clauses[i]].mark() == 0) - clauses[j++] = clauses[i]; - clauses.shrink(i - j); -} - - -//================================================================================================= -// Garbage Collection methods: - - -void SimpSolver::relocAll(ClauseAllocator& to) -{ - if (!use_simplification) return; - - // All occurs lists: - // - for (int i = 0; i < nVars(); i++){ - vec& cs = occurs[i]; - for (int j = 0; j < cs.size(); j++) - ca.reloc(cs[j], to); - } - - // Subsumption queue: - // - for (int i = 0; i < subsumption_queue.size(); i++) - ca.reloc(subsumption_queue[i], to); - - // Temporary clause: - // - ca.reloc(bwdsub_tmpunit, to); -} - - -void SimpSolver::garbageCollect() -{ - // Initialize the next region to a size corresponding to the estimated utilization degree. This - // is not precise but should avoid some unnecessary reallocations for the new region: - ClauseAllocator to(ca.size() - ca.wasted()); - - cleanUpClauses(); - to.extra_clause_field = ca.extra_clause_field; // NOTE: this is important to keep (or lose) the extra fields. - relocAll(to); - Solver::relocAll(to); - if (verbosity >= 2) - printf("| Garbage collection: %12d bytes => %12d bytes |\n", - ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size); - to.moveTo(ca); -} diff --git a/src/sat/minisat/simp/SimpSolver.h b/src/sat/minisat/simp/SimpSolver.h deleted file mode 100644 index 49090181..00000000 --- a/src/sat/minisat/simp/SimpSolver.h +++ /dev/null @@ -1,197 +0,0 @@ -/************************************************************************************[SimpSolver.h] -Copyright (c) 2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_SimpSolver_h -#define Minisat_SimpSolver_h - -#include "mtl/Queue.h" -#include "core/Solver.h" - - -namespace Minisat { - -//================================================================================================= - - -class SimpSolver : public Solver { - public: - // Constructor/Destructor: - // - SimpSolver(); - ~SimpSolver(); - - // Problem specification: - // - Var newVar (bool polarity = true, bool dvar = true); - bool addClause (const vec& ps); - bool addEmptyClause(); // Add the empty clause to the solver. - bool addClause (Lit p); // Add a unit clause to the solver. - bool addClause (Lit p, Lit q); // Add a binary clause to the solver. - bool addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver. - bool addClause_( vec& ps); - bool substitute(Var v, Lit x); // Replace all occurences of v with x (may cause a contradiction). - - // Variable mode: - // - void setFrozen (Var v, bool b); // If a variable is frozen it will not be eliminated. - bool isEliminated(Var v) const; - - // Solving: - // - bool solve (const vec& assumps, bool do_simp = true, bool turn_off_simp = false); - lbool solveLimited(const vec& assumps, bool do_simp = true, bool turn_off_simp = false); - bool solve ( bool do_simp = true, bool turn_off_simp = false); - bool solve (Lit p , bool do_simp = true, bool turn_off_simp = false); - bool solve (Lit p, Lit q, bool do_simp = true, bool turn_off_simp = false); - bool solve (Lit p, Lit q, Lit r, bool do_simp = true, bool turn_off_simp = false); - bool eliminate (bool turn_off_elim = false); // Perform variable elimination based simplification. - - // Memory managment: - // - virtual void garbageCollect(); - - - // Generate a (possibly simplified) DIMACS file: - // -#if 0 - void toDimacs (const char* file, const vec& assumps); - void toDimacs (const char* file); - void toDimacs (const char* file, Lit p); - void toDimacs (const char* file, Lit p, Lit q); - void toDimacs (const char* file, Lit p, Lit q, Lit r); -#endif - - // Mode of operation: - // - int grow; // Allow a variable elimination step to grow by a number of clauses (default to zero). - int clause_lim; // Variables are not eliminated if it produces a resolvent with a length above this limit. - // -1 means no limit. - int subsumption_lim; // Do not check if subsumption against a clause larger than this. -1 means no limit. - double simp_garbage_frac; // A different limit for when to issue a GC during simplification (Also see 'garbage_frac'). - - bool use_asymm; // Shrink clauses by asymmetric branching. - bool use_rcheck; // Check if a clause is already implied. Prett costly, and subsumes subsumptions :) - bool use_elim; // Perform variable elimination. - - // Statistics: - // - int merges; - int asymm_lits; - int eliminated_vars; - - protected: - - // Helper structures: - // - struct ElimLt { - const vec& n_occ; - explicit ElimLt(const vec& no) : n_occ(no) {} - - // TODO: are 64-bit operations here noticably bad on 32-bit platforms? Could use a saturating - // 32-bit implementation instead then, but this will have to do for now. - uint64_t cost (Var x) const { return (uint64_t)n_occ[toInt(mkLit(x))] * (uint64_t)n_occ[toInt(~mkLit(x))]; } - bool operator()(Var x, Var y) const { return cost(x) < cost(y); } - - // TODO: investigate this order alternative more. - // bool operator()(Var x, Var y) const { - // int c_x = cost(x); - // int c_y = cost(y); - // return c_x < c_y || c_x == c_y && x < y; } - }; - - struct ClauseDeleted { - const ClauseAllocator& ca; - explicit ClauseDeleted(const ClauseAllocator& _ca) : ca(_ca) {} - bool operator()(const CRef& cr) const { return ca[cr].mark() == 1; } }; - - // Solver state: - // - int elimorder; - bool use_simplification; - vec elimclauses; - vec touched; - OccLists, ClauseDeleted> - occurs; - vec n_occ; - Heap elim_heap; - Queue subsumption_queue; - vec frozen; - vec eliminated; - int bwdsub_assigns; - int n_touched; - - // Temporaries: - // - CRef bwdsub_tmpunit; - - // Main internal methods: - // - lbool solve_ (bool do_simp = true, bool turn_off_simp = false); - bool asymm (Var v, CRef cr); - bool asymmVar (Var v); - void updateElimHeap (Var v); - void gatherTouchedClauses (); - bool merge (const Clause& _ps, const Clause& _qs, Var v, vec& out_clause); - bool merge (const Clause& _ps, const Clause& _qs, Var v, int& size); - bool backwardSubsumptionCheck (bool verbose = false); - bool eliminateVar (Var v); - void extendModel (); - - void removeClause (CRef cr); - bool strengthenClause (CRef cr, Lit l); - void cleanUpClauses (); - bool implied (const vec& c); - void relocAll (ClauseAllocator& to); -}; - - -//================================================================================================= -// Implementation of inline methods: - - -inline bool SimpSolver::isEliminated (Var v) const { return eliminated[v]; } -inline void SimpSolver::updateElimHeap(Var v) { - assert(use_simplification); - // if (!frozen[v] && !isEliminated(v) && value(v) == l_Undef) - if (elim_heap.inHeap(v) || (!frozen[v] && !isEliminated(v) && value(v) == l_Undef)) - elim_heap.update(v); } - - -inline bool SimpSolver::addClause (const vec& ps) { ps.copyTo(add_tmp); return addClause_(add_tmp); } -inline bool SimpSolver::addEmptyClause() { add_tmp.clear(); return addClause_(add_tmp); } -inline bool SimpSolver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); } -inline bool SimpSolver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); } -inline bool SimpSolver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); } -inline void SimpSolver::setFrozen (Var v, bool b) { frozen[v] = (char)b; if (use_simplification && !b) { updateElimHeap(v); } } - -inline bool SimpSolver::solve ( bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); return solve_(do_simp, turn_off_simp) == l_True; } -inline bool SimpSolver::solve (Lit p , bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_(do_simp, turn_off_simp) == l_True; } -inline bool SimpSolver::solve (Lit p, Lit q, bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_(do_simp, turn_off_simp) == l_True; } -inline bool SimpSolver::solve (Lit p, Lit q, Lit r, bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_(do_simp, turn_off_simp) == l_True; } -inline bool SimpSolver::solve (const vec& assumps, bool do_simp, bool turn_off_simp){ - budgetOff(); assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp) == l_True; } - -inline lbool SimpSolver::solveLimited (const vec& assumps, bool do_simp, bool turn_off_simp){ - assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp); } - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/utils/Makefile b/src/sat/minisat/utils/Makefile deleted file mode 100644 index 204cea54..00000000 --- a/src/sat/minisat/utils/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -EXEC = system_test -DEPDIR = mtl - -include $(MROOT)/mtl/template.mk diff --git a/src/sat/minisat/utils/Options.cc b/src/sat/minisat/utils/Options.cc deleted file mode 100644 index ec5a6e93..00000000 --- a/src/sat/minisat/utils/Options.cc +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************************[Options.cc] -Copyright (c) 2008-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#include "mtl/Sort.h" -#include "utils/Options.h" -#include "utils/ParseUtils.h" - -using namespace Minisat; - -void Minisat::parseOptions(int& argc, char** argv, bool strict) -{ - int i, j; - for (i = j = 1; i < argc; i++){ - const char* str = argv[i]; - if (match(str, "--") && match(str, Option::getHelpPrefixString()) && match(str, "help")){ - if (*str == '\0') - printUsageAndExit(argc, argv); - else if (match(str, "-verb")) - printUsageAndExit(argc, argv, true); - } else { - bool parsed_ok = false; - - for (int k = 0; !parsed_ok && k < Option::getOptionList().size(); k++){ - parsed_ok = Option::getOptionList()[k]->parse(argv[i]); - - // fprintf(stderr, "checking %d: %s against flag <%s> (%s)\n", i, argv[i], Option::getOptionList()[k]->name, parsed_ok ? "ok" : "skip"); - } - - if (!parsed_ok) - if (strict && match(argv[i], "-")) - fprintf(stderr, "ERROR! Unknown flag \"%s\". Use '--%shelp' for help.\n", argv[i], Option::getHelpPrefixString()), exit(1); - else - argv[j++] = argv[i]; - } - } - - argc -= (i - j); -} - - -void Minisat::setUsageHelp (const char* str){ Option::getUsageString() = str; } -void Minisat::setHelpPrefixStr (const char* str){ Option::getHelpPrefixString() = str; } -void Minisat::printUsageAndExit (int argc, char** argv, bool verbose) -{ - const char* usage = Option::getUsageString(); - if (usage != NULL) - fprintf(stderr, usage, argv[0]); - - sort(Option::getOptionList(), Option::OptionLt()); - - const char* prev_cat = NULL; - const char* prev_type = NULL; - - for (int i = 0; i < Option::getOptionList().size(); i++){ - const char* cat = Option::getOptionList()[i]->category; - const char* type = Option::getOptionList()[i]->type_name; - - if (cat != prev_cat) - fprintf(stderr, "\n%s OPTIONS:\n\n", cat); - else if (type != prev_type) - fprintf(stderr, "\n"); - - Option::getOptionList()[i]->help(verbose); - - prev_cat = Option::getOptionList()[i]->category; - prev_type = Option::getOptionList()[i]->type_name; - } - - fprintf(stderr, "\nHELP OPTIONS:\n\n"); - fprintf(stderr, " --%shelp Print help message.\n", Option::getHelpPrefixString()); - fprintf(stderr, " --%shelp-verb Print verbose help message.\n", Option::getHelpPrefixString()); - fprintf(stderr, "\n"); - exit(0); -} - diff --git a/src/sat/minisat/utils/Options.h b/src/sat/minisat/utils/Options.h deleted file mode 100644 index 9c1f4069..00000000 --- a/src/sat/minisat/utils/Options.h +++ /dev/null @@ -1,386 +0,0 @@ -/***************************************************************************************[Options.h] -Copyright (c) 2008-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_Options_h -#define Minisat_Options_h - -#include -#include -#include -#include - -#include "mtl/IntTypes.h" -#include "mtl/Vec.h" -#include "utils/ParseUtils.h" - -namespace Minisat { - -//================================================================================================== -// Top-level option parse/help functions: - - -extern void parseOptions (int& argc, char** argv, bool strict = false); -extern void printUsageAndExit(int argc, char** argv, bool verbose = false); -extern void setUsageHelp (const char* str); -extern void setHelpPrefixStr (const char* str); - - -//================================================================================================== -// Options is an abstract class that gives the interface for all types options: - - -class Option -{ - protected: - const char* name; - const char* description; - const char* category; - const char* type_name; - - static vec& getOptionList () { static vec options; return options; } - static const char*& getUsageString() { static const char* usage_str; return usage_str; } - static const char*& getHelpPrefixString() { static const char* help_prefix_str = ""; return help_prefix_str; } - - struct OptionLt { - bool operator()(const Option* x, const Option* y) { - int test1 = strcmp(x->category, y->category); - return test1 < 0 || test1 == 0 && strcmp(x->type_name, y->type_name) < 0; - } - }; - - Option(const char* name_, - const char* desc_, - const char* cate_, - const char* type_) : - name (name_) - , description(desc_) - , category (cate_) - , type_name (type_) - { - getOptionList().push(this); - } - - public: - virtual ~Option() {} - - virtual bool parse (const char* str) = 0; - virtual void help (bool verbose = false) = 0; - - friend void parseOptions (int& argc, char** argv, bool strict); - friend void printUsageAndExit (int argc, char** argv, bool verbose); - friend void setUsageHelp (const char* str); - friend void setHelpPrefixStr (const char* str); -}; - - -//================================================================================================== -// Range classes with specialization for floating types: - - -struct IntRange { - int begin; - int end; - IntRange(int b, int e) : begin(b), end(e) {} -}; - -struct Int64Range { - int64_t begin; - int64_t end; - Int64Range(int64_t b, int64_t e) : begin(b), end(e) {} -}; - -struct DoubleRange { - double begin; - double end; - bool begin_inclusive; - bool end_inclusive; - DoubleRange(double b, bool binc, double e, bool einc) : begin(b), end(e), begin_inclusive(binc), end_inclusive(einc) {} -}; - - -//================================================================================================== -// Double options: - - -class DoubleOption : public Option -{ - protected: - DoubleRange range; - double value; - - public: - DoubleOption(const char* c, const char* n, const char* d, double def = double(), DoubleRange r = DoubleRange(-HUGE_VAL, false, HUGE_VAL, false)) - : Option(n, d, c, ""), range(r), value(def) { - // FIXME: set LC_NUMERIC to "C" to make sure that strtof/strtod parses decimal point correctly. - } - - operator double (void) const { return value; } - operator double& (void) { return value; } - DoubleOption& operator=(double x) { value = x; return *this; } - - virtual bool parse(const char* str){ - const char* span = str; - - if (!match(span, "-") || !match(span, name) || !match(span, "=")) - return false; - - char* end; - double tmp = strtod(span, &end); - - if (end == NULL) - return false; - else if (tmp >= range.end && (!range.end_inclusive || tmp != range.end)){ - fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name); - exit(1); - }else if (tmp <= range.begin && (!range.begin_inclusive || tmp != range.begin)){ - fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name); - exit(1); } - - value = tmp; - // fprintf(stderr, "READ VALUE: %g\n", value); - - return true; - } - - virtual void help (bool verbose = false){ - fprintf(stderr, " -%-12s = %-8s %c%4.2g .. %4.2g%c (default: %g)\n", - name, type_name, - range.begin_inclusive ? '[' : '(', - range.begin, - range.end, - range.end_inclusive ? ']' : ')', - value); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } - } -}; - - -//================================================================================================== -// Int options: - - -class IntOption : public Option -{ - protected: - IntRange range; - int32_t value; - - public: - IntOption(const char* c, const char* n, const char* d, int32_t def = int32_t(), IntRange r = IntRange(INT32_MIN, INT32_MAX)) - : Option(n, d, c, ""), range(r), value(def) {} - - operator int32_t (void) const { return value; } - operator int32_t& (void) { return value; } - IntOption& operator= (int32_t x) { value = x; return *this; } - - virtual bool parse(const char* str){ - const char* span = str; - - if (!match(span, "-") || !match(span, name) || !match(span, "=")) - return false; - - char* end; - int32_t tmp = strtol(span, &end, 10); - - if (end == NULL) - return false; - else if (tmp > range.end){ - fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name); - exit(1); - }else if (tmp < range.begin){ - fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name); - exit(1); } - - value = tmp; - - return true; - } - - virtual void help (bool verbose = false){ - fprintf(stderr, " -%-12s = %-8s [", name, type_name); - if (range.begin == INT32_MIN) - fprintf(stderr, "imin"); - else - fprintf(stderr, "%4d", range.begin); - - fprintf(stderr, " .. "); - if (range.end == INT32_MAX) - fprintf(stderr, "imax"); - else - fprintf(stderr, "%4d", range.end); - - fprintf(stderr, "] (default: %d)\n", value); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } - } -}; - - -// Leave this out for visual C++ until Microsoft implements C99 and gets support for strtoll. -#ifndef _MSC_VER - -class Int64Option : public Option -{ - protected: - Int64Range range; - int64_t value; - - public: - Int64Option(const char* c, const char* n, const char* d, int64_t def = int64_t(), Int64Range r = Int64Range(INT64_MIN, INT64_MAX)) - : Option(n, d, c, ""), range(r), value(def) {} - - operator int64_t (void) const { return value; } - operator int64_t& (void) { return value; } - Int64Option& operator= (int64_t x) { value = x; return *this; } - - virtual bool parse(const char* str){ - const char* span = str; - - if (!match(span, "-") || !match(span, name) || !match(span, "=")) - return false; - - char* end; - int64_t tmp = strtoll(span, &end, 10); - - if (end == NULL) - return false; - else if (tmp > range.end){ - fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name); - exit(1); - }else if (tmp < range.begin){ - fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name); - exit(1); } - - value = tmp; - - return true; - } - - virtual void help (bool verbose = false){ - fprintf(stderr, " -%-12s = %-8s [", name, type_name); - if (range.begin == INT64_MIN) - fprintf(stderr, "imin"); - else - fprintf(stderr, "%4"PRIi64, range.begin); - - fprintf(stderr, " .. "); - if (range.end == INT64_MAX) - fprintf(stderr, "imax"); - else - fprintf(stderr, "%4"PRIi64, range.end); - - fprintf(stderr, "] (default: %"PRIi64")\n", value); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } - } -}; -#endif - -//================================================================================================== -// String option: - - -class StringOption : public Option -{ - const char* value; - public: - StringOption(const char* c, const char* n, const char* d, const char* def = NULL) - : Option(n, d, c, ""), value(def) {} - - operator const char* (void) const { return value; } - operator const char*& (void) { return value; } - StringOption& operator= (const char* x) { value = x; return *this; } - - virtual bool parse(const char* str){ - const char* span = str; - - if (!match(span, "-") || !match(span, name) || !match(span, "=")) - return false; - - value = span; - return true; - } - - virtual void help (bool verbose = false){ - fprintf(stderr, " -%-10s = %8s\n", name, type_name); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } - } -}; - - -//================================================================================================== -// Bool option: - - -class BoolOption : public Option -{ - bool value; - - public: - BoolOption(const char* c, const char* n, const char* d, bool v) - : Option(n, d, c, ""), value(v) {} - - operator bool (void) const { return value; } - operator bool& (void) { return value; } - BoolOption& operator=(bool b) { value = b; return *this; } - - virtual bool parse(const char* str){ - const char* span = str; - - if (match(span, "-")){ - bool b = !match(span, "no-"); - - if (strcmp(span, name) == 0){ - value = b; - return true; } - } - - return false; - } - - virtual void help (bool verbose = false){ - - fprintf(stderr, " -%s, -no-%s", name, name); - - for (uint32_t i = 0; i < 32 - strlen(name)*2; i++) - fprintf(stderr, " "); - - fprintf(stderr, " "); - fprintf(stderr, "(default: %s)\n", value ? "on" : "off"); - if (verbose){ - fprintf(stderr, "\n %s\n", description); - fprintf(stderr, "\n"); - } - } -}; - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/utils/Options.or b/src/sat/minisat/utils/Options.or deleted file mode 100644 index 7015117a..00000000 Binary files a/src/sat/minisat/utils/Options.or and /dev/null differ diff --git a/src/sat/minisat/utils/ParseUtils.h b/src/sat/minisat/utils/ParseUtils.h deleted file mode 100644 index d3071649..00000000 --- a/src/sat/minisat/utils/ParseUtils.h +++ /dev/null @@ -1,122 +0,0 @@ -/************************************************************************************[ParseUtils.h] -Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_ParseUtils_h -#define Minisat_ParseUtils_h - -#include -#include - -#include - -namespace Minisat { - -//------------------------------------------------------------------------------------------------- -// A simple buffered character stream class: - -static const int buffer_size = 1048576; - - -class StreamBuffer { - gzFile in; - unsigned char buf[buffer_size]; - int pos; - int size; - - void assureLookahead() { - if (pos >= size) { - pos = 0; - size = gzread(in, buf, sizeof(buf)); } } - -public: - explicit StreamBuffer(gzFile i) : in(i), pos(0), size(0) { assureLookahead(); } - - int operator * () const { return (pos >= size) ? EOF : buf[pos]; } - void operator ++ () { pos++; assureLookahead(); } - int position () const { return pos; } -}; - - -//------------------------------------------------------------------------------------------------- -// End-of-file detection functions for StreamBuffer and char*: - - -static inline bool isEof(StreamBuffer& in) { return *in == EOF; } -static inline bool isEof(const char* in) { return *in == '\0'; } - -//------------------------------------------------------------------------------------------------- -// Generic parse functions parametrized over the input-stream type. - - -template -static void skipWhitespace(B& in) { - while ((*in >= 9 && *in <= 13) || *in == 32) - ++in; } - - -template -static void skipLine(B& in) { - for (;;){ - if (isEof(in)) return; - if (*in == '\n') { ++in; return; } - ++in; } } - - -template -static int parseInt(B& in) { - int val = 0; - bool neg = false; - skipWhitespace(in); - if (*in == '-') neg = true, ++in; - else if (*in == '+') ++in; - if (*in < '0' || *in > '9') fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", *in), exit(3); - while (*in >= '0' && *in <= '9') - val = val*10 + (*in - '0'), - ++in; - return neg ? -val : val; } - - -// String matching: in case of a match the input iterator will be advanced the corresponding -// number of characters. -template -static bool match(B& in, const char* str) { - int i; - for (i = 0; str[i] != '\0'; i++) - if (in[i] != str[i]) - return false; - - in += i; - - return true; -} - -// String matching: consumes characters eagerly, but does not require random access iterator. -template -static bool eagerMatch(B& in, const char* str) { - for (; *str != '\0'; ++str, ++in) - if (*str != *in) - return false; - return true; } - - -//================================================================================================= -} - -#endif diff --git a/src/sat/minisat/utils/System.cc b/src/sat/minisat/utils/System.cc deleted file mode 100644 index a7cf53f5..00000000 --- a/src/sat/minisat/utils/System.cc +++ /dev/null @@ -1,95 +0,0 @@ -/***************************************************************************************[System.cc] -Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#include "utils/System.h" - -#if defined(__linux__) - -#include -#include - -using namespace Minisat; - -// TODO: split the memory reading functions into two: one for reading high-watermark of RSS, and -// one for reading the current virtual memory size. - -static inline int memReadStat(int field) -{ - char name[256]; - pid_t pid = getpid(); - int value; - - sprintf(name, "/proc/%d/statm", pid); - FILE* in = fopen(name, "rb"); - if (in == NULL) return 0; - - for (; field >= 0; field--) - if (fscanf(in, "%d", &value) != 1) - printf("ERROR! Failed to parse memory statistics from \"/proc\".\n"), exit(1); - fclose(in); - return value; -} - - -static inline int memReadPeak(void) -{ - char name[256]; - pid_t pid = getpid(); - - sprintf(name, "/proc/%d/status", pid); - FILE* in = fopen(name, "rb"); - if (in == NULL) return 0; - - // Find the correct line, beginning with "VmPeak:": - int peak_kb = 0; - while (!feof(in) && fscanf(in, "VmPeak: %d kB", &peak_kb) != 1) - while (!feof(in) && fgetc(in) != '\n') - ; - fclose(in); - - return peak_kb; -} - -double Minisat::memUsed() { return (double)memReadStat(0) * (double)getpagesize() / (1024*1024); } -double Minisat::memUsedPeak() { - double peak = memReadPeak() / 1024; - return peak == 0 ? memUsed() : peak; } - -#elif defined(__FreeBSD__) - -double Minisat::memUsed(void) { - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - return (double)ru.ru_maxrss / 1024; } -double MiniSat::memUsedPeak(void) { return memUsed(); } - - -#elif defined(__APPLE__) -#include - -double Minisat::memUsed(void) { - malloc_statistics_t t; - malloc_zone_statistics(NULL, &t); - return (double)t.max_size_in_use / (1024*1024); } - -#else -double Minisat::memUsed() { - return 0; } -#endif diff --git a/src/sat/minisat/utils/System.h b/src/sat/minisat/utils/System.h deleted file mode 100644 index 17581927..00000000 --- a/src/sat/minisat/utils/System.h +++ /dev/null @@ -1,60 +0,0 @@ -/****************************************************************************************[System.h] -Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007-2010, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Minisat_System_h -#define Minisat_System_h - -#if defined(__linux__) -#include -#endif - -#include "mtl/IntTypes.h" - -//------------------------------------------------------------------------------------------------- - -namespace Minisat { - -static inline double cpuTime(void); // CPU-time in seconds. -extern double memUsed(); // Memory in mega bytes (returns 0 for unsupported architectures). -extern double memUsedPeak(); // Peak-memory in mega bytes (returns 0 for unsupported architectures). - -} - -//------------------------------------------------------------------------------------------------- -// Implementation of inline functions: - -#if defined(_MSC_VER) || defined(__MINGW32__) -#include - -static inline double Minisat::cpuTime(void) { return (double)clock() / CLOCKS_PER_SEC; } - -#else -#include -#include -#include - -static inline double Minisat::cpuTime(void) { - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; } - -#endif - -#endif diff --git a/src/sat/minisat/utils/System.or b/src/sat/minisat/utils/System.or deleted file mode 100644 index 9e266370..00000000 Binary files a/src/sat/minisat/utils/System.or and /dev/null differ diff --git a/src/sat/minisatMgr.cpp b/src/sat/minisatMgr.cpp new file mode 100644 index 00000000..50515af2 --- /dev/null +++ b/src/sat/minisatMgr.cpp @@ -0,0 +1,261 @@ +/**************************************************************************** + FileName [ sat.cpp ] + PackageName [ sat ] + Synopsis [ Define miniSat solver interface functions ] + Author [ Chung-Yang (Ric) Huang, Cheng-Yin Wu ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] +****************************************************************************/ + +#include "minisatMgr.h" + +#include + +#include "cirGate.h" +#include "cirMgr.h" +#include "satMgr.h" + +using namespace gv::cir; +using gv::sat::MinisatMgr; + +MinisatMgr::MinisatMgr(CirMgr* cirMgr) : SatSolverMgr(cirMgr), _cirMgr(cirMgr) { + _solver = new SolverV(); + _solver->proof = new Proof(); + _assump.clear(); + _curVar = 0; + _solver->newVar(); + ++_curVar; + _ntkData = new vector[_cirMgr->getNumTots()]; + for (uint32_t i = 0; i < _cirMgr->getNumTots(); ++i) _ntkData[i].clear(); + for (uint32_t i = 0; i < _cirMgr->getNumTots(); ++i) { + if ((*_cirMgr)[i] != nullptr) + (*_cirMgr)[i]->clearSatVar(); + } +} + +MinisatMgr::~MinisatMgr() { + delete _solver; + assumeRelease(); + for (uint32_t i = 0; i < _cirMgr->getNumTots(); ++i) _ntkData[i].clear(); + delete[] _ntkData; +} + +void MinisatMgr::reset() { + delete _solver; + _solver = new SolverV(); + _solver->proof = new Proof(); + _assump.clear(); + _curVar = 0; + _solver->newVar(); + ++_curVar; + _ntkData = new vector[_cirMgr->getNumTots()]; + for (uint32_t i = 0; i < _cirMgr->getNumTots(); ++i) _ntkData[i].clear(); + for (uint32_t i = 0; i < _cirMgr->getNumTots(); ++i) _cirMgr->getGate(i)->clearSatVar(); +} + +void MinisatMgr::assumeRelease() { + _assump.clear(); +} + +void MinisatMgr::assumeProperty(const size_t& var, const bool& invert) { + _assump.push(mkLit(getOriVar(var), invert ^ isNegFormula(var))); +} + +void MinisatMgr::assertProperty(const size_t& var, const bool& invert) { + _solver->addUnit(mkLit(getOriVar(var), invert ^ isNegFormula(var))); +} + +void MinisatMgr::assumeProperty(const CirGate* gate, const bool& invert, const uint32_t& depth) { + const Var var = getVerifyData(gate, depth); + _assump.push(mkLit(var, invert)); +} + +void MinisatMgr::assertProperty(const CirGate* gate, const bool& invert, const uint32_t& depth) { + const Var var = getVerifyData(gate, depth); + _solver->addUnit(mkLit(var, invert)); +} + +const bool MinisatMgr::simplify() { + return _solver->simplifyDB(); +} + +const bool MinisatMgr::solve() { + _solver->solve(); + return _solver->okay(); +} + +const bool MinisatMgr::assump_solve() { + bool result = _solver->solve(_assump); + return result; +} + +const GVBitVecX MinisatMgr::getDataValue(const CirGate* gate, const uint32_t& depth) const { + Var var = getVerifyData(gate, depth); + uint32_t i, width = 1; + GVBitVecX value(width); + // Modification for cir structure + if (false) { + for (i = 0; i < width; ++i) + if (gv_l_True == _solver->model[var + i]) + value.set0(i); + else + value.set1(i); + } else { + for (i = 0; i < width; ++i) + if (gv_l_True == _solver->model[var + i]) + value.set1(i); + else + value.set0(i); + } + return value; +} + +const bool MinisatMgr::getDataValue(const size_t& var) const { + return (isNegFormula(var)) ^ (gv_l_True == _solver->model[getOriVar(var)]); +} + +// const size_t +// MinisatMgr::getFormula(const GVNetId& id, const uint32_t& depth) { +// Var var = getVerifyData(id, depth); +// return (id.fanin0Cp ? getNegVar(var) : getPosVar(var)); +// } + +void MinisatMgr::resizeNtkData(const uint32_t& num) { + vector* tmp = new vector[_cirMgr->getNumTots()]; + for (uint32_t i = 0, j = _cirMgr->getNumTots() - num; i < j; ++i) tmp[i] = _ntkData[i]; + delete[] _ntkData; + _ntkData = tmp; +} + +const Var MinisatMgr::newVar() { + Var cur_var = _curVar; + _solver->newVar(); + _curVar++; + return cur_var; +} + +const Var MinisatMgr::getVerifyData(const CirGate* gate, const uint32_t& depth) const { + /*if (depth >= _ntkData[gate->getGid()].size())*/ + /* return 0;*/ + /*else*/ + /* return _ntkData[gate->getGid()][depth];*/ + return gate->getSatVar(depth); +} + +void MinisatMgr::add_FALSE_Formula(const CirGate* gate, const uint32_t& depth) { + /*const uint32_t index = gate->getGid();*/ + /*_ntkData[index].push_back(newVar());*/ + /*_solver->addUnit(mkLit(_ntkData[index].back(), true));*/ + gate->addSatVar(newVar()); + _solver->addUnit(mkLit(gate->getSatVar(depth), true)); +} + +void MinisatMgr::add_PI_Formula(const CirGate* gate, const uint32_t& depth) { + /*const uint32_t index = gate->getGid();*/ + /*_ntkData[index].push_back(newVar());*/ + gate->addSatVar(newVar()); +} + +void MinisatMgr::add_FF_Formula(const CirGate* gate, const uint32_t& depth) { + const uint32_t index = gate->getGid(); + if (depth) { + // Build FF I/O Relation + CirGateV in0 = gate->getIn0(); + const Var var1 = getVerifyData(in0.gate(), depth - 1); + + if (in0.isInv()) { + // a <-> b + /*_ntkData[index].push_back(newVar());*/ + gate->addSatVar(newVar()); + /*Lit a = mkLit(_ntkData[index].back());*/ + Lit a = mkLit(gate->getLastSatVar()); + Lit b = mkLit(var1, true); + vec lits; + lits.clear(); + lits.push(~a); + lits.push(b); + _solver->addClause(lits); + lits.clear(); + lits.push(a); + lits.push(~b); + _solver->addClause(lits); + lits.clear(); + } else { + /*_ntkData[index].push_back(var1);*/ + gate->addSatVar(var1); + } + } else { // Timeframe 0 + /*_ntkData[index].push_back(newVar());*/ + gate->addSatVar(newVar()); + } +} + +void MinisatMgr::add_AND_Formula(const CirGate* gate, const uint32_t& depth) { + // const uint32_t index = getGVNetIndex(out); + const uint32_t index = gate->getGid(); + /*_ntkData[index].push_back(newVar());*/ + gate->addSatVar(newVar()); + + /*const Var& var = _ntkData[index].back();*/ + const Var& var = gate->getLastSatVar(); + // Build AND I/O Relation + const CirGateV in0 = gate->getIn0(); + const CirGateV in1 = gate->getIn1(); + const Var var0 = getVerifyData(in0.gate(), depth); + const Var var1 = getVerifyData(in1.gate(), depth); + + Lit y = mkLit(var); + Lit a = mkLit(var0, in0.isInv()); + Lit b = mkLit(var1, in1.isInv()); + + vec lits; + lits.clear(); + lits.push(a); + lits.push(~y); + _solver->addClause(lits); + lits.clear(); + lits.push(b); + lits.push(~y); + _solver->addClause(lits); + lits.clear(); + lits.push(~a); + lits.push(~b); + lits.push(y); + _solver->addClause(lits); + lits.clear(); +} + +void MinisatMgr::addBoundedVerifyData(const CirGate* gate, const uint32_t& depth) { + if (existVerifyData(gate, depth)) return; + addBoundedVerifyDataRecursively(gate, depth); +} + +void MinisatMgr::addBoundedVerifyDataRecursively(const CirGate* gate, const uint32_t& depth) { + GateType type = gate->getType(); + if (existVerifyData(gate, depth)) return; + if (type == PI_GATE) + add_PI_Formula(gate, depth); + else if (RO_GATE == type || RI_GATE == type) { + uint32_t newDepth = depth; + if (depth) { + if (type == RI_GATE) newDepth -= 1; + addBoundedVerifyDataRecursively(gate->getIn0Gate(), newDepth); + } + add_FF_Formula(gate, depth); + } else { + if (type == PO_GATE) { + addBoundedVerifyDataRecursively(gate->getIn0Gate(), depth); + add_FF_Formula(gate, depth); + } else if (type == AIG_GATE) { + addBoundedVerifyDataRecursively(gate->getIn0Gate(), depth); + addBoundedVerifyDataRecursively(gate->getIn1Gate(), depth); + add_AND_Formula(gate, depth); + } else { + // CONST_GATE + add_FALSE_Formula(gate, depth); + } + } +} + +const bool MinisatMgr::existVerifyData(const CirGate* gate, const uint32_t& depth) { + return getVerifyData(gate, depth); +} diff --git a/src/sat/minisatMgr.h b/src/sat/minisatMgr.h new file mode 100644 index 00000000..3ff19dad --- /dev/null +++ b/src/sat/minisatMgr.h @@ -0,0 +1,91 @@ +/**************************************************************************** + FileName [ sat.h ] + PackageName [ sat ] + Synopsis [ Define miniSat solver interface functions ] + Author [ Chung-Yang (Ric) Huang, Cheng-Yin Wu ] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] +****************************************************************************/ + +#pragma once + +#include +#include + +#include "cirGate.h" +#include "cirMgr.h" +#include "minisat/Solver.h" +#include "minisat/gvBitVec.h" +#include "satMgr.h" + +using namespace std; + +namespace gv { +namespace itp { +class ItpMgr; +} // namespace itp +} // namespace gv + +namespace gv { +namespace sat { + +/********** MiniSAT_Solver **********/ +class MinisatMgr : public SatSolverMgr { + friend class gv::itp::ItpMgr; + +public: + MinisatMgr(gv::cir::CirMgr*); + ~MinisatMgr(); + + void reset(); + void assumeRelease(); + void assumeProperty(const size_t&, const bool&); + void assertProperty(const size_t&, const bool&); + void assumeProperty(const gv::cir::CirGate* gate, const bool& invert, const uint32_t& depth); + void assertProperty(const gv::cir::CirGate* gate, const bool& invert, const uint32_t& depth); + const bool simplify(); + const bool solve(); + const bool assump_solve(); + const bool setSolver(); + int getNumClauses() const { return _solver->nRootCla(); } + + // Network to Solver Functions + // const size_t getFormula(const GVNetId&, const uint32_t&); + const GVBitVecX getDataValue(const gv::cir::CirGate*, const uint32_t&) const; + const bool getDataValue(const size_t&) const; + // Variable Interface Functions + inline const size_t reserveFormula() { return getPosVar(newVar()); } + inline const bool isNegFormula(const size_t& v) const { return (v & 1ul); } + inline const size_t getNegFormula(const size_t& v) const { return (v ^ 1ul); } + + // Gate Formula to Solver Functions + void add_FALSE_Formula(const gv::cir::CirGate*, const uint32_t&); + void add_PI_Formula(const gv::cir::CirGate*, const uint32_t&); + void add_FF_Formula(const gv::cir::CirGate*, const uint32_t&); + void add_AND_Formula(const gv::cir::CirGate*, const uint32_t&); + + void addBoundedVerifyData(const gv::cir::CirGate*, const uint32_t&); + const bool existVerifyData(const gv::cir::CirGate*, const uint32_t&); + void resizeNtkData(const uint32_t& num); + + Proof* getProof() { return _solver->proof; }; + int nVars() { return _solver->nVars(); }; + const Var getVerifyData(const gv::cir::CirGate*, const uint32_t&) const; + +private: + const Var newVar(); + /*const Var getVerifyData(const gv::cir::CirGate*, const uint32_t&) const;*/ + void addBoundedVerifyDataRecursively(const gv::cir::CirGate*, const uint32_t&); + + inline const Var getOriVar(const size_t& v) const { return (Var)(v >> 1ul); } + inline const size_t getPosVar(const Var& v) const { return (((size_t)v) << 1ul); } + inline const size_t getNegVar(const Var& v) const { return ((getPosVar(v)) | 1ul); } + + SolverV* _solver; // Pointer to a Minisat solver + Var _curVar; // Variable currently + vec _assump; // Assumption List for assumption solve + vector* _ntkData; // Mapping between GVNetId and Solver Data + const gv::cir::CirMgr* _cirMgr; // Network Under Verification +}; + +} // namespace sat +} // namespace gv diff --git a/src/sat/ref b/src/sat/ref deleted file mode 100644 index 9b65a5dd..00000000 --- a/src/sat/ref +++ /dev/null @@ -1,121 +0,0 @@ -[Qiskit] Qiskit: An open-source quantum computing framework for leveraging today's quantum processors in research, education, and business. https://qiskit.org/ -[LKJ14] Lin, C.-C., Sur-Kolay, S., Jha, N.K., “PAQCS: physical design-aware fault-tolerant quantum circuit synthesis,” IEEE Trans. Very Large Scale Integr. (VLSI) Syst. 23(7), 2014 -[IBM21] IBM Research, “IBM Quantum Development Roadmap,” [Online] Video: https://www.youtube.com/watch?v=bp7UFdtwdTw -[MSRM20] G. Meuli, M. Soeken, M. Roetteler and G. D. Micheli, “ROS: resource-constrained oracle synthesis for quantum computers,” [Online]. Available: https://arxiv.org/abs/2005.00211 -[MSR+19] G. Meuli, M. Soeken, M. Roetteler, N. Bjorner and G. D. Micheli, “Reversible Pebbling Game for Quantum Memory Management,” 2019 Design, Automation & Test in Europe Conference & Exhibition (DATE), 2019, pp. 288-291, doi: 10.23919/DATE.2019.8715092. -[AMM18] M. Amy, A. Parsiad, and M. Mosca. “On the controlled-NOT complexity of controlled-NOT–phase circuits.” Quantum Science and Technology 4.1 (2018): 015002. -[PS16] M. Pedram, A. Shafaei. Layout Optimization for Quantum Circuits with Linear Nearest Neighbor Architectures. IEEE Circuits and Systems Magazine, vol. 16, no. 2, pp. 62-74, Secondquarter 2016, doi: 10.1109/MCAS.2016.2549950. -[TC20] B. Tan, J. Cong. Optimal Layout Synthesis for Quantum Computing. 2020 IEEE/ACM International Conference On Computer Aided Design (ICCAD), 2020, pp. 1-9. -[VDW20] VAN DE WETERING, John. ZX-calculus for the working quantum computer scientist. arXiv preprint arXiv:2012.13966, 2020. Available: https://arxiv.org/abs/2012.13966 -[DKPW20] DUNCAN, Ross, et al. Graph-theoretic Simplification of Quantum Circuits with the ZX-calculus. Quantum, 2020, 4: 279. -[KW20] KISSINGER, Aleks; VAN DE WETERING, John. Reducing the number of non-Clifford gates in quantum circuits. Physical Review A, 2020, 102.2: 022406. -[AMM14] M. Amy, D. Maslov and M. Mosca, "Polynomial-Time T-Depth Optimization of Clifford+T Circuits Via Matroid Partitioning," in IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems, vol. 33, no. 10, pp. 1476-1489, Oct. 2014, doi: 10.1109/TCAD.2014.2341953. -[MSD14] MILLER, D. Michael; SOEKEN, Mathias; DRECHSLER, Rolf. Mapping NCV circuits to optimized Clifford+T circuits. In: International Conference on Reversible Computation. Springer, Cham, 2014. p. 163-175. -[Kit97] A. Y. Kitaev. Quantum computations: algorithms and error correction. Uspekhi Matematicheskikh Nauk, 52(6):53–112, 1997. -[DN06] C. M. Dawson and M. A. Nielsen. The Solovay-Kitaev algorithm. Quantum Information and Computation, 6(1):81–95, 2006 -[Sel15] P. Selinger. Efficient Clifford+T approximation of single-qubit operators. Quantum Information & Computation, 15(1-2):159–180, 2015. -[RS16] N. J. Ross and P. Selinger. Optimal ancilla-free Clifford+T approximation of Z-rotations. Quantum Information & Computation, 16(11-12):901–953, 2016. -[GMM21] V. Gheorghiu, M. Mosca, & P. Mukhopadhyay. (2021). T-count and T-depth of any multi-qubit unitary. arXiv preprint arXiv:2110.10292. -[Lit19] D. Litinski (2019). Magic state distillation: Not as costly as you think. Quantum, 3, 205. -[HEMN20] M. Hanks, M. P. Estarellas, W. J. Munro, & K. Nemoto. (2020). Effective compression of quantum braided circuits aided by ZX-calculus. Physical Review X, 10(4), 041030. -[CH17] E. T. Campbell, & M. Howard (2017). Unified framework for magic state distillation and multiqubit gate synthesis with reduced resource cost. Physical Review A, 95(2), 022316. -[Cro18] A. Cross. "The IBM Q experience and QISKit open-source quantum computing software." APS March Meeting Abstracts. Vol. 2018. 2018. -[AJV01] A. Acín, E. Jané, and G. Vidal. 2001. Optimal estimation of quantum dynamics.Physical Review A64 (2001), 050302. -[MSZ21] M. Lewis, S. Soudjani, and P. Zuliani. Formal Verification of Quantum Programs: Theory, Tools and Challenges. arXiv:2110.01320, 2021. -[Quantiki] Quantiki. List of QC simulators. https://quantiki.org/wiki/list-qc-simulators -[GLR+13] A. S. Green, P. L. Lumsdaine, N. J. Ross, P. Selinger, and B. Valiron, “Quipper: A scalable quantum programming language,” in ACM SIGPLAN Conference on Programming Language Design and Implementation, (PLDI), 2013, pp. 333–342. -[WS14] D. Wecker and K. M. Svore, “Liqui|i: A software design architecture and domain-specific language for quantum computing,” 2014, arXiv: quant-ph/1402.4467. -[KAF+17] N. Khammassi, I. Ashraf, X. Fu, C. G. Almudever, and K. Bertels, “QX: A high-performance quantum computer simulation platform,” in Design, Automation and Test in Europe Conference and Exhibition (DATE), 2017, pp. 464–469. -[Ped17] E. Pednault et al., “Breaking the 49-qubit barrier in the simulation of quantum circuits,” 2017, arXiv: quant-ph/1710.05867. -[SHT18] D. S. Steiger, T. Hner, and M. Troyer, “ProjectQ: An open source software framework for quantum computing,” Quantum, vol. 2, p. 49, Jan 2018. -[VMH09] G. F. Viamontes, I. L. Markov, and J. P. Hayes, Quantum Circuit Simulation. Springer Publishing Company, Incorporated, 2009. -[Sam08] V. Samoladas, “Improved BDD algorithms for the simulation of quantum circuits,” in European Symposium on Algorithms (ESA), 2008, pp. 720–731. -[ZW19] A. Zulehner and R. Wille, “Advanced simulation of quantum computations,” Trans. on CAD of Integrated Circuits and Systems, vol. 38, no. 5, pp. 848–859, 2019. -[ZHW19] A. Zulehner, S. Hillmich, and R. Wille, “How to efficiently handle complex values? Implementing decision diagrams for quantum computing,” in International Conference on Computer-Aided Design (ICCAD), 2019, pp. 1–7. -[NWM+16] P. Niemann, R. Wille, D. M. Miller, M. A. Thornton, and R. Drechsler, “QMDDs: Efficient quantum function representation and manipulation,” IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems, vol. 35, no. 1, pp. 86–99, 2016. -[ZND+19] A. Zulehner, P. Niemann, R. Drechsler, and R. Wille, “Accuracy and compactness in decision diagrams for quantum computation,” in Design, Automation and Test in Europe Conference and Exhibition (DATE), 2019, pp. 280–283. -[BW21] L. Burgholzer and R. Wille. 2021. Advanced Equivalence Checking for Quantum Circuits. IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems 40, 9 (2021), 1810–1824. -[HYF+21] X. Hong, M. Ying, Y. Feng, X. Zhou, and S. Li. 2021. Approximate Equivalence Checking of Noisy Quantum Circuits. In Proc. DAC. 637–642. -[HZL+20] X. Hong, X. Zhou, S. Li, Y. Feng, and M. Ying. 2020. A Tensor Network based Decision Diagram for Representation of Quantum Circuits. CoRR abs/2009.02618 (2020). -[ZHW19] Alwin Zulehner, Stefan Hillmich, and Robert Wille. 2019. How to Efficiently Handle Complex Values? Implementing Decision Diagrams for Quantum Computing. In Proc. ICCAD. 1–7. -[WPD13] Robert Wille, Nils Przigoda, and Rolf Drechsler. 2013. A compact and efficient SAT encoding for quantum circuits. In Proc. Africon. 1–6. -[YM10] S. Yamashita and I. L. Markov. 2010. Fast Equivalence-Checking For Quantum Circuits. In Proc. NANOARCH. 23–28. -[YF18] M. Ying and Y. Feng. 2018. Model Checking Quantum Systems — A Survey. arXiv:1807.09466 -[KW97] A. Kondacs and J. Watrous. 1997. On the Power of Quantum Finite State Automata. In Proc. FOCS, 1997, 66–75. -[SZ00] J. W. Santhders and Pa Zuliani. 2000. Quantum Programming. In Mathematics of Program Construction, R. Backhouse and J. N. Oliveira (Eds.). Springer, 80–99. -[DP06] E. D’Hondt and P. Panangaden. 2006. Quantum weakest preconditions. Math. Struct. Comput. Sci. 16, 3 (2006), 429–451. -[Ying11] M. Ying. 2011. Floyd-hoare logic for quantum programs. ACM Trans. Program. Lang. Syst. 33, 6 (2011), 19:1–19:49. -[FY20] Y. Feng and M. Ying. 2020. Quantum Hoare logic with classical variables. CoRR abs/2008.06812 (2020). arXiv:2008.06812 https://arxiv.org/abs/2008.06812. -[BCM08] P. Baltazar, R. Chadha, and P. Mateus. 2008. Quantum Computation Tree Logic — Model Checking and Complete Calculus. International Journal of Quantum Information 06, 02 (2008), 219–236. -[FYY13] Y. Feng, N. Yu, and M. Ying. 2013. Model checking quantum Markov chains. J. Comput. System Sci. 79, 7 (2013), 1181 – 1198. -[XFM+21] M. Xu, J. Fu, J. Mei, and Y. Deng. 2021. An Algebraic Method to Fidelity-based Model Checking over Quantum Markov Chains. (2021). arXiv:2101.04971. -[PRZ17] J. Paykin, R. Rand, and S. Zdancewic. 2017. QWIRE: A Core Language for Quantum Circuits. SIGPLAN Not. 52, 1 (Jan. 2017), 846–858. -[HRH+20] K. Hietala, R. Rand, S.-H. Hung, L. Li, and M. Hicks. 2020. Proving Quantum Programs Correct. arXiv e-prints (Oct. 2020). arXiv:2010.01240. -[Coq20] The Coq Development Team. 2020. The Coq Proof Assistant, version 8.12.0. -[LZW+19] J. Liu, B. Zhan, S. Wang, S. Ying, T. Liu, Y. Li, M. Ying, and N. Zhan. 2019. Quantum Hoare Logic. Archive of Formal Proofs (March 2019). https://isa-afp.org/entries/QHLProver.html, Formal proof development -[BLH20] A. Bordg, H. Lachnitt, and Y. He. 2020. Isabelle Marries Dirac: a Library for Quantum Computation and Quantum Information. Archive of Formal Proofs (Nov. 2020). -[CBB+20] C. Chareton, S. Bardin, F. Bobot, V. Perrelle, and B. Valiron. 2020. Toward certified quantum programming. CoRR abs/2003.05841 (2020). arXiv:2003.05841 -[HWH+20] C.-Y. Hsieh, C.-H. Wu, C.-H. Huang, H.-S. Goan, J. C.-M. Li: Realistic Fault Models and Fault Simulation for Quantum Dot Quantum Circuits. DAC 2020: 1-6. -[JKL20] J.-H. R. Jiang, V. N. Kravets, N.-Z. Lee: Engineering Change Order for Combinational and Sequential Design Rectification. DATE 2020: 726-731. -[MSR+19] G. Meuli, M. Soeken, M. Roetteler, G. De Micheli: ROS: Resource-constrained Oracle Synthesis for Quantum Computers. QPL 2019: 119-130. -[PGO] How To Build Clang and LLVM with Profile-Guided Optimizations. https://llvm.org/docs/HowToBuildWithPGO.html -[QOSF] Quantum Open Source Foundation (QOSF). List of Open Quantum Projects, https://qosf.org/project_list/ -[SHR18] M. Soeken, T. Häner, M. Roetteler: Programming quantum computers using design automation. DATE 2018: 137-146. -[WHL+20] C.-H. Wu, C.-Y. Hsieh, J.-Y. Li, J. C.-M. Li: qATG: Automatic Test Generation for Quantum Circuits. ITC 2020: 1-10. -[KAS20] N. Khammassi, I. Ashraf, J. v. Someren, R. Nane, A. M. Krol, M. A. Rol, L. Lao, K. Bertels, C. G. Almudever. OpenQL : A Portable Quantum Programming Framework for Quantum Accelerators -[MQ#] Microsoft Documentation. Q# and the Quantum Development Kit - Testing and debugging. https://docs.microsoft.com/en-us/azure/quantum/user-guide/testing-debugging -[CIRQ] Cirq: A python framework for creating, editing, and invoking noisy intermediate scale quantum circuits,” (2018). https://github.com/quantumlib/Cirq -[STA21] Sam Stanwyck. NVIDIA Sets World Record for QuantumComputing Simulation With cuQuantum Running on DGX SuperPOD. (November 9, 2021) https://blogs.nvidia.com/blog/2021/11/09/cuquantum-world-record/ -[WIG21] Kyle Wiggers. Alphabet is repurposing Google TPUs for quantum computing simulations. https://venturebeat.com/2021/03/10/alphabet-is-repurposing-google-tpus-for-quantum-computing-simulations/ -[MHB21] Alan Morningstar, Markus Hauru, Jackson Beall, Martin Ganahl, Adam G. M. Lewis, Vedika Khemani, Guifre Vidal. Simulation of quantum many-body dynamics with Tensor Processing Units: Floquet prethermalization. arXiv:2111.08044 [Submitted on 15 Nov 2021] -[BVM+20] Michael Broughton, Guillaume Verdon, Trevor McCourt, Antonio J. Martinez, Jae Hyeon Yoo, Sergei V. Isakov, Philip Massey, Ramin Halavati, Murphy Yuezhen Niu, Alexander Zlokapa, Evan Peters, Owen Lockwood, Andrea Skolik, Sofiene Jerbi, Vedran Dunjko, Martin Leib, Michael Streif, David Von Dollen, Hongxiang Chen, Shuxiang Cao, Roeland Wiersema, Hsin-Yuan Huang, Jarrod R. McClean, Ryan Babbush, Sergio Boixo, Dave Bacon, Alan K. Ho, Hartmut Neven, Masoud Mohseni. TensorFlow Quantum: A Software Framework for Quantum Machine Learning. arXiv:2003.02989 [Submitted on 6 Mar 2020 (v1), last revised 26 Aug 2021 (thisversion, v2)] -[GRE] Brandan Gregg, Linux Performance. https://www.brendangregg.com/linuxperf.html -[VTU] Intel VTune Profiler. https://www.intel.com/content/www/us/en/developer/tools/oneapi/vtune-profiler.html -[UPR] AMD μProf. https://developer.amd.com/amd-uprof/ -[QIS] Qiskit, Open-Source Quantum Development. https://qiskit.org/ -[QGA] Qgate, Quntum circuit simulator. https://github.com/shinmorino/qgate -[QUI] Quimb. https://quimb.readthedocs.io/en/latest/ -[TAIWANIA] Taiwania Supercomputers. https://www.nchc.org.tw/Page?itemid=2&mid=4 -[JBB+19] Jones, T., Brown, A., Bush, I. et al. QuEST and High Performance Simulation of Quantum Computers. Sci Rep 9, 10736 (2019). -[WDD+19] Xin-Chuan Wu, Sheng Di, Emma Maitreyee Dasgupta, Franck Cappello, Hal Finkel, Yuri Alexeev, and Frederic T. Chong. 2019. Full-state quantum circuit simulation by using data compression. In Proceedings of the International Conference for High Performance Computing, Networking, Storage and Analysis (SC '19). Association for Computing Machinery, New York, NY, USA, Article 80, 1–24. -[TN] https://tensornetwork.org/ -[GRA18] Gray, (2018). quimb: A python package for quantum information and many-body calculations. Journal of Open Source Software, 3(29), 819. -[VBN+19] Villalonga, B., Boixo, S., Nelson, B. et al. A flexible high-performance simulator for verifying and benchmarking quantum circuits implemented on real hardware. npj Quantum Inf 5, 86 (2019). -[HZN+21] Huang, C., Zhang, F., Newman, M. et al. Efficient parallelization of tensor network contraction for simulating quantum computation. Nat Comput Sci 1, 578–587 (2021). -[WAH20] H. M. Waidyasooriya and M. Hariyama, "A GPU-Based Quantum Annealing Simulator for Fully-Connected Ising Models Utilizing Spatial and Temporal Parallelism," in IEEE Access, vol. 8, pp. 67929-67939, 2020 -[VEG14] M. N. Velev and P. Gao, "Efficient parallel GPU algorithms for BDD manipulation," 2014 19th Asia and South Pacific Design Automation Conference (ASP-DAC), 2014, pp. 750-755, doi: 10.1109/ASPDAC.2014.6742980. -[TJJ21] Y.-H. Tsai, J.-H. R. Jiang, C.-S. Jhang: Bit-Slicing the Hilbert Space: Scaling Up Accurate Quantum Circuit Simulation. DAC 2021: 1-6. (https://arxiv.org/abs/2007.09304) -[LHT+18] C.-Y. Liu, P.-Y. Huang, C.-H. Tu, S.-H. Hung: A Fastand Scalable Cluster Simulator for Network Performance Projection of HPC Applications. HPCS 2018: 970-977 -[YTH19] Chih Wei Yeh, Chia-Heng Tu, Shih-Hao Hung: Rapid Hybrid Simulation Methods for Exploring the Design Space of Signal Processors with Dynamic and Scalable Timing Models. Signal Processing Systems 91(3-4): 247-259 (2019) -[HYH16] Hao-Che Hsu, Chih Wei Yeh, Shih-Hao Hung, Wei-Chung Hsu, Chung-Ta King, Yeh-Ching Chung: HSAemu 2.0: Full System Emulation for HSA platforms with Soft-MMU. ACM RACS 2016: 230-235. -[Qiskit19] Héctor Abraham, et al. Qiskit: An Open-source Framework for Quantum Computing. 2019. -[Bera17] Debajyoti Bera. Detection and diagnosis of single faults in quantum circuits. IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems 37.3: 587-600, 2017. -[BSSO18] Xavi Bonet-Monroig, et al. Low-cost error mitigation by symmetry verification. Physical Review A 98.6: 062339, 2018. -[CBSNG19] Andrew W. Cross, et al. Validating quantum computers using randomized model circuits. Physical Review A 100.3, 2019. -[CN97] Isaac L. Chuang, and Michael A. Nielsen. Prescription for experimental determination of the dynamics of a quantum black box, Journal of Modern Optics 44.11-12: 2455-2467, 1997. -[EBL18] Suguru Endo, Simon C. Benjamin, and Ying Li. Practical quantum error mitigation for near-future applications. Physical Review X 8.3: 031027, 2018. -[Google20] Arute, Frank, et al. Observation of separated dynamics of charge and spin in the fermi-hubbard model. arXiv preprint arXiv:2010.07965, 2020. -[HPB04] John P. Hayes, Ilia Polian, and Bernd Becker. Testing for missing-gate faults in reversible circuits, IEEE 13th Asian Test Symposium, 2004. -[HWHGL20] Hsieh, Cheng-Yun, et al. Realistic fault models and fault simulation for quantum dot quantum circuits. 2020 57th ACM/IEEE Design Automation Conference, IEEE, 2020. -[IBM blog] https://research.ibm.com/blog/heavy-hex-lattice/, 2021 -[IBM Q] IBM Quantum. https://quantum-computing.ibm.com/, 2021 -[KLR+08] Emanuel Knill et al., Randomized benchmarking of quantum gates, Physical Review A 77.1, 2008. -[KTC+19] Abhinav Kandala, et al. Error mitigation extends the computational reach of a noisy quantum processor. Nature 567.7749: 491-495, 2019. -[LB17] Ying Li, and Simon C. Benjamin. Efficient variational quantum simulator incorporating active error minimization. Physical Review X 7.2: 021050, 2017. -[MGE12] Easwar Magesan, Jay M. Gambetta, and Joseph Emerson. Characterizing quantum gates via randomized benchmarking. Physical Review A 85.4, 2012. -[MJR+20] Jarrod R. McClean, et al. Decoding quantum errors with subspace expansions. Nature communications 11.1: 1-9, 2020. -[MKCJ17] Jarrod R. McClean, et al. Hybrid quantum-classical hierarchy for mitigation of decoherence and determination of excited states. Physical Review A 95.4: 042308, 2017. -[MYB19] Sam McArdle, Xiao Yuan, and Simon Benjamin. Error-mitigated digital quantum simulation. Physical review letters 122.18: 180501, 2019. -[MYS12] Matthew McKague, Tzyh Haur Yang, and Valerio Scarani, Robust self-testing of the singlet, Journal of Physics A: Mathematical and Theoretical 45.45, 2012. -[NC02] Michael A. Nielsen, and Isaac Chuang. Quantum computation and quantum information. 2002. -[OPR+21] Thomas E. O’Brien, et al. Error mitigation via verified phase estimation. PRX Quantum 2.2: 020317, 2021. -[PAPH11] Alexandru Paler, et al. Tomographic testing and validation of probabilistic circuits. 2011 Sixteenth IEEE European Test Symposium, 2011. -[PFBH05] Polian, Ilia, et al. A family of logical fault models for reversible circuits. 14th Asian Test Symposium, 2005. -[PPH12] Alexandru Paler, Ilia Polian, and John P. Hayes. Detection and diagnosis of faulty quantum circuits. 17th Asia and South Pacific Design Automation Conference, 2012. -[ŠASA16] Ivan Šupić, et al., Self-testing protocols based on the chained Bell inequalities, New Journal of Physics 18.3, 2016. -[TBG17] Kristan Temme, Sergey Bravyi, and Jay M. Gambetta. Error mitigation for short-depth quantum circuits. Physical review letters 119.18: 180509, 2017. -[Uhrig07] Götz S. Uhrig Keeping a quantum bit alive by optimized π-pulse sequences. Physical Review Letters 98.10: 100504, 2007. -[WHLL20] Wu, Chen-Hung, et al. qATG: Automatic Test Generation for Quantum Circuits. 2020 IEEE International Test Conference, 2020. -[WZD11] Robert Wille, Hongyan Zhang, and Rolf Drechsler, ATPG for reversible circuits using simulation, Boolean satisfiability, and pseudo Boolean optimization, IEEE Computer Society Annual Symposium on VLSI, 2011. -[ZWD11] Hongyan Zhang, Robert Wille, and Rolf Drechsler. Improved fault diagnosis for reversible circuits. 2011 Asian Test Symposium, 2011. -[ZZZD20] Yuan-Hang Zhang, et al. Topological quantum compiling with reinforcement learning. Physical Review Letters 125.17: 170501, 2020. diff --git a/src/sat/reff b/src/sat/reff deleted file mode 100644 index 2890fcd3..00000000 --- a/src/sat/reff +++ /dev/null @@ -1,121 +0,0 @@ -[AJV01] A. Acín, E. Jané, and G. Vidal. 2001. Optimal estimation of quantum dynamics.Physical Review A64 (2001), 050302. -[AMM14] M. Amy, D. Maslov and M. Mosca, "Polynomial-Time T-Depth Optimization of Clifford+T Circuits Via Matroid Partitioning," in IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems, vol. 33, no. 10, pp. 1476-1489, Oct. 2014, doi: 10.1109/TCAD.2014.2341953. -[AMM18] M. Amy, A. Parsiad, and M. Mosca. “On the controlled-NOT complexity of controlled-NOT–phase circuits.” Quantum Science and Technology 4.1 (2018): 015002. -[BCM08] P. Baltazar, R. Chadha, and P. Mateus. 2008. Quantum Computation Tree Logic — Model Checking and Complete Calculus. International Journal of Quantum Information 06, 02 (2008), 219–236. -[BLH20] A. Bordg, H. Lachnitt, and Y. He. 2020. Isabelle Marries Dirac: a Library for Quantum Computation and Quantum Information. Archive of Formal Proofs (Nov. 2020). -[BSSO18] Xavi Bonet-Monroig, et al. Low-cost error mitigation by symmetry verification. Physical Review A 98.6: 062339, 2018. -[BVM+20] Michael Broughton, Guillaume Verdon, Trevor McCourt, Antonio J. Martinez, Jae Hyeon Yoo, Sergei V. Isakov, Philip Massey, Ramin Halavati, Murphy Yuezhen Niu, Alexander Zlokapa, Evan Peters, Owen Lockwood, Andrea Skolik, Sofiene Jerbi, Vedran Dunjko, Martin Leib, Michael Streif, David Von Dollen, Hongxiang Chen, Shuxiang Cao, Roeland Wiersema, Hsin-Yuan Huang, Jarrod R. McClean, Ryan Babbush, Sergio Boixo, Dave Bacon, Alan K. Ho, Hartmut Neven, Masoud Mohseni. TensorFlow Quantum: A Software Framework for Quantum Machine Learning. arXiv:2003.02989 [Submitted on 6 Mar 2020 (v1), last revised 26 Aug 2021 (thisversion, v2)] -[BW21] L. Burgholzer and R. Wille. 2021. Advanced Equivalence Checking for Quantum Circuits. IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems 40, 9 (2021), 1810–1824. -[Bera17] Debajyoti Bera. Detection and diagnosis of single faults in quantum circuits. IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems 37.3: 587-600, 2017. -[CBB+20] C. Chareton, S. Bardin, F. Bobot, V. Perrelle, and B. Valiron. 2020. Toward certified quantum programming. CoRR abs/2003.05841 (2020). arXiv:2003.05841 -[CBSNG19] Andrew W. Cross, et al. Validating quantum computers using randomized model circuits. Physical Review A 100.3, 2019. -[CH17] E. T. Campbell, & M. Howard (2017). Unified framework for magic state distillation and multiqubit gate synthesis with reduced resource cost. Physical Review A, 95(2), 022316. -[CIRQ] Cirq: A python framework for creating, editing, and invoking noisy intermediate scale quantum circuits,” (2018). https://github.com/quantumlib/Cirq -[CN97] Isaac L. Chuang, and Michael A. Nielsen. Prescription for experimental determination of the dynamics of a quantum black box, Journal of Modern Optics 44.11-12: 2455-2467, 1997. -[Coq20] The Coq Development Team. 2020. The Coq Proof Assistant, version 8.12.0. -[Cro18] A. Cross. "The IBM Q experience and QISKit open-source quantum computing software." APS March Meeting Abstracts. Vol. 2018. 2018. -[DKPW20] DUNCAN, Ross, et al. Graph-theoretic Simplification of Quantum Circuits with the ZX-calculus. Quantum, 2020, 4: 279. -[DN06] C. M. Dawson and M. A. Nielsen. The Solovay-Kitaev algorithm. Quantum Information and Computation, 6(1):81–95, 2006 -[DP06] E. D’Hondt and P. Panangaden. 2006. Quantum weakest preconditions. Math. Struct. Comput. Sci. 16, 3 (2006), 429–451. -[EBL18] Suguru Endo, Simon C. Benjamin, and Ying Li. Practical quantum error mitigation for near-future applications. Physical Review X 8.3: 031027, 2018. -[FY20] Y. Feng and M. Ying. 2020. Quantum Hoare logic with classical variables. CoRR abs/2008.06812 (2020). arXiv:2008.06812 https://arxiv.org/abs/2008.06812. -[FYY13] Y. Feng, N. Yu, and M. Ying. 2013. Model checking quantum Markov chains. J. Comput. System Sci. 79, 7 (2013), 1181 – 1198. -[GLR+13] A. S. Green, P. L. Lumsdaine, N. J. Ross, P. Selinger, and B. Valiron, “Quipper: A scalable quantum programming language,” in ACM SIGPLAN Conference on Programming Language Design and Implementation, (PLDI), 2013, pp. 333–342. -[GMM21] V. Gheorghiu, M. Mosca, & P. Mukhopadhyay. (2021). T-count and T-depth of any multi-qubit unitary. arXiv preprint arXiv:2110.10292. -[GRA18] Gray, (2018). quimb: A python package for quantum information and many-body calculations. Journal of Open Source Software, 3(29), 819. -[GRE] Brandan Gregg, Linux Performance. https://www.brendangregg.com/linuxperf.html -[Google20] Arute, Frank, et al. Observation of separated dynamics of charge and spin in the fermi-hubbard model. arXiv preprint arXiv:2010.07965, 2020. -[HEMN20] M. Hanks, M. P. Estarellas, W. J. Munro, & K. Nemoto. (2020). Effective compression of quantum braided circuits aided by ZX-calculus. Physical Review X, 10(4), 041030. -[HPB04] John P. Hayes, Ilia Polian, and Bernd Becker. Testing for missing-gate faults in reversible circuits, IEEE 13th Asian Test Symposium, 2004. -[HRH+20] K. Hietala, R. Rand, S.-H. Hung, L. Li, and M. Hicks. 2020. Proving Quantum Programs Correct. arXiv e-prints (Oct. 2020). arXiv:2010.01240. -[HWH+20] C.-Y. Hsieh, C.-H. Wu, C.-H. Huang, H.-S. Goan, J. C.-M. Li: Realistic Fault Models and Fault Simulation for Quantum Dot Quantum Circuits. DAC 2020: 1-6. -[HWHGL20] Hsieh, Cheng-Yun, et al. Realistic fault models and fault simulation for quantum dot quantum circuits. 2020 57th ACM/IEEE Design Automation Conference, IEEE, 2020. -[HYF+21] X. Hong, M. Ying, Y. Feng, X. Zhou, and S. Li. 2021. Approximate Equivalence Checking of Noisy Quantum Circuits. In Proc. DAC. 637–642. -[HYH16] Hao-Che Hsu, Chih Wei Yeh, Shih-Hao Hung, Wei-Chung Hsu, Chung-Ta King, Yeh-Ching Chung: HSAemu 2.0: Full System Emulation for HSA platforms with Soft-MMU. ACM RACS 2016: 230-235. -[HZL+20] X. Hong, X. Zhou, S. Li, Y. Feng, and M. Ying. 2020. A Tensor Network based Decision Diagram for Representation of Quantum Circuits. CoRR abs/2009.02618 (2020). -[HZN+21] Huang, C., Zhang, F., Newman, M. et al. Efficient parallelization of tensor network contraction for simulating quantum computation. Nat Comput Sci 1, 578–587 (2021). -[IBM Q] IBM Quantum. https://quantum-computing.ibm.com/, 2021 -[IBM blog] https://research.ibm.com/blog/heavy-hex-lattice/, 2021 -[IBM21] IBM Research, “IBM Quantum Development Roadmap,” [Online] Video: https://www.youtube.com/watch?v=bp7UFdtwdTw -[JBB+19] Jones, T., Brown, A., Bush, I. et al. QuEST and High Performance Simulation of Quantum Computers. Sci Rep 9, 10736 (2019). -[JKL20] J.-H. R. Jiang, V. N. Kravets, N.-Z. Lee: Engineering Change Order for Combinational and Sequential Design Rectification. DATE 2020: 726-731. -[KAF+17] N. Khammassi, I. Ashraf, X. Fu, C. G. Almudever, and K. Bertels, “QX: A high-performance quantum computer simulation platform,” in Design, Automation and Test in Europe Conference and Exhibition (DATE), 2017, pp. 464–469. -[KAS20] N. Khammassi, I. Ashraf, J. v. Someren, R. Nane, A. M. Krol, M. A. Rol, L. Lao, K. Bertels, C. G. Almudever. OpenQL : A Portable Quantum Programming Framework for Quantum Accelerators -[KLR+08] Emanuel Knill et al., Randomized benchmarking of quantum gates, Physical Review A 77.1, 2008. -[KTC+19] Abhinav Kandala, et al. Error mitigation extends the computational reach of a noisy quantum processor. Nature 567.7749: 491-495, 2019. -[KW20] KISSINGER, Aleks; VAN DE WETERING, John. Reducing the number of non-Clifford gates in quantum circuits. Physical Review A, 2020, 102.2: 022406. -[KW97] A. Kondacs and J. Watrous. 1997. On the Power of Quantum Finite State Automata. In Proc. FOCS, 1997, 66–75. -[Kit97] A. Y. Kitaev. Quantum computations: algorithms and error correction. Uspekhi Matematicheskikh Nauk, 52(6):53–112, 1997. -[LB17] Ying Li, and Simon C. Benjamin. Efficient variational quantum simulator incorporating active error minimization. Physical Review X 7.2: 021050, 2017. -[LHT+18] C.-Y. Liu, P.-Y. Huang, C.-H. Tu, S.-H. Hung: A Fastand Scalable Cluster Simulator for Network Performance Projection of HPC Applications. HPCS 2018: 970-977 -[LKJ14] Lin, C.-C., Sur-Kolay, S., Jha, N.K., “PAQCS: physical design-aware fault-tolerant quantum circuit synthesis,” IEEE Trans. Very Large Scale Integr. (VLSI) Syst. 23(7), 2014 -[LZW+19] J. Liu, B. Zhan, S. Wang, S. Ying, T. Liu, Y. Li, M. Ying, and N. Zhan. 2019. Quantum Hoare Logic. Archive of Formal Proofs (March 2019). https://isa-afp.org/entries/QHLProver.html, Formal proof development -[Lit19] D. Litinski (2019). Magic state distillation: Not as costly as you think. Quantum, 3, 205. -[MGE12] Easwar Magesan, Jay M. Gambetta, and Joseph Emerson. Characterizing quantum gates via randomized benchmarking. Physical Review A 85.4, 2012. -[MHB21] Alan Morningstar, Markus Hauru, Jackson Beall, Martin Ganahl, Adam G. M. Lewis, Vedika Khemani, Guifre Vidal. Simulation of quantum many-body dynamics with Tensor Processing Units: Floquet prethermalization. arXiv:2111.08044 [Submitted on 15 Nov 2021] -[MJR+20] Jarrod R. McClean, et al. Decoding quantum errors with subspace expansions. Nature communications 11.1: 1-9, 2020. -[MKCJ17] Jarrod R. McClean, et al. Hybrid quantum-classical hierarchy for mitigation of decoherence and determination of excited states. Physical Review A 95.4: 042308, 2017. -[MQ#] Microsoft Documentation. Q# and the Quantum Development Kit - Testing and debugging. https://docs.microsoft.com/en-us/azure/quantum/user-guide/testing-debugging -[MSD14] MILLER, D. Michael; SOEKEN, Mathias; DRECHSLER, Rolf. Mapping NCV circuits to optimized Clifford+T circuits. In: International Conference on Reversible Computation. Springer, Cham, 2014. p. 163-175. -[MSR+19] G. Meuli, M. Soeken, M. Roetteler, G. De Micheli: ROS: Resource-constrained Oracle Synthesis for Quantum Computers. QPL 2019: 119-130. -[MSR+19] G. Meuli, M. Soeken, M. Roetteler, N. Bjorner and G. D. Micheli, “Reversible Pebbling Game for Quantum Memory Management,” 2019 Design, Automation & Test in Europe Conference & Exhibition (DATE), 2019, pp. 288-291, doi: 10.23919/DATE.2019.8715092. -[MSRM20] G. Meuli, M. Soeken, M. Roetteler and G. D. Micheli, “ROS: resource-constrained oracle synthesis for quantum computers,” [Online]. Available: https://arxiv.org/abs/2005.00211 -[MSZ21] M. Lewis, S. Soudjani, and P. Zuliani. Formal Verification of Quantum Programs: Theory, Tools and Challenges. arXiv:2110.01320, 2021. -[MYB19] Sam McArdle, Xiao Yuan, and Simon Benjamin. Error-mitigated digital quantum simulation. Physical review letters 122.18: 180501, 2019. -[MYS12] Matthew McKague, Tzyh Haur Yang, and Valerio Scarani, Robust self-testing of the singlet, Journal of Physics A: Mathematical and Theoretical 45.45, 2012. -[NC02] Michael A. Nielsen, and Isaac Chuang. Quantum computation and quantum information. 2002. -[NWM+16] P. Niemann, R. Wille, D. M. Miller, M. A. Thornton, and R. Drechsler, “QMDDs: Efficient quantum function representation and manipulation,” IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems, vol. 35, no. 1, pp. 86–99, 2016. -[OPR+21] Thomas E. O’Brien, et al. Error mitigation via verified phase estimation. PRX Quantum 2.2: 020317, 2021. -[PAPH11] Alexandru Paler, et al. Tomographic testing and validation of probabilistic circuits. 2011 Sixteenth IEEE European Test Symposium, 2011. -[PFBH05] Polian, Ilia, et al. A family of logical fault models for reversible circuits. 14th Asian Test Symposium, 2005. -[PGO] How To Build Clang and LLVM with Profile-Guided Optimizations. https://llvm.org/docs/HowToBuildWithPGO.html -[PPH12] Alexandru Paler, Ilia Polian, and John P. Hayes. Detection and diagnosis of faulty quantum circuits. 17th Asia and South Pacific Design Automation Conference, 2012. -[PRZ17] J. Paykin, R. Rand, and S. Zdancewic. 2017. QWIRE: A Core Language for Quantum Circuits. SIGPLAN Not. 52, 1 (Jan. 2017), 846–858. -[PS16] M. Pedram, A. Shafaei. Layout Optimization for Quantum Circuits with Linear Nearest Neighbor Architectures. IEEE Circuits and Systems Magazine, vol. 16, no. 2, pp. 62-74, Secondquarter 2016, doi: 10.1109/MCAS.2016.2549950. -[Ped17] E. Pednault et al., “Breaking the 49-qubit barrier in the simulation of quantum circuits,” 2017, arXiv: quant-ph/1710.05867. -[QGA] Qgate, Quntum circuit simulator. https://github.com/shinmorino/qgate -[QIS] Qiskit, Open-Source Quantum Development. https://qiskit.org/ -[QOSF] Quantum Open Source Foundation (QOSF). List of Open Quantum Projects, https://qosf.org/project_list/ -[QUI] Quimb. https://quimb.readthedocs.io/en/latest/ -[Qiskit19] Héctor Abraham, et al. Qiskit: An Open-source Framework for Quantum Computing. 2019. -[Qiskit] Qiskit: An open-source quantum computing framework for leveraging today's quantum processors in research, education, and business. https://qiskit.org/ -[Quantiki] Quantiki. List of QC simulators. https://quantiki.org/wiki/list-qc-simulators -[RS16] N. J. Ross and P. Selinger. Optimal ancilla-free Clifford+T approximation of Z-rotations. Quantum Information & Computation, 16(11-12):901–953, 2016. -[SHR18] M. Soeken, T. Häner, M. Roetteler: Programming quantum computers using design automation. DATE 2018: 137-146. -[SHT18] D. S. Steiger, T. Hner, and M. Troyer, “ProjectQ: An open source software framework for quantum computing,” Quantum, vol. 2, p. 49, Jan 2018. -[STA21] Sam Stanwyck. NVIDIA Sets World Record for QuantumComputing Simulation With cuQuantum Running on DGX SuperPOD. (November 9, 2021) https://blogs.nvidia.com/blog/2021/11/09/cuquantum-world-record/ -[SZ00] J. W. Santhders and Pa Zuliani. 2000. Quantum Programming. In Mathematics of Program Construction, R. Backhouse and J. N. Oliveira (Eds.). Springer, 80–99. -[Sam08] V. Samoladas, “Improved BDD algorithms for the simulation of quantum circuits,” in European Symposium on Algorithms (ESA), 2008, pp. 720–731. -[Sel15] P. Selinger. Efficient Clifford+T approximation of single-qubit operators. Quantum Information & Computation, 15(1-2):159–180, 2015. -[TAIWANIA] Taiwania Supercomputers. https://www.nchc.org.tw/Page?itemid=2&mid=4 -[TBG17] Kristan Temme, Sergey Bravyi, and Jay M. Gambetta. Error mitigation for short-depth quantum circuits. Physical review letters 119.18: 180509, 2017. -[TC20] B. Tan, J. Cong. Optimal Layout Synthesis for Quantum Computing. 2020 IEEE/ACM International Conference On Computer Aided Design (ICCAD), 2020, pp. 1-9. -[TJJ21] Y.-H. Tsai, J.-H. R. Jiang, C.-S. Jhang: Bit-Slicing the Hilbert Space: Scaling Up Accurate Quantum Circuit Simulation. DAC 2021: 1-6. (https://arxiv.org/abs/2007.09304) -[TN] https://tensornetwork.org/ -[UPR] AMD μProf. https://developer.amd.com/amd-uprof/ -[Uhrig07] Götz S. Uhrig Keeping a quantum bit alive by optimized π-pulse sequences. Physical Review Letters 98.10: 100504, 2007. -[VBN+19] Villalonga, B., Boixo, S., Nelson, B. et al. A flexible high-performance simulator for verifying and benchmarking quantum circuits implemented on real hardware. npj Quantum Inf 5, 86 (2019). -[VDW20] VAN DE WETERING, John. ZX-calculus for the working quantum computer scientist. arXiv preprint arXiv:2012.13966, 2020. Available: https://arxiv.org/abs/2012.13966 -[VEG14] M. N. Velev and P. Gao, "Efficient parallel GPU algorithms for BDD manipulation," 2014 19th Asia and South Pacific Design Automation Conference (ASP-DAC), 2014, pp. 750-755, doi: 10.1109/ASPDAC.2014.6742980. -[VMH09] G. F. Viamontes, I. L. Markov, and J. P. Hayes, Quantum Circuit Simulation. Springer Publishing Company, Incorporated, 2009. -[VTU] Intel VTune Profiler. https://www.intel.com/content/www/us/en/developer/tools/oneapi/vtune-profiler.html -[WAH20] H. M. Waidyasooriya and M. Hariyama, "A GPU-Based Quantum Annealing Simulator for Fully-Connected Ising Models Utilizing Spatial and Temporal Parallelism," in IEEE Access, vol. 8, pp. 67929-67939, 2020 -[WDD+19] Xin-Chuan Wu, Sheng Di, Emma Maitreyee Dasgupta, Franck Cappello, Hal Finkel, Yuri Alexeev, and Frederic T. Chong. 2019. Full-state quantum circuit simulation by using data compression. In Proceedings of the International Conference for High Performance Computing, Networking, Storage and Analysis (SC '19). Association for Computing Machinery, New York, NY, USA, Article 80, 1–24. -[WHL+20] C.-H. Wu, C.-Y. Hsieh, J.-Y. Li, J. C.-M. Li: qATG: Automatic Test Generation for Quantum Circuits. ITC 2020: 1-10. -[WHLL20] Wu, Chen-Hung, et al. qATG: Automatic Test Generation for Quantum Circuits. 2020 IEEE International Test Conference, 2020. -[WIG21] Kyle Wiggers. Alphabet is repurposing Google TPUs for quantum computing simulations. https://venturebeat.com/2021/03/10/alphabet-is-repurposing-google-tpus-for-quantum-computing-simulations/ -[WPD13] Robert Wille, Nils Przigoda, and Rolf Drechsler. 2013. A compact and efficient SAT encoding for quantum circuits. In Proc. Africon. 1–6. -[WS14] D. Wecker and K. M. Svore, “Liqui|i: A software design architecture and domain-specific language for quantum computing,” 2014, arXiv: quant-ph/1402.4467. -[WZD11] Robert Wille, Hongyan Zhang, and Rolf Drechsler, ATPG for reversible circuits using simulation, Boolean satisfiability, and pseudo Boolean optimization, IEEE Computer Society Annual Symposium on VLSI, 2011. -[XFM+21] M. Xu, J. Fu, J. Mei, and Y. Deng. 2021. An Algebraic Method to Fidelity-based Model Checking over Quantum Markov Chains. (2021). arXiv:2101.04971. -[YF18] M. Ying and Y. Feng. 2018. Model Checking Quantum Systems — A Survey. arXiv:1807.09466 -[YM10] S. Yamashita and I. L. Markov. 2010. Fast Equivalence-Checking For Quantum Circuits. In Proc. NANOARCH. 23–28. -[YTH19] Chih Wei Yeh, Chia-Heng Tu, Shih-Hao Hung: Rapid Hybrid Simulation Methods for Exploring the Design Space of Signal Processors with Dynamic and Scalable Timing Models. Signal Processing Systems 91(3-4): 247-259 (2019) -[Ying11] M. Ying. 2011. Floyd-hoare logic for quantum programs. ACM Trans. Program. Lang. Syst. 33, 6 (2011), 19:1–19:49. -[ZHW19] A. Zulehner, S. Hillmich, and R. Wille, “How to efficiently handle complex values? Implementing decision diagrams for quantum computing,” in International Conference on Computer-Aided Design (ICCAD), 2019, pp. 1–7. -[ZHW19] Alwin Zulehner, Stefan Hillmich, and Robert Wille. 2019. How to Efficiently Handle Complex Values? Implementing Decision Diagrams for Quantum Computing. In Proc. ICCAD. 1–7. -[ZND+19] A. Zulehner, P. Niemann, R. Drechsler, and R. Wille, “Accuracy and compactness in decision diagrams for quantum computation,” in Design, Automation and Test in Europe Conference and Exhibition (DATE), 2019, pp. 280–283. -[ZW19] A. Zulehner and R. Wille, “Advanced simulation of quantum computations,” Trans. on CAD of Integrated Circuits and Systems, vol. 38, no. 5, pp. 848–859, 2019. -[ZWD11] Hongyan Zhang, Robert Wille, and Rolf Drechsler. Improved fault diagnosis for reversible circuits. 2011 Asian Test Symposium, 2011. -[ZZZD20] Yuan-Hang Zhang, et al. Topological quantum compiling with reinforcement learning. Physical Review Letters 125.17: 170501, 2020. -[ŠASA16] Ivan Šupić, et al., Self-testing protocols based on the chained Bell inequalities, New Journal of Physics 18.3, 2016. diff --git a/src/sat/sat.h b/src/sat/sat.h deleted file mode 100644 index effa531a..00000000 --- a/src/sat/sat.h +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** - FileName [ sat.h ] - PackageName [ sat ] - Synopsis [ Define miniSat solver interface functions ] - Author [ Chung-Yang (Ric) Huang, Cheng-Yin Wu ] - Copyright [ Copyleft(c) 2010-present LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#ifndef SAT_H -#define SAT_H - -#include -#include -// #include "Solver.h" -#include -#include "sat/bsat/satSolver.h" - -using namespace std; - -/********** MiniSAT_Solver **********/ -enum SatResult -{ - UNSAT = 0, - SAT, - UNDECIDED -}; - -typedef int Var; - -class SatSolver -{ - public : - SatSolver():_solver(0) { } - ~SatSolver() { if (_solver) delete _solver; } - - // Solver initialization and reset - void initialize() { - reset(); - if (_curVar == 0) { sat_solver_addvar(_solver); ++_curVar; } - } - void reset() { - if (_solver) delete _solver; - _solver = new sat_solver(); - _assump.clear(); //_curVar = 0; - } - - // // Constructing proof model - // Return the Var ID of the new Var - inline Var newVar() { sat_solver_addvar(_solver); return ++_curVar;; } - // fa/fb = true if it is inverted - void addAigCNF(Var vf, Var va, bool fa, Var vb, bool fb) { - sat_solver_add_and( _solver, vf, va, vb, va, vb, 0 ); - // vec lits; - // Lit lf = Lit(vf); - // Lit la = fa? ~Lit(va): Lit(va); - // Lit lb = fb? ~Lit(vb): Lit(vb); - // lits.push(la); lits.push(~lf); - // _solver->addClause(lits); lits.clear(); - // lits.push(lb); lits.push(~lf); - // _solver->addClause(lits); lits.clear(); - // lits.push(~la); lits.push(~lb); lits.push(lf); - // _solver->addClause(lits); lits.clear(); - } - // // fa/fb = true if it is inverted - void addXorCNF(Var vf, Var va, bool fa, Var vb, bool fb) { - sat_solver_add_xor( _solver, vf, va, vb, (fa ^ fb) ? 1 : 0 ); - // vec lits; - // Lit lf = Lit(vf); - // Lit la = fa? ~Lit(va): Lit(va); - // Lit lb = fb? ~Lit(vb): Lit(vb); - // lits.push(~la); lits.push( lb); lits.push( lf); - // _solver->addClause(lits); lits.clear(); - // lits.push( la); lits.push(~lb); lits.push( lf); - // _solver->addClause(lits); lits.clear(); - // lits.push( la); lits.push( lb); lits.push(~lf); - // _solver->addClause(lits); lits.clear(); - // lits.push(~la); lits.push(~lb); lits.push(~lf); - // _solver->addClause(lits); lits.clear(); - } - - // For incremental proof, use "assumeSolve()" - void assumeRelease() { _assump.clear(); } - void assumeProperty(Var prop, bool val) { - _assump.push_back(toLitCond(prop, val)); - } - SatResult assumpSolve() { - return lbool2SatResult(sat_solver_solve(_solver, &_assump.front(), &_assump.back(), 0, 0, 0, 0)); - } - - // For one time proof, use "solve" - void assertProperty(Var prop, bool val) { - lit Lits[1]; - Lits[0] = Abc_Var2Lit(prop, val); - sat_solver_addclause(_solver, Lits, Lits+1); - // _solver->addUnit(val? Lit(prop): ~Lit(prop)); - } - bool solve() { return lbool2bool(sat_solver_solve(_solver, 0, 0, 0, 0, 0, 0)); } - - // Functions about Reporting - // Return 1/0/-1; -1 means unknown value - int getValue(Var v) const { - return sat_solver_get_var_value(_solver, v); } - void printStats() const { Sat_SolverPrintStats( stdout, _solver ); } - - private : - sat_solver *_solver; // Pointer to a Minisat solver - Var _curVar; // Variable currently - vector _assump; // Assumption List for assumption solve - - static SatResult lbool2SatResult(lbool b) { - if (b == l_False) return UNSAT; - if (b == l_True) return SAT; - return UNDECIDED; - } - static bool lbool2bool(lbool b) { - if (b == l_False) return false; - if (b == l_True) return true; - } -}; - -#endif // SAT_H - diff --git a/src/sat/satMgr.cpp b/src/sat/satMgr.cpp new file mode 100644 index 00000000..854eae13 --- /dev/null +++ b/src/sat/satMgr.cpp @@ -0,0 +1,13 @@ +#include "satMgr.h" + +namespace gv { +namespace sat { + +/*SatSolverMgr::SatSolverMgr(CirMgr* c) : _cirMgr(c), _solver(Solver::MINISAT) {*/ +/*}*/ +SatSolverMgr::SatSolverMgr(gv::cir::CirMgr* c) : _cirMgr(c) {} + +SatSolverMgr::~SatSolverMgr() {} + +} // namespace sat +} // namespace gv diff --git a/src/sat/satMgr.h b/src/sat/satMgr.h new file mode 100644 index 00000000..b6cfed2c --- /dev/null +++ b/src/sat/satMgr.h @@ -0,0 +1,62 @@ +/**************************************************************************** + FileName [ satMgr.h ] + PackageName [ sat ] + Synopsis [ Define miniSat solver interface functions ] + Author [] + Copyright [ Copyright(c) 2023-present DVLab, GIEE, NTU, Taiwan ] +****************************************************************************/ +#pragma once + +#include + +#include "cirMgr.h" +#include "core/Solver.h" +#include "minisat/Proof.h" +#include "minisat/gvBitVec.h" + +namespace gv { +namespace sat { + +enum class SATSolverType { + MINISAT = 0, + GLUCOSE +}; + +// Top-level SAT solver manager +class SatSolverMgr { +public: + SatSolverMgr(gv::cir::CirMgr*); + virtual ~SatSolverMgr(); + + // clang-format off + virtual void reset() = 0; + virtual void assumeRelease() = 0; + virtual void assumeProperty(const size_t&, const bool&) = 0; + virtual void assertProperty(const size_t&, const bool&) = 0; + virtual void assumeProperty(const gv::cir::CirGate* gate, const bool& invert, const uint32_t& depth) = 0; + virtual void assertProperty(const gv::cir::CirGate* gate, const bool& invert, const uint32_t& depth) = 0; + virtual const bool simplify() = 0; + virtual const bool solve() = 0; + virtual const bool assump_solve() = 0; + virtual int getNumClauses() const = 0; + virtual void add_FALSE_Formula(const gv::cir::CirGate*, const uint32_t&) = 0; + virtual void add_PI_Formula(const gv::cir::CirGate*, const uint32_t&) = 0; + virtual void add_FF_Formula(const gv::cir::CirGate*, const uint32_t&) = 0; + virtual void add_AND_Formula(const gv::cir::CirGate*, const uint32_t&) = 0; + virtual void addBoundedVerifyData(const gv::cir::CirGate*, const uint32_t&) = 0; + virtual const bool existVerifyData(const gv::cir::CirGate*, const uint32_t&) = 0; + // clang-format on + + // minisat interface + virtual void resizeNtkData(const uint32_t& num) {}; + virtual Proof* getProof() { return nullptr; }; + virtual int nVars() { return 0; }; + virtual const GVBitVecX getDataValue(const gv::cir::CirGate* gate, const uint32_t& depth) const { return GVBitVecX(); }; + virtual const Var getVerifyData(const gv::cir::CirGate*, const uint32_t&) const {}; + +private: + gv::cir::CirMgr* _cirMgr; +}; + +} // namespace sat +} // namespace gv diff --git a/src/sat/test/File.cpp b/src/sat/test/File.cpp deleted file mode 100644 index eb113245..00000000 --- a/src/sat/test/File.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "File.h" - -void File::open(int file_descr, FileMode m, bool own) -{ - if (fd != -1) ::close(fd); - fd = file_descr; - mode = m; - own_fd = own; - pos = 0; - buf = xmalloc(File_BufSize); - if (mode == READ) size = read(fd, buf, File_BufSize); - else size = -1; -} - -void File::open(cchar* name, cchar* mode_) -{ - if (fd != -1) ::close(fd); - bool has_r = strchr(mode_, 'r') != NULL; - bool has_w = strchr(mode_, 'w') != NULL; - bool has_a = strchr(mode_, 'a') != NULL; - bool has_p = strchr(mode_, '+') != NULL; - bool has_x = strchr(mode_, 'x') != NULL; - assert(!(has_r && has_w)); - assert(has_r || has_w || has_a); - - int mask = 0; - if (has_p) mask |= O_RDWR; - else if (has_r) mask |= O_RDONLY; - else mask |= O_WRONLY; - - if (!has_r) mask |= O_CREAT; - if (has_w) mask |= O_TRUNC; - if (has_x) mask |= O_EXCL; - - fd = open64(name, mask, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); - - if (fd != -1){ - mode = has_r ? READ : WRITE; - own_fd = true; - pos = 0; - if (has_a) lseek64(fd, 0, SEEK_END); - buf = xmalloc(File_BufSize); - if (mode == READ) size = read(fd, buf, File_BufSize); - else size = -1; - } -} - - -void File::close(void) -{ - if (fd == -1) return; - if (mode == WRITE) - flush(); - xfree(buf); buf = NULL; - if (own_fd) - ::close(fd); - fd = -1; -} - -void File::seek(int64 file_pos, int whence) -{ - if (mode == WRITE){ - flush(); - pos = 0; - lseek64(fd, file_pos, whence); - }else{ - if (whence == SEEK_CUR) lseek64(fd, file_pos - (size - pos), SEEK_CUR); - else lseek64(fd, file_pos, whence); - size = read(fd, buf, File_BufSize); - pos = 0; - } -} - -int64 File::tell(void) -{ - if (mode == WRITE) - return lseek64(fd, 0, SEEK_CUR); - else - return lseek64(fd, 0, SEEK_CUR) - (size - pos); -} - - -//================================================================================================= -// Marshaling: - - -void putUInt(File& out, uint64 val) -{ - if (val < 0x20000000){ - uint v = (uint)val; - if (v < 0x80) - out.putChar(v); - else{ - if (v < 0x2000) - out.putChar(0x80 | (v >> 8)), - out.putChar((uchar)v); - else if (v < 0x200000) - out.putChar(0xA0 | (v >> 16)), - out.putChar((uchar)(v >> 8)), - out.putChar((uchar)v); - else - out.putChar((v >> 24) | 0xC0), - out.putChar((uchar)(v >> 16)), - out.putChar((uchar)(v >> 8)), - out.putChar((uchar)v); - } - }else - out.putChar(0xE0), - out.putChar((uchar)(val >> 56)), - out.putChar((uchar)(val >> 48)), - out.putChar((uchar)(val >> 40)), - out.putChar((uchar)(val >> 32)), - out.putChar((uchar)(val >> 24)), - out.putChar((uchar)(val >> 16)), - out.putChar((uchar)(val >> 8)), - out.putChar((uchar)val); -} - - -uint64 getUInt(File& in) -// throw(Exception_EOF) -//warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated] -{ - uint byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7; - byte0 = in.getChar(); - if (byte0 == (uint)EOF) - throw Exception_EOF(); - if (!(byte0 & 0x80)) - return byte0; - else{ - switch ((byte0 & 0x60) >> 5){ - case 0: - byte1 = in.getChar(); - return ((byte0 & 0x1F) << 8) | byte1; - case 1: - byte1 = in.getChar(); - byte2 = in.getChar(); - return ((byte0 & 0x1F) << 16) | (byte1 << 8) | byte2; - case 2: - byte1 = in.getChar(); - byte2 = in.getChar(); - byte3 = in.getChar(); - return ((byte0 & 0x1F) << 24) | (byte1 << 16) | (byte2 << 8) | byte3; - default: - byte0 = in.getChar(); - byte1 = in.getChar(); - byte2 = in.getChar(); - byte3 = in.getChar(); - byte4 = in.getChar(); - byte5 = in.getChar(); - byte6 = in.getChar(); - byte7 = in.getChar(); - return ((uint64)((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3) << 32) - | (uint64)((byte4 << 24) | (byte5 << 16) | (byte6 << 8) | byte7); - } - } -} diff --git a/src/sat/test/File.h b/src/sat/test/File.h deleted file mode 100644 index 931a9542..00000000 --- a/src/sat/test/File.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef File_h -#define File_h - -#ifndef Global_h -#include "Global.h" -#endif - -#include -#include -#include - -#ifndef _LARGEFILE64_SOURCE -#define lseek64 ::lseek -#define open64 ::open -#endif - - -//================================================================================================= -// A buffered file abstraction with only 'putChar()' and 'getChar()'. - - -#define File_BufSize 1024 // A small buffer seem to work just as fine as a big one (at least under Linux) - -enum FileMode { READ, WRITE }; - -class Exception_EOF {}; - - -// WARNING! This code is not thoroughly tested. May contain bugs! - -class File { - int fd; // Underlying file descriptor. - FileMode mode; // Reading or writing. - uchar* buf; // Read or write buffer. - int size; // Size of buffer (at end of file, less than 'File_BufSize'). - int pos; // Current position in buffer - bool own_fd; // Do we own the file descriptor? If so, will close file in destructor. - -public: - #define DEFAULTS fd(-1), mode(READ), buf(NULL), size(-1), pos(0), own_fd(true) - File(void) : DEFAULTS {} - - File(int fd, FileMode mode, bool own_fd = true) : DEFAULTS { - open(fd, mode, own_fd); } - - File(cchar* name, cchar* mode) : DEFAULTS { - open(name, mode); } - #undef DEFAULTS - - ~File(void) { - close(); } - - void open(int fd, FileMode mode, bool own_fd = true); // Low-level open. If 'own_fd' is FALSE, descriptor will not be closed by destructor. - void open(cchar* name, cchar* mode); // FILE* compatible interface. - void close(void); - - bool null(void) { // TRUE if no file is opened. - return fd == -1; } - - int releaseDescriptor(void) { // Don't run UNIX function 'close()' on descriptor in 'File's 'close()'. - if (mode == READ) - lseek64(fd, pos - size, SEEK_CUR); - own_fd = false; - return fd; } - - FileMode getMode(void) { - return mode; } - - void setMode(FileMode m) { - if (m == mode) return; - if (m == READ){ - flush(); - size = read(fd, buf, File_BufSize); - }else{ - lseek64(fd, pos - size, SEEK_CUR); - size = -1; } - mode = m; - pos = 0; } - - int getCharQ(void) { // Quick version with minimal overhead -- don't call this in the wrong mode! - #ifdef PARANOID - assert(mode == READ); - #endif - if (pos < size) return (uchar)buf[pos++]; - if (size < File_BufSize) return EOF; - size = read(fd, buf, File_BufSize); - pos = 0; - if (size == 0) return EOF; - return (uchar)buf[pos++]; } - - int putCharQ(int chr) { // Quick version with minimal overhead -- don't call this in the wrong mode! - #ifdef PARANOID - assert(mode == WRITE); - #endif - if (pos == File_BufSize) - write(fd, buf, File_BufSize), - pos = 0; - return buf[pos++] = (uchar)chr; } - - int getChar(void) { - if (mode == WRITE) setMode(READ); - return getCharQ(); } - - int putChar(int chr) { - if (mode == READ) setMode(WRITE); - return putCharQ(chr); } - - bool eof(void) { - assert(mode == READ); - if (pos < size) return false; - if (size < File_BufSize) return true; - size = read(fd, buf, File_BufSize); - pos = 0; - if (size == 0) return true; - return false; } - - void flush(void) { - assert(mode == WRITE); - write(fd, buf, pos); - pos = 0; } - - void seek(int64 pos, int whence = SEEK_SET); - int64 tell(void); -}; - - -//================================================================================================= -// Some nice helper functions: - - -void putUInt (File& out, uint64 val); -//uint64 getUInt (File& in) throw(Exception_EOF); -//warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated] -uint64 getUInt (File& in); -static inline uint64 encode64(int64 val) { return (val >= 0) ? (uint64)val << 1 : (((uint64)(~val) << 1) | 1); } -static inline int64 decode64(uint64 val) { return ((val & 1) == 0) ? (int64)(val >> 1) : ~(int64)(val >> 1); } -static inline void putInt (File& out, int64 val) { putUInt(out, encode64(val)); } -static inline uint64 getInt (File& in) { return decode64(getUInt(in)); } - - -//================================================================================================= -#endif diff --git a/src/sat/test/Global.h b/src/sat/test/Global.h deleted file mode 100644 index 14dbfe85..00000000 --- a/src/sat/test/Global.h +++ /dev/null @@ -1,278 +0,0 @@ -/****************************************************************************************[Global.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Global_h -#define Global_h - -#include -#include -#include -#include -#include -#include -#include - - -//================================================================================================= -// Basic Types & Minor Things: - - -#ifdef _MSC_VER -typedef INT64 int64; -typedef UINT64 uint64; -typedef INT_PTR intp; -typedef UINT_PTR uintp; -#define I64_fmt "I64d" -#else -typedef long long int64; -typedef unsigned long long uint64; -typedef __PTRDIFF_TYPE__ intp; -typedef unsigned __PTRDIFF_TYPE__ uintp; -#define I64_fmt "lld" -#endif -typedef unsigned char uchar; -typedef const char cchar; - -// FIXED BY RIC -#ifndef uint -typedef unsigned int uint; -#endif - -template static inline T min(T x, T y) { return (x < y) ? x : y; } -template static inline T max(T x, T y) { return (x > y) ? x : y; } - -template struct STATIC_ASSERTION_FAILURE {}; -//template <> struct STATIC_ASSERTION_FAILURE{}; -#define TEMPLATE_FAIL STATIC_ASSERTION_FAILURE() - - -//================================================================================================= -// 'malloc()'-style memory allocation -- never returns NULL; aborts instead: - - -template static inline T* xmalloc(size_t size) { - T* tmp = (T*)malloc(size * sizeof(T)); - assert(size == 0 || tmp != NULL); - return tmp; } - -template static inline T* xrealloc(T* ptr, size_t size) { - T* tmp = (T*)realloc((void*)ptr, size * sizeof(T)); - assert(size == 0 || tmp != NULL); - return tmp; } - -template static inline void xfree(T *ptr) { - if (ptr != NULL) free((void*)ptr); } - - -//================================================================================================= -// Random numbers: - - -// Returns a random float 0 <= x < 1. Seed must never be 0. -static inline double drand(double& seed) { - seed *= 1389796; - int q = (int)(seed / 2147483647); - seed -= (double)q * 2147483647; - return seed / 2147483647; } - -// Returns a random integer 0 <= x < size. Seed must never be 0. -static inline int irand(double& seed, int size) { - return (int)(drand(seed) * size); } - - -//================================================================================================= -// Time and Memory: - - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#ifdef _MSC_VER - -#include - -static inline double cpuTime(void) { - return (double)clock() / CLOCKS_PER_SEC; } - -static inline int64 memUsed() { - return 0; } - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#else - -#include -#include -#include - -static inline double cpuTime(void) { - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; } - -static inline int memReadStat(int field) -{ - char name[256]; - pid_t pid = getpid(); - sprintf(name, "/proc/%d/statm", pid); - FILE* in = fopen(name, "rb"); - if (in == NULL) return 0; - int value; - for (; field >= 0; field--) - fscanf(in, "%d", &value); - fclose(in); - return value; -} - -static inline int64 memUsed() { return (int64)memReadStat(0) * (int64)getpagesize(); } - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#endif - - - -//================================================================================================= -// 'vec' -- automatically resizable arrays (via 'push()' method): - - -// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc) - -template -class vec { - T* data; - int sz; - int cap; - - void init(int size, const T& pad); - void grow(int min_cap); - -public: - // Types: - typedef int Key; - typedef T Datum; - - // Constructors: - vec(void) : data(NULL) , sz(0) , cap(0) { } - vec(int size) : data(NULL) , sz(0) , cap(0) { growTo(size); } - vec(int size, const T& pad) : data(NULL) , sz(0) , cap(0) { growTo(size, pad); } - vec(T* array, int size) : data(array), sz(size), cap(size) { } // (takes ownership of array -- will be deallocated with 'xfree()') - ~vec(void) { clear(true); } - - // Ownership of underlying array: - T* release (void) { T* ret = data; data = NULL; sz = 0; cap = 0; return ret; } - operator T* (void) { return data; } // (unsafe but convenient) - operator const T* (void) const { return data; } - - // Size operations: - int size (void) const { return sz; } - void shrink (int nelems) { assert(nelems <= sz); for (int i = 0; i < nelems; i++) sz--, data[sz].~T(); } - void pop (void) { sz--, data[sz].~T(); } - void growTo (int size); - void growTo (int size, const T& pad); - void clear (bool dealloc = false); - void capacity (int size) { grow(size); } - - // Stack interface: - void push (void) { if (sz == cap) grow(sz+1); new (&data[sz]) T() ; sz++; } - void push (const T& elem) { if (sz == cap) grow(sz+1); new (&data[sz]) T(elem); sz++; } - const T& last (void) const { return data[sz-1]; } - T& last (void) { return data[sz-1]; } - - // Vector interface: - const T& operator [] (int index) const { return data[index]; } - T& operator [] (int index) { return data[index]; } - - // Don't allow copying (error prone): - vec& operator = (vec& other) { TEMPLATE_FAIL; } - vec (vec& other) { TEMPLATE_FAIL; } - - // Duplicatation (preferred instead): - void copyTo(vec& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) new (©[i]) T(data[i]); } - void moveTo(vec& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; } -}; - -template -void vec::grow(int min_cap) { - if (min_cap <= cap) return; - if (cap == 0) cap = (min_cap >= 2) ? min_cap : 2; - else do cap = (cap*3+1) >> 1; while (cap < min_cap); - data = xrealloc(data, cap); } - -template -void vec::growTo(int size, const T& pad) { - if (sz >= size) return; - grow(size); - for (int i = sz; i < size; i++) new (&data[i]) T(pad); - sz = size; } - -template -void vec::growTo(int size) { - if (sz >= size) return; - grow(size); - for (int i = sz; i < size; i++) new (&data[i]) T(); - sz = size; } - -template -void vec::clear(bool dealloc) { - if (data != NULL){ - for (int i = 0; i < sz; i++) data[i].~T(); - sz = 0; - if (dealloc) xfree(data), data = NULL, cap = 0; } } - - -//================================================================================================= -// Lifted booleans: - - -class lbool { - int value; - explicit lbool(int v) : value(v) { } - -public: - lbool() : value(0) { } - lbool(bool x) : value((int)x*2-1) { } - int toInt(void) const { return value; } - - bool operator == (const lbool& other) const { return value == other.value; } - bool operator != (const lbool& other) const { return value != other.value; } - lbool operator ~ (void) const { return lbool(-value); } - - friend int toInt (lbool l); - friend lbool toLbool(int v); -}; -inline int toInt (lbool l) { return l.toInt(); } -inline lbool toLbool(int v) { return lbool(v); } - -const lbool l_True = toLbool( 1); -const lbool l_False = toLbool(-1); -const lbool l_Undef = toLbool( 0); - - -//================================================================================================= -// Relation operators -- extend definitions from '==' and '<' - - -#ifndef __SGI_STL_INTERNAL_RELOPS // (be aware of SGI's STL implementation...) -#define __SGI_STL_INTERNAL_RELOPS -template static inline bool operator != (const T& x, const T& y) { return !(x == y); } -template static inline bool operator > (const T& x, const T& y) { return y < x; } -template static inline bool operator <= (const T& x, const T& y) { return !(y < x); } -template static inline bool operator >= (const T& x, const T& y) { return !(x < y); } -#endif - - -//================================================================================================= -#endif diff --git a/src/sat/test/Heap.h b/src/sat/test/Heap.h deleted file mode 100644 index cddf6693..00000000 --- a/src/sat/test/Heap.h +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************************[Heap.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Heap_h -#define Heap_h - - -//================================================================================================= - - -static inline int left (int i) { return i+i; } -static inline int right (int i) { return i+i + 1; } -static inline int parent(int i) { return i >> 1; } - -template -class Heap { - public: - C comp; - vec heap; // heap of ints - vec indices; // int -> index in heap - - inline void percolateUp(int i) - { - int x = heap[i]; - while (parent(i) != 0 && comp(x,heap[parent(i)])){ - heap[i] = heap[parent(i)]; - indices[heap[i]] = i; - i = parent(i); - } - heap [i] = x; - indices[x] = i; - } - - inline void percolateDown(int i) - { - int x = heap[i]; - while (left(i) < heap.size()){ - int child = right(i) < heap.size() && comp(heap[right(i)],heap[left(i)]) ? right(i) : left(i); - if (!comp(heap[child],x)) break; - heap[i] = heap[child]; - indices[heap[i]] = i; - i = child; - } - heap [i] = x; - indices[x] = i; - } - - bool ok(int n) { return n >= 0 && n < (int)indices.size(); } - - public: - Heap(C c) : comp(c) { heap.push(-1); } - - void setBounds (int size) { assert(size >= 0); indices.growTo(size,0); } - bool inHeap (int n) { assert(ok(n)); return indices[n] != 0; } - void increase (int n) { assert(ok(n)); assert(inHeap(n)); percolateUp(indices[n]); } - bool empty () { return heap.size() == 1; } - - void insert(int n) { - assert(ok(n)); - indices[n] = heap.size(); - heap.push(n); - percolateUp(indices[n]); } - - int getmin() { - int r = heap[1]; - heap[1] = heap.last(); - indices[heap[1]] = 1; - indices[r] = 0; - heap.pop(); - if (heap.size() > 1) - percolateDown(1); - return r; } - - bool heapProperty() { - return heapProperty(1); } - - bool heapProperty(int i) { - return (size_t)i >= heap.size() - || ((parent(i) == 0 || !comp(heap[i],heap[parent(i)])) && heapProperty(left(i)) && heapProperty(right(i))); } -}; - - -//================================================================================================= -#endif diff --git a/src/sat/test/Makefile b/src/sat/test/Makefile deleted file mode 100644 index 190aee12..00000000 --- a/src/sat/test/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -andTest: clean File.o Proof.o Solver.o andTest.o - g++ -o $@ -std=c++11 -g File.o Proof.o Solver.o andTest.o - -File.o: File.cpp - g++ -c -std=c++11 -g File.cpp - -Proof.o: Proof.cpp - g++ -c -std=c++11 -g Proof.cpp - -Solve.o: Solver.cpp - g++ -c -std=c++11 -g Solver.cpp - -andTest.o: andTest.cpp - g++ -c -std=c++11 -g andTest.cpp - -clean: - rm -f *.o diff --git a/src/sat/test/Makefile2 b/src/sat/test/Makefile2 deleted file mode 100644 index cc6b13ec..00000000 --- a/src/sat/test/Makefile2 +++ /dev/null @@ -1,17 +0,0 @@ -satTest2: clean File.o Proof.o Solver.o satTest2.o - g++ -o $@ -g File.o Proof.o Solver.o satTest2.o - -File.o: File.cpp - g++ -c -g File.cpp - -Proof.o: Proof.cpp - g++ -c -g Proof.cpp - -Solve.o: Solver.cpp - g++ -c -g Solver.cpp - -satTest2.o: satTest2.cpp - g++ -c -g satTest2.cpp - -clean: - rm -f *.o diff --git a/src/sat/test/Makefile3 b/src/sat/test/Makefile3 deleted file mode 100644 index ad33223f..00000000 --- a/src/sat/test/Makefile3 +++ /dev/null @@ -1,17 +0,0 @@ -satTest3: clean File.o Proof.o Solver.o satTest.o - g++ -o $@ -g File.o Proof.o Solver.o satTest.o - -File.o: File.cpp - g++ -c -g File.cpp - -Proof.o: Proof.cpp - g++ -c -g Proof.cpp - -Solve.o: Solver.cpp - g++ -c -g Solver.cpp - -satTest.o: satTest.cpp - g++ -c -g satTest.cpp - -clean: - rm -f *.o diff --git a/src/sat/test/NO_USE/itp.h b/src/sat/test/NO_USE/itp.h deleted file mode 100644 index d38b492e..00000000 --- a/src/sat/test/NO_USE/itp.h +++ /dev/null @@ -1,228 +0,0 @@ -#ifndef ITP_H -#define ITP_H - -#include "Proof.h" -#include "Solver.h" -#include "strash.h" -//#include - -//==== ITP ====== [ Abstract class ] ========================================== -// is a ProofTraverser -// has setType to set the vartype label -//============================================================================= - -class ITP : virtual public ProofTraverser -{ - -public: - static const int VarA = -1 ; - static const int VarB = -2 ; - static const int VarUnknow = -3 ; - -protected: - - vector _subITP; - bool _inv; - -public: - vector base; - - void set( bool i ){_inv = i; } - ITP(){} -}; - -//==== Boolean AigPtr Calculator ============================================== -// Boolean interface -//============================================================================= - -class AigCal -{ -public: - virtual ~AigCal(){}; - virtual AigPtr AND( const AigPtr & a , const AigPtr & b)= 0 ; - virtual AigPtr OR( const AigPtr & a , const AigPtr & b){ return ~( AND ( (~a) , (~b)) );} - virtual AigPtr ITE(const AigPtr & c , const AigPtr & t , const AigPtr & f){ return OR( AND(c,t),AND(~c,f)) ; } -}; - - -//==== PITP ======== [ Abstract class ] ======================================= - -class PITP : virtual public ITP , virtual public AigCal , virtual public ProofTraverser -{ -public: - /// constructor - PITP():ITP(){} - virtual ~PITP(){} - - /// interpolation usage - virtual void root(const vec & c , bool A); - virtual void chain(const vec & cs , const vec & xs ); -private: - AigPtr resolve(AigPtr a ,Lit v, AigPtr b); - -}; - -//==== MITP ===== [ Abstract class ] ========================================== - -class MITP : virtual public ITP , virtual public AigCal , virtual public ProofTraverser -{ -public: - MITP( ) :ITP(){} - virtual ~MITP(){} - - virtual void root( const vec & c , bool A); - virtual void chain( const vec & cs , const vec & xs); -private: - AigPtr resolve( AigPtr a, Lit v , AigPtr b ); -}; - -//==== InterpolantITP ========================================================= -// a interface to wrapping SITP and MutiSITP -//============================================================================= -class InterpolantITP : virtual public ProofTraverser -{ -public : - virtual AigPtr interpolant() =0 ; -}; - - - -//==== SITP ====== [] ========================================================= -// is a ITP , AigCal , InterpolantITP -// have StrashMgr reference , and a final construct interpolant -//============================================================================= -class SITP : virtual public ITP , virtual public AigCal , virtual public InterpolantITP -{ - StrashCkt & _ref; - AigPtr _interpolant; - -public: - - //--- construct & destruct --- - SITP( StrashCkt & k ,bool p); - virtual ~SITP(){} - - //--- concrete func of AigCal --- - virtual AigPtr AND( const AigPtr & a , const AigPtr & b){return _ref.createAND( a, b);} - - //--- concreate func of ITP --- - virtual void done(); - - //--- concrete func of InterpolantITP --- - virtual AigPtr interpolant(){return _interpolant;} - - //--- utilization func --- - virtual unsigned size(); -}; - -//==== MultiITP ====== [] ====================================================== -// Wrap multi ITP container as to perform online interpolant construction -//============================================================================= -class MultiSITP : virtual public ProofTraverser -{ - - vector _sitp; - -public : - //--- construct & destruct - MultiSITP( unsigned a ); - virtual ~MultiSITP(); - void set( unsigned i , SITP * s ){ _sitp[i] = s ;} - -// SITP * itp(unsigned i){ return _sitp[i] ;} - SITP & operator[]( unsigned i ){ return * (_sitp[i] ); } - - //--- concrete func of ProofTraverser --- - virtual void root (const vec& c , bool A); - virtual void chain (const vec& cs, const vec& xs); - virtual void deleted(ClauseId c); - virtual void done (); -}; - - -//==== SMITP ====== [ Concrete class ] ======================================== -// is a McMillan construction structure hash circuit -// -// applying the [McMillan] method to construct the [interpolation] to -// the complete structure hash circuit -// -//============================================================================= - - -class SMITP : virtual public SITP , virtual public MITP -{ -public: - virtual ~SMITP(){} - SMITP( StrashCkt & k , bool p ):SITP(k,p){} -}; - -//==== SPITP ====== [ Concrete class ] ======================================== -// is a Pudlark construction structure hash circuit -// -// applying the [Pudlark] method to construct the [interpolation] to -// the complete structure hash circuit -// -//============================================================================= - -class SPITP: virtual public SITP , virtual public PITP -{ -public: - virtual ~SPITP(){} - SPITP( StrashCkt & k , bool p):SITP(k,p){} -}; - -//==== Checker ================================================================ -// -//============================================================================= -struct Checker : virtual public ProofTraverser -{ - vec< vec > clauses; - vec< vec< ClauseId > > vcs; - vec< vec > vxs; - vector< bool > phase; - - int TRA_INT; - Checker():TRA_INT(0){} - void root (const vec& c ,bool A); - void chain (const vec& cs, const vec& xs) ; - void deleted(ClauseId c) ; - void resolve(vec& main, vec& other, Lit x); - void traverse( ProofTraverser & ); - void done(); -}; - -/****************************************************************************** - * [Synopsis] help for saving the proof traverser information -******************************************************************************/ -class ITPMgr -{ - protected: - ProofTraverser * _pft; // internal - SITP * _itp; // construction - Proof * _pf; // proof - AigPtr _interpolant; // constructed - - public: - - enum CONST_MODE{ ON_THE_FLY , NONE , POST }; - - int CC_MIN;// - int ITP_CONTAINER; - int PFT_CONTAINER; - int ITP_PHASE; - int MODE; - - - ITPMgr( ): - _pft( NULL ), _itp( NULL ),_pf( NULL ), - - CC_MIN(1), ITP_CONTAINER(3), PFT_CONTAINER(4), - ITP_PHASE(0), MODE( ON_THE_FLY ) - {} - ~ITPMgr(); - - ProofTraverser * pfGen( Solver & S, StrashCkt & ckt ); // parameter for _itp - AigPtr itpGen(); -}; - -#endif diff --git a/src/sat/test/NO_USE/mitp.h b/src/sat/test/NO_USE/mitp.h deleted file mode 100644 index c88a6803..00000000 --- a/src/sat/test/NO_USE/mitp.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef MITP_H -#define MITP_H - -#include "Proof.h" -#include "Solver.h" - -class MVITP : virtual public ProofTraverser -{ - public: - protected: -}; - -#endif diff --git a/src/sat/test/Proof.cpp b/src/sat/test/Proof.cpp deleted file mode 100644 index 9f5fedfe..00000000 --- a/src/sat/test/Proof.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/*****************************************************************************************[Proof.C] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#include "Proof.h" -#include "Sort.h" -#include - -//================================================================================================= -// Temporary files handling: - - -class TempFiles { - vec files; // For clean-up purposed on abnormal exit. - -public: - ~TempFiles() - { - for (int i = 0; i < files.size(); i++) - remove(files[i]); - //printf("Didn't delete:\n %s\n", files[i]); - } - - // Returns a read-only string with the filename of the temporary file. The pointer can be used to - // remove the file (which is otherwise done automatically upon program exit). - // - char* open(File& fp) - { -// char * name; -// char* name = "/tmp/fileXXXXXX"; - char* name = new char[64]; - strcpy(name, "/tmp/fileXXXXXX"); - for(;;){ -// name = tempnam(NULL, NULL); // (gcc complains about this... stupid gcc...) -// fp.open(name, "wx+"); - fp.open( mkstemp(name) , WRITE , true ); - assert(name != NULL); - if (fp.null()) - xfree(name); - else{ - files.push(name); - return name; - } - } - } -}; -static TempFiles temp_files; // (should be singleton) - - -//================================================================================================= -// Proof logging: - - -Proof::Proof() -{ - fp_name = temp_files.open(fp); - id_counter = 0; - trav = NULL; - TRA_INT = 0; - fpos =0 ; -} - - -Proof::Proof(ProofTraverser& t) -{ - id_counter = 0; - trav = &t; - TRA_INT = 0; - fpos = 0; -} - - -ClauseId Proof::addRoot(vec& cl, bool A) -{ - cl.copyTo(clause); - sortUnique(clause); - - if (trav != NULL) - trav->root(clause, A); - if (!fp.null()){ - putUInt(fp, index(clause[0]) << 1); - for (int i = 1; i < clause.size(); i++) - putUInt(fp, index(clause[i]) - index(clause[i-1])); - putUInt(fp, 0); // (0 is safe terminator since we removed duplicates) - if(A) putUInt(fp , 1); - else putUInt(fp , 2 ); - } - - return id_counter++; -} - - -void Proof::beginChain(ClauseId start) -{ - assert(start != ClauseId_NULL); - chain_id .clear(); - chain_lit.clear(); - chain_id.push(start); -} - - -void Proof::resolve(ClauseId next, Lit x) -{ - assert(next != ClauseId_NULL); - chain_id .push(next); - chain_lit.push(x); -} - - -ClauseId Proof::endChain() -{ - assert(chain_id.size() == chain_lit.size() + 1); - if (chain_id.size() == 1) - return chain_id[0]; - else{ - if (trav != NULL) - trav->chain(chain_id, chain_lit); - if (!fp.null()){ - putUInt(fp, ((id_counter - chain_id[0]) << 1) | 1); - for (int i = 0; i < chain_lit.size(); i++) - putUInt(fp, index(chain_lit[i])+1 ), - putUInt(fp, id_counter - chain_id[i+1]); - putUInt(fp, 0); - } - - return id_counter++; - } -} - - -void Proof::deleted(ClauseId gone) -{ - if (trav != NULL) - trav->deleted(gone); - if (!fp.null()){ - putUInt(fp, ((id_counter - gone) << 1) | 1); - putUInt(fp, 0); - } -} - - -//================================================================================================= -// Read-back methods: - - -void Proof::compress(Proof& dst, ClauseId goal) -{ - assert(!fp.null()); - assert(false); // Not yet! -} - - -bool Proof::save(cchar* filename) -{ - assert(!fp.null()); - - // Switch to read mode: - fp.setMode(READ); - fp.seek(0); - - // Copy file: - File out(filename, "wox"); - if (out.null()) - return false; - - while (!fp.eof()) - out.putChar(fp.getChar()); - - // Restore write (proof-logging) mode: - fp.seek(0, SEEK_END); - fp.setMode(WRITE); - return true; -} - - -void Proof::traverse(ProofTraverser& trav, ClauseId goal) -{ - assert(!fp.null()); - - // Switch to read mode: - fp.setMode(READ); - fp.seek( fpos ); - - // Traverse proof: - if (goal == ClauseId_NULL) - goal = last(); - - uint64 tmp; - int idx; - bool A; - - for(ClauseId id = TRA_INT ; id <= goal; id++){ - tmp = getUInt(fp); - if ((tmp & 1) == 0){ - // Root clause: - clause.clear(); - idx = tmp >> 1; - clause.push(toLit(idx)); - for(;;){ - tmp = getUInt(fp); - if (tmp == 0) break; - idx += tmp; - clause.push(toLit(idx)); - } - if( getUInt(fp) == 1 ) A = true; - else A = false; - //assert( false); - trav.root(clause ,A); - - - }else{ - // Derivation or Deletion: - - chain_id .clear(); - chain_lit.clear(); - chain_id.push(id - (tmp >> 1)); - for(;;){ - tmp = getUInt(fp); - if (tmp == 0) break; - chain_lit.push(toLit( tmp - 1)); - tmp = getUInt(fp); - chain_id.push(id - tmp); - } - - if (chain_lit.size() == 0) - id--, // (no new clause introduced) - trav.deleted(chain_id[0]); - else - trav.chain(chain_id, chain_lit); - } - } - TRA_INT = goal+1; - fpos = fp.tell(); - fp.seek(0, SEEK_END); - fp.setMode(WRITE); -} diff --git a/src/sat/test/Proof.h b/src/sat/test/Proof.h deleted file mode 100644 index b1dbe039..00000000 --- a/src/sat/test/Proof.h +++ /dev/null @@ -1,74 +0,0 @@ -/*****************************************************************************************[Proof.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Proof_h -#define Proof_h - -#include "SolverTypes.h" -#include "File.h" - - -//================================================================================================= - - -// A "listner" for the proof. Proof events will be passed onto (online mode) or replayed to -// (offline mode) this class. Each call to 'root()' or 'chain()' produces a new clause. The first -// clause has ID 0, the next 1 and so on. These are the IDs passed to 'chain()'s 'cs' parameter. -// -struct ProofTraverser { - virtual void root (const vec& c , bool A)=0;// {assert(false);}; - virtual void chain (const vec& cs, const vec& xs)=0;// {assert(false);}; - virtual void deleted(ClauseId c){} - virtual void done ()=0;//{assert(false);} - virtual ~ProofTraverser(){} -}; - - -class Proof { - File fp; - cchar* fp_name; - ClauseId id_counter; - ProofTraverser* trav; - - int TRA_INT; - int64 fpos; - - vec clause; - vec chain_id; - vec chain_lit; - -public: - Proof(); // Offline mode -- proof stored to a file, which can be saved, compressed, and/or traversed. - Proof(ProofTraverser& t); // Online mode -- proof will not be stored. - - ClauseId addRoot (vec& clause , bool A ); - void beginChain(ClauseId start); - void resolve (ClauseId next, Lit x); - ClauseId endChain (); - void deleted (ClauseId gone); - ClauseId last () { assert(id_counter != ClauseId_NULL); return id_counter - 1; } - - void compress (Proof& dst, ClauseId goal = ClauseId_NULL); // 'dst' should be a newly constructed, empty proof. - bool save (cchar* filename); - void traverse (ProofTraverser& trav, ClauseId goal = ClauseId_NULL) ; -}; - - -//================================================================================================= -#endif diff --git a/src/sat/test/Solver.cpp b/src/sat/test/Solver.cpp deleted file mode 100644 index 7e6b34ba..00000000 --- a/src/sat/test/Solver.cpp +++ /dev/null @@ -1,854 +0,0 @@ -/****************************************************************************************[Solver.C] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#include "Solver.h" -#include "Sort.h" -#include - -int effLimit = INT_MAX; // 100000; // INT_MAX; - -//================================================================================================= -// Helper functions: - - -void removeWatch(vec& ws, Clause* elem) -{ - if (ws.size() == 0) return; // (skip lists that are already cleared) - int j = 0; - for (; ws[j] != elem ; j++) assert(j < ws.size()); - for (; j < ws.size()-1; j++) ws[j] = ws[j+1]; - ws.pop(); -} - - -//================================================================================================= -// Operations on clauses: - - -/*_________________________________________________________________________________________________ -| -| newClause : (ps : const vec&) (learnt : bool) (id : ClauseId) -> [void] -| -| Description: -| Allocate and add a new clause to the SAT solvers clause database. If a conflict is detected, -| the 'ok' flag is cleared and the solver is in an unusable state (must be disposed). -| -| Input: -| ps - The new clause as a vector of literals. -| learnt - Is the clause a learnt clause? For learnt clauses, 'ps[0]' is assumed to be the -| asserting literal. An appropriate 'enqueue()' operation will be performed on this -| literal. One of the watches will always be on this literal, the other will be set to -| the literal with the highest decision level. -| id - If logging proof, learnt clauses should be given an ID by caller. -| -| Effect: -| Activity heuristics are updated. -|________________________________________________________________________________________________@*/ -void Solver::newClause(const vec& ps_, bool learnt, ClauseId id , bool A) -{ - assert(learnt || id == ClauseId_NULL); - if (!ok) return; - - vec qs; - if (!learnt){ - assert(decisionLevel() == 0); - ps_.copyTo(qs); // Make a copy of the input vector. - - // Remove duplicates: - sortUnique(qs); - - // Check if clause is satisfied: - for (int i = 0; i < qs.size()-1; i++){ - if (qs[i] == ~qs[i+1]) - return; } - for (int i = 0; i < qs.size(); i++){ - if (value(qs[i]) == l_True) - return; } - - // Remove false literals: - int i, j; - if (proof != NULL) proof->beginChain(proof->addRoot(qs,A)); - for (i = j = 0; i < qs.size(); i++) - if (value(qs[i]) != l_False) - qs[j++] = qs[i]; - else - if (proof != NULL) proof->resolve(unit_id[var(qs[i])], qs[i]); - qs.shrink(i - j); - if (proof != NULL) id = proof->endChain(); - } - const vec& ps = learnt ? ps_ : qs; // 'ps' is now the (possibly) reduced vector of literals. - - if (ps.size() == 0){ - ok = false; - - }else if (ps.size() == 1){ - // NOTE: If enqueue takes place at root level, the assignment will be lost in incremental use (it doesn't seem to hurt much though). - if (id != ClauseId_NULL) - unit_id[var(ps[0])] = id; - if (!enqueue(ps[0])) - ok = false; - - }else{ - // Allocate clause: - Clause* c = Clause_new(learnt, ps, id); - - if (learnt){ - // Put the second watch on the literal with highest decision level: - int max_i = 1; - int max = level[var(ps[1])]; - for (int i = 2; i < ps.size(); i++) - if (level[var(ps[i])] > max) - max = level[var(ps[i])], - max_i = i; - (*c)[1] = ps[max_i]; - (*c)[max_i] = ps[1]; - - // Bumping: - claBumpActivity(c); // (newly learnt clauses should be considered active) - - // Enqueue asserting literal: - check(enqueue((*c)[0], c)); - - // Store clause: - watches[index(~(*c)[0])].push(c); - watches[index(~(*c)[1])].push(c); - learnts.push(c); - stats.learnts_literals += c->size(); - - }else{ - // Store clause: - watches[index(~(*c)[0])].push(c); - watches[index(~(*c)[1])].push(c); - clauses.push(c); - stats.clauses_literals += c->size(); - } - } -} - - -// Disposes a clauses and removes it from watcher lists. NOTE! Low-level; does NOT change the 'clauses' and 'learnts' vector. -// -void Solver::remove(Clause* c, bool just_dealloc) -{ - if (!just_dealloc){ - removeWatch(watches[index(~(*c)[0])], c), - removeWatch(watches[index(~(*c)[1])], c); - - if (c->learnt()) stats.learnts_literals -= c->size(); - else stats.clauses_literals -= c->size(); - - if (proof != NULL) proof->deleted(c->id()); - } - - xfree(c); -} - - -// Can assume everything has been propagated! (esp. the first two literals are != l_False, unless -// the clause is binary and satisfied, in which case the first literal is true) -// Returns True if clause is satisfied (will be removed), False otherwise. -// -bool Solver::simplify(Clause* c) const -{ - assert(decisionLevel() == 0); - for (int i = 0; i < c->size(); i++){ - if (value((*c)[i]) == l_True) - return true; - } - return false; -} - - -//================================================================================================= -// Minor methods: - - -// Creates a new SAT variable in the solver. If 'decision_var' is cleared, variable will not be -// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result). -// -Var Solver::newVar() { - int index; - index = nVars(); - watches .push(); // (list for positive literal) - watches .push(); // (list for negative literal) - reason .push(NULL); - assigns .push(toInt(l_Undef)); - level .push(-1); - trail_pos .push(-1); - activity .push(0); - order .newVar(); - analyze_seen.push(0); - if (proof != NULL) unit_id.push(ClauseId_NULL); - return index; } - - -// Returns FALSE if immediate conflict. -bool Solver::assume(Lit p) { - trail_lim.push(trail.size()); - return enqueue(p); } - - -// Revert to the state at given level. -void Solver::cancelUntil(int level) { - if (decisionLevel() > level){ - for (int c = trail.size()-1; c >= trail_lim[level]; c--){ - Var x = var(trail[c]); - assigns[x] = toInt(l_Undef); - reason [x] = NULL; - order.undo(x); } - trail.shrink(trail.size() - trail_lim[level]); - trail_lim.shrink(trail_lim.size() - level); - qhead = trail.size(); } } - - -//================================================================================================= -// Major methods: - - -/*_________________________________________________________________________________________________ -| -| analyze : (confl : Clause*) (out_learnt : vec&) (out_btlevel : int&) -> [void] -| -| Description: -| Analyze conflict and produce a reason clause ('out_learnt') and a backtracking level -| ('out_btlevel'). -| -| Pre-conditions: -| * 'out_learnt' is assumed to be cleared. -| * Current decision level must be greater than root level. -| -| Post-conditions: -| * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'. -| * If performing proof-logging, the last derived clause in the proof is the reason clause. -|________________________________________________________________________________________________@*/ - -class lastToFirst_lt { // Helper class to 'analyze' -- order literals from last to first occurance in 'trail[]'. - const vec& trail_pos; -public: - lastToFirst_lt(const vec& t) : trail_pos(t) {} - bool operator () (Lit p, Lit q) { return trail_pos[var(p)] > trail_pos[var(q)]; } -}; -void Solver::analyze(Clause* confl, vec& out_learnt, int& out_btlevel) -{ - vec& seen = analyze_seen; - int pathC = 0; - Lit p = lit_Undef; - - // Generate conflict clause: - // - if (proof != NULL) proof->beginChain(confl->id()); - out_learnt.push(); // (leave room for the asserting literal) - out_btlevel = 0; - int index = trail.size()-1; - for(;;){ - assert(confl != NULL); // (otherwise should be UIP) - - Clause& c = *confl; - if (c.learnt()) - claBumpActivity(&c); - - for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){ - Lit q = c[j]; - if (!seen[var(q)]){ - if (level[var(q)] > 0){ - varBumpActivity(q); - seen[var(q)] = 1; - if (level[var(q)] == decisionLevel()) - pathC++; - else{ - out_learnt.push(q); - out_btlevel = max(out_btlevel, level[var(q)]); - } - }else - if (proof != NULL) proof->resolve(unit_id[var(q)], q); - } - } - - // Select next clause to look at: - while (!seen[var(trail[index--])]); - p = trail[index+1]; - confl = reason[var(p)]; - seen[var(p)] = 0; - pathC--; - if (pathC == 0) break; - - if (proof != NULL) proof->resolve(confl->id(), ~p); - } - out_learnt[0] = ~p; - - // Conflict clause minimization: - // - int i=0 , j=0 ; - if (expensive_ccmin == 2){ - // Simplify conflict clause (a lot): - // - uint min_level = 0; - for (i = 1; i < out_learnt.size(); i++) - min_level |= 1 << (level[var(out_learnt[i])] & 31); // (maintain an abstraction of levels involved in conflict) - - analyze_toclear.clear(); - for (i = j = 1; i < out_learnt.size(); i++) - if (reason[var(out_learnt[i])] == NULL || !analyze_removable(out_learnt[i], min_level)) - out_learnt[j++] = out_learnt[i]; - }else if(expensive_ccmin == 1){ - // Simplify conflict clause (a little): - // - analyze_toclear.clear(); - for (i = j = 1; i < out_learnt.size(); i++){ - Clause* r = reason[var(out_learnt[i])]; - if (r == NULL) - out_learnt[j++] = out_learnt[i]; - else{ - Clause& c = *r; - for (int k = 1; k < c.size(); k++) - if (!seen[var(c[k])] && level[var(c[k])] != 0){ - out_learnt[j++] = out_learnt[i]; - goto Keep; - } - analyze_toclear.push(out_learnt[i]); - Keep:; - } - } - } - - // Finilize proof logging with conflict clause minimization steps: - // - if (proof != NULL){ - sort(analyze_toclear, lastToFirst_lt(trail_pos)); - for (int k = 0; k < analyze_toclear.size(); k++){ - Var v = var(analyze_toclear[k]); assert(level[v] > 0); - Lit l = analyze_toclear[k]; - Clause& c = *reason[v]; - proof->resolve(c.id(), l); - for (int k = 1; k < c.size(); k++) - if (level[var(c[k])] == 0) - proof->resolve(unit_id[var(c[k])], c[k]); - } - proof->endChain(); - } - // Clean up: - // - for (int j = 0; j < out_learnt.size() ; j++) seen[var(out_learnt [j])] = 0; - for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared) - - stats.max_literals += out_learnt.size(); - out_learnt.shrink(i - j); - stats.tot_literals += out_learnt.size(); -} - - -// Check if 'p' can be removed. 'min_level' is used to abort early if visiting literals at a level that cannot be removed. -// -bool Solver::analyze_removable(Lit p, uint min_level) -{ - assert(reason[var(p)] != NULL); - analyze_stack.clear(); analyze_stack.push(p); - int top = analyze_toclear.size(); - while (analyze_stack.size() > 0){ - assert(reason[var(analyze_stack.last())] != NULL); - Clause& c = *reason[var(analyze_stack.last())]; - analyze_stack.pop(); - for (int i = 1; i < c.size(); i++){ - Lit p = c[i]; - if (!analyze_seen[var(p)] && level[var(p)] != 0){ - if (reason[var(p)] != NULL && ((1 << (level[var(p)] & 31)) & min_level) != 0){ - analyze_seen[var(p)] = 1; - analyze_stack.push(p); - analyze_toclear.push(p); - }else{ - for (int j = top; j < analyze_toclear.size(); j++) - analyze_seen[var(analyze_toclear[j])] = 0; - analyze_toclear.shrink(analyze_toclear.size() - top); - return false; - } - } - } - } - analyze_toclear.push(p); - - return true; -} - - -/*_________________________________________________________________________________________________ -| -| analyzeFinal : (confl : Clause*) (skip_first : bool) -> [void] -| -| Description: -| Specialized analysis procedure to express the final conflict in terms of assumptions. -| 'root_level' is allowed to point beyond end of trace (useful if called after conflict while -| making assumptions). If 'skip_first' is TRUE, the first literal of 'confl' is ignored (needed -| if conflict arose before search even started). -|________________________________________________________________________________________________@*/ -void Solver::analyzeFinal(Clause* confl, bool skip_first) -{ - // -- NOTE! This code is relatively untested. Please report bugs! - conflict.clear(); - if (root_level == 0){ - if (proof != NULL) conflict_id = proof->last(); - return; } - //assert(false); - vec& seen = analyze_seen; - if (proof != NULL) proof->beginChain(confl->id()); - for (int i = skip_first ? 1 : 0; i < confl->size(); i++){ - Var x = var((*confl)[i]); - Lit l = (*confl)[i]; - if (level[x] > 0) - seen[x] = 1; - else - if (proof != NULL) proof->resolve(unit_id[x], l); - } - - int start = (root_level >= trail_lim.size()) ? trail.size()-1 : trail_lim[root_level]; - for (int i = start; i >= trail_lim[0]; i--){ - Var x = var(trail[i]); - Lit l = trail[i]; - if (seen[x]){ - Clause* r = reason[x]; - if (r == NULL){ - assert(level[x] > 0); - conflict.push(~trail[i]); - }else{ - Clause& c = *r; - if (proof != NULL) proof->resolve(c.id(), l); - for (int j = 1; j < c.size(); j++) - if (level[var(c[j])] > 0) - seen[var(c[j])] = 1; - else - if (proof != NULL) proof->resolve(unit_id[var(c[j])], c[j]); - } - seen[x] = 0; - } - } - if (proof != NULL) conflict_id = proof->endChain(); -} - - -/*_________________________________________________________________________________________________ -| -| enqueue : (p : Lit) (from : Clause*) -> [bool] -| -| Description: -| Puts a new fact on the propagation queue as well as immediately updating the variable's value. -| Should a conflict arise, FALSE is returned. -| -| Input: -| p - The fact to enqueue -| from - [Optional] Fact propagated from this (currently) unit clause. Stored in 'reason[]'. -| Default value is NULL (no reason). -| -| Output: -| TRUE if fact was enqueued without conflict, FALSE otherwise. -|________________________________________________________________________________________________@*/ -bool Solver::enqueue(Lit p, Clause* from) -{ - if (value(p) != l_Undef) - return value(p) != l_False; - else{ - Var x = var(p); - assigns [x] = toInt(lbool(!sign(p))); - level [x] = decisionLevel(); - trail_pos[x] = trail.size(); - reason [x] = from; - trail.push(p); - return true; - } -} - - - -/*_________________________________________________________________________________________________ -| -| propagate : [void] -> [Clause*] -| -| Description: -| Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned, -| otherwise NULL. NOTE! This method has been optimized for speed rather than readability. -| -| Post-conditions: -| * The propagation queue is empty, even if there was a conflict. -|________________________________________________________________________________________________@*/ -Clause* Solver::propagate() -{ - Clause* confl = NULL; - while (qhead < trail.size()){ - stats.propagations++; - simpDB_props--; - - Lit p = trail[qhead++]; // 'p' is enqueued fact to propagate. - vec& ws = watches[index(p)]; - Clause** i,** j,** end; - - for (i = j = (Clause**)ws, end = i + ws.size(); i != end;){ - Clause& c = **i; i++; - // Make sure the false literal is data[1]: - Lit false_lit = ~p; - if (c[0] == false_lit) - c[0] = c[1], c[1] = false_lit; - - assert(c[1] == false_lit); - - // If 0th watch is true, then clause is already satisfied. - Lit first = c[0]; - lbool val = value(first); - if (val == l_True){ - *j++ = &c; - }else{ - // Look for new watch: - for (int k = 2; k < c.size(); k++) - if (value(c[k]) != l_False){ - c[1] = c[k]; c[k] = false_lit; - watches[index(~c[1])].push(&c); - goto FoundWatch; } - - // Did not find watch -- clause is unit under assignment: - if (decisionLevel() == 0 && proof != NULL){ - // Log the production of this unit clause: - proof->beginChain(c.id()); - for (int k = 1; k < c.size(); k++) - proof->resolve(unit_id[var(c[k])], c[k]); - ClauseId id = proof->endChain(); - assert(unit_id[var(first)] == ClauseId_NULL || value(first) == l_False); // (if variable already has 'id', it must be with the other polarity and we should have derived the empty clause here) - if (value(first) != l_False) - unit_id[var(first)] = id; - else{ - // Empty clause derived: - proof->beginChain(unit_id[var(first)]); - proof->resolve(id, ~first); - proof->endChain(); - } - } - - *j++ = &c; - if (!enqueue(first, &c)){ - if (decisionLevel() == 0) - ok = false; - confl = &c; - qhead = trail.size(); - // Copy the remaining watches: - while (i < end) - *j++ = *i++; - } - FoundWatch:; - } - } - ws.shrink(i - j); - } - - return confl; -} - - -/*_________________________________________________________________________________________________ -| -| reduceDB : () -> [void] -| -| Description: -| Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked -| clauses are clauses that are reason to some assignment. Binary clauses are never removed. -|________________________________________________________________________________________________@*/ -struct reduceDB_lt { bool operator () (Clause* x, Clause* y) { return x->size() > 2 && (y->size() == 2 || x->activity() < y->activity()); } }; -void Solver::reduceDB() -{ - int i, j; - double extra_lim = cla_inc / learnts.size(); // Remove any clause below this activity - - sort(learnts, reduceDB_lt()); - for (i = j = 0; i < learnts.size() / 2; i++){ - if (learnts[i]->size() > 2 && !locked(learnts[i])) - remove(learnts[i]); - else - learnts[j++] = learnts[i]; - } - for (; i < learnts.size(); i++){ - if (learnts[i]->size() > 2 && !locked(learnts[i]) && learnts[i]->activity() < extra_lim) - remove(learnts[i]); - else - learnts[j++] = learnts[i]; - } - learnts.shrink(i - j); -} - - -/*_________________________________________________________________________________________________ -| -| simplifyDB : [void] -> [bool] -| -| Description: -| Simplify the clause database according to the current top-level assigment. Currently, the only -| thing done here is the removal of satisfied clauses, but more things can be put here. -|________________________________________________________________________________________________@*/ -void Solver::simplifyDB() -{ - if (!ok) return; // GUARD (public method) - assert(decisionLevel() == 0); - - if (propagate() != NULL){ - ok = false; - return; } - - if (nAssigns() == simpDB_assigns || simpDB_props > 0) // (nothing has changed or preformed a simplification too recently) - return; - - // Clear watcher lists: - for (int i = simpDB_assigns; i < nAssigns(); i++){ - Lit p = trail[i]; - watches[index( p)].clear(true); - watches[index(~p)].clear(true); - } - - // Remove satisfied clauses: - for (int type = 0; type < 2; type++){ - vec& cs = type ? learnts : clauses; - int j = 0; - for (int i = 0; i < cs.size(); i++){ - if (!locked(cs[i]) && simplify(cs[i])) - remove(cs[i]); - else - cs[j++] = cs[i]; - } - cs.shrink(cs.size()-j); - } - - simpDB_assigns = nAssigns(); - simpDB_props = stats.clauses_literals + stats.learnts_literals; // (shouldn't depend on 'stats' really, but it will do for now) -} - - -/*_________________________________________________________________________________________________ -| -| search : (nof_conflicts : int) (nof_learnts : int) (params : const SearchParams&) -> [lbool] -| -| Description: -| Search for a model the specified number of conflicts, keeping the number of learnt clauses -| below the provided limit. NOTE! Use negative value for 'nof_conflicts' or 'nof_learnts' to -| indicate infinity. -| -| Output: -| 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If -| all variables are decision variables, this means that the clause set is satisfiable. 'l_False' -| if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached. -|________________________________________________________________________________________________@*/ -lbool Solver::search(int nof_conflicts, int nof_learnts, const SearchParams& params) -{ - if (!ok) return l_False; // GUARD (public method) - assert(root_level == decisionLevel()); - - stats.starts++; - int conflictC = 0; - var_decay = 1 / params.var_decay; - cla_decay = 1 / params.clause_decay; - model.clear(); - - for (;;){ - Clause* confl = propagate(); - if (confl != NULL){ - // CONFLICT - - stats.conflicts++; conflictC++; - vec learnt_clause; - int backtrack_level; - if (decisionLevel() == root_level){ - // Contradiction found: - analyzeFinal(confl); - return l_False; } - analyze(confl, learnt_clause, backtrack_level); - cancelUntil(max(backtrack_level, root_level)); - newClause(learnt_clause, true, (proof != NULL) ? proof->last() : ClauseId_NULL); - if (learnt_clause.size() == 1) level[var(learnt_clause[0])] = 0; // (this is ugly (but needed for 'analyzeFinal()') -- in future versions, we will backtrack past the 'root_level' and redo the assumptions) - varDecayActivity(); - claDecayActivity(); - - }else{ - // NO CONFLICT - - if (nof_conflicts >= 0 && conflictC >= nof_conflicts){ - // Reached bound on number of conflicts: - progress_estimate = progressEstimate(); - cancelUntil(root_level); - return l_Undef; } - - if (decisionLevel() == 0) - // Simplify the set of problem clauses: - simplifyDB(), assert(ok); - - if (nof_learnts >= 0 && learnts.size()-nAssigns() >= nof_learnts) - // Reduce the set of learnt clauses: - reduceDB(); - - // New variable decision: - stats.decisions++; - Var next = order.select(params.random_var_freq); - - if (next == var_Undef){ - // Model found: - model.growTo(nVars()); - for (int i = 0; i < nVars(); i++) model[i] = value(i); - cancelUntil(root_level); - return l_True; - } - - check(assume(~Lit(next))); - } - } -} - - -// Return search-space coverage. Not extremely reliable. -// -double Solver::progressEstimate() -{ - double progress = 0; - double F = 1.0 / nVars(); - for (int i = 0; i < nVars(); i++) - if (value(i) != l_Undef) - progress += pow(F, level[i]); - return progress / nVars(); -} - - -// Divide all variable activities by 1e100. -// -void Solver::varRescaleActivity() -{ - for (int i = 0; i < nVars(); i++) - activity[i] *= 1e-100; - var_inc *= 1e-100; -} - - -// Divide all constraint activities by 1e100. -// -void Solver::claRescaleActivity() -{ - for (int i = 0; i < learnts.size(); i++) - learnts[i]->activity() *= 1e-20; - cla_inc *= 1e-20; -} - - -/*_________________________________________________________________________________________________ -| -| solve : (assumps : const vec&) -> [bool] -| -| Description: -| Top-level solve. If using assumptions (non-empty 'assumps' vector), you must call -| 'simplifyDB()' first to see that no top-level conflict is present (which would put the solver -| in an undefined state). -| -| Input: -| A list of assumptions (unit clauses coded as literals). Pre-condition: The assumptions must -| not contain both 'x' and '~x' for any variable 'x'. -|________________________________________________________________________________________________@*/ -lbool Solver::solve(const vec& assumps) -{ - simplifyDB(); - if (!ok) return l_False; // false; - - SearchParams params(default_params); - double nof_conflicts = 100; - double nof_learnts = nClauses() / 3; - lbool status = l_Undef; - - // Perform assumptions: - root_level = assumps.size(); - for (int i = 0; i < assumps.size(); i++){ - Lit p = assumps[i]; - assert(var(p) < nVars()); - if (!assume(p)){ - if (reason[var(p)] != NULL){ - analyzeFinal(reason[var(p)], true); - conflict.push(~p); - }else{ - assert(proof == NULL || unit_id[var(p)] != ClauseId_NULL); // (this is the pre-condition above) - conflict.clear(); - conflict.push(~p); - if (proof != NULL) conflict_id = unit_id[var(p)]; - } - cancelUntil(0); - return l_False; } // false; } - Clause* confl = propagate(); - if (confl != NULL){ - analyzeFinal(confl), assert(conflict.size() > 0); - cancelUntil(0); - return l_False; } // false; } - } - assert(root_level == decisionLevel()); - - // Search: - if (verbosity >= 1){ - reportf("==================================[MINISAT]"); - reportf("===================================\n"); - reportf("| Conflicts | ORIGINAL | "); - reportf("LEARNT | Progress |\n"); - reportf("| | Clauses Literals | Limit Clauses "); - reportf("Literals Lit/Cl | |\n"); - reportf("==========================================="); - reportf("===================================\n"); - } - - while (status == l_Undef){ - if (verbosity >= 1){ - printStats(); - reportf("| %9d | %7d %8d | %7d %7d %8d %7.1f | %6.3f %% |\n", - (int)stats.conflicts, nClauses(), - (int)stats.clauses_literals, - (int)nof_learnts, nLearnts(), - (int)stats.learnts_literals, - (double)stats.learnts_literals/nLearnts(), - progress_estimate*100); - fflush(stdout); - } - status = search((int)nof_conflicts, (int)nof_learnts, params); - nof_conflicts *= 1.5; - nof_learnts *= 1.1; - -if ((int)stats.conflicts >= effLimit) { - cancelUntil(0); - return l_Undef; // status == l_True; -// return status == l_True; -} - } - if (verbosity >= 1) { - reportf("==========================================="); - reportf("===================================\n"); - } - - cancelUntil(0); - return status; -// return status == l_True; -} - -void Solver::printStats() -{ - reportf("==============================[MINISAT]"); - reportf("===============================\n"); - reportf("| Conflicts | ORIGINAL | "); - reportf("LEARNT | Progress |\n"); - reportf("| | Clauses Literals | Clauses "); - reportf("Literals Lit/Cl | |\n"); - reportf("======================================="); - reportf("===============================\n"); - reportf("| %9d | %7d %8d | %7d %8d %7.1f | %6.3f %% |\n", - (int)stats.conflicts, nClauses(), (int)stats.clauses_literals, - nLearnts(), (int)stats.learnts_literals, - (double)stats.learnts_literals/nLearnts(), progress_estimate*100); - reportf("======================================="); - reportf("===============================\n"); -} diff --git a/src/sat/test/Solver.h b/src/sat/test/Solver.h deleted file mode 100644 index b5343760..00000000 --- a/src/sat/test/Solver.h +++ /dev/null @@ -1,219 +0,0 @@ -/****************************************************************************************[Solver.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Solver_h -#define Solver_h - -#include "SolverTypes.h" -#include "VarOrder.h" -#include "Proof.h" - -// Redfine if you want output to go somewhere else: -#define reportf(format, args...) ( printf(format , ## args), fflush(stdout) ) - - -//================================================================================================= -// Solver -- the main class: - - -struct SolverStats { - int64 starts, decisions, propagations, conflicts; - int64 clauses_literals, learnts_literals, max_literals, tot_literals; - SolverStats() : starts(0), decisions(0), propagations(0), conflicts(0) - , clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0) { } -}; - - -struct SearchParams { - double var_decay, clause_decay, random_var_freq; // (reasonable values are: 0.95, 0.999, 0.02) - SearchParams(double v = 1, double c = 1, double r = 0) : var_decay(v), clause_decay(c), random_var_freq(r) { } -}; - - -class Solver { -protected: - // Solver state: - // - bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used! - vec clauses; // List of problem clauses. - vec learnts; // List of learnt clauses. - vec unit_id; // 'unit_id[var]' is the clause ID for the unit literal 'var' or '~var' (if set at toplevel). - double cla_inc; // Amount to bump next clause with. - double cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. - - vec activity; // A heuristic measurement of the activity of a variable. - double var_inc; // Amount to bump next variable with. - double var_decay; // INVERSE decay factor for variable activity: stores 1/decay. Use negative value for static variable order. - VarOrder order; // Keeps track of the decision variable order. - - vec > watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true). - vec assigns; // The current assignments (lbool:s stored as char:s). - vec trail; // Assignment stack; stores all assigments made in the order they were made. - vec trail_lim; // Separator indices for different decision levels in 'trail[]'. - vec reason; // 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none. - vec level; // 'level[var]' is the decision level at which assignment was made. - vec trail_pos; // 'trail_pos[var]' is the variable's position in 'trail[]'. This supersedes 'level[]' in some sense, and 'level[]' will probably be removed in future releases. - int root_level; // Level of first proper decision. - int qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat). - int simpDB_assigns; // Number of top-level assignments since last execution of 'simplifyDB()'. - int64 simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplifyDB()'. - - // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which is used: - // - vec analyze_seen; - vec analyze_stack; - vec analyze_toclear; - Clause* propagate_tmpbin; - Clause* analyze_tmpbin; - vec addUnit_tmp; - vec addBinary_tmp; - vec addTernary_tmp; - - // Main internal methods: - // - bool assume (Lit p); - void cancelUntil (int level); - void record (const vec& clause); - - void analyze (Clause* confl, vec& out_learnt, int& out_btlevel); // (bt = backtrack) - bool analyze_removable(Lit p, uint min_level); // (helper method for 'analyze()') - void analyzeFinal (Clause* confl, bool skip_first = false); - bool enqueue (Lit fact, Clause* from = NULL); - Clause* propagate (); - void reduceDB (); - Lit pickBranchLit (const SearchParams& params); - lbool search (int nof_conflicts, int nof_learnts, const SearchParams& params); - double progressEstimate (); - - // Activity: - // - void varBumpActivity(Lit p) { - if (var_decay < 0) return; // (negative decay means static variable order -- don't bump) - if ( (activity[var(p)] += var_inc) > 1e100 ) varRescaleActivity(); - order.update(var(p)); } - void varDecayActivity () { if (var_decay >= 0) var_inc *= var_decay; } - void varRescaleActivity(); - void claDecayActivity () { cla_inc *= cla_decay; } - void claRescaleActivity(); - - // Operations on clauses: - // - void newClause(const vec& ps, bool learnt = false, ClauseId id = ClauseId_NULL, bool A = true); - void claBumpActivity (Clause* c) { if ( (c->activity() += cla_inc) > 1e20 ) claRescaleActivity(); } - void remove (Clause* c, bool just_dealloc = false); - bool locked (const Clause* c) const { return reason[var((*c)[0])] == c; } - bool simplify (Clause* c) const; - - int decisionLevel() const { return trail_lim.size(); } - -public: - Solver() : ok (true) - , cla_inc (1) - , cla_decay (1) - , var_inc (1) - , var_decay (1) - , order (assigns, activity) - , qhead (0) - , simpDB_assigns (0) - , simpDB_props (0) - , default_params (SearchParams(0.95, 0.999, 0.02)) - , expensive_ccmin (2) - , proof (NULL) - , verbosity (0) - , progress_estimate(0) - , conflict_id (ClauseId_NULL) - { - vec dummy(2,lit_Undef); - propagate_tmpbin = Clause_new(false, dummy); - analyze_tmpbin = Clause_new(false, dummy); - addUnit_tmp .growTo(1); - addBinary_tmp .growTo(2); - addTernary_tmp.growTo(3); - } - - ~Solver() { - for (int i = 0; i < learnts.size(); i++) remove(learnts[i], true); - for (int i = 0; i < clauses.size(); i++) if (clauses[i] != NULL) remove(clauses[i], true); - remove(propagate_tmpbin, true); - remove(analyze_tmpbin, true); - } - - // Helpers: (semi-internal) - // - lbool value(Var x) const { return toLbool(assigns[x]); } - lbool value(Lit p) const { return sign(p) ? ~toLbool(assigns[var(p)]) : toLbool(assigns[var(p)]); } - lbool modelValue(Var x) const { return model[x]; } -// lbool modelValue(Lit p) const { return model[var(p)] ^ sign(p); } - - int nAssigns() { return trail.size(); } - int nClauses() { return clauses.size(); } - int nLearnts() { return learnts.size(); } - - // Statistics: (read-only member variable) - // - SolverStats stats; - - // Mode of operation: - // - SearchParams default_params; // Restart frequency etc. - int expensive_ccmin; // Controls conflict clause minimization. TRUE by default. - Proof* proof; // Set this directly after constructing 'Solver' to enable proof logging. Initialized to NULL. - int verbosity; // Verbosity level. 0=silent, 1=some progress report, 2=everything - - // Problem specification: - // - Var newVar (); - int nVars () { return assigns.size(); } - void addUnit (Lit p) { addUnit_tmp [0] = p; addClause(addUnit_tmp); } - void addBinary (Lit p, Lit q) { addBinary_tmp [0] = p; addBinary_tmp [1] = q; addClause(addBinary_tmp); } - void addTernary(Lit p, Lit q, Lit r) { addTernary_tmp[0] = p; addTernary_tmp[1] = q; addTernary_tmp[2] = r; addClause(addTernary_tmp); } - void addClause (const vec& ps , bool A = true) { newClause(ps , false , ClauseId_NULL , A); } - // (used to be a difference between internal and external method...) - - // Solving: - // - bool okay() { return ok; } // FALSE means solver is in an conflicting state (must never be used again!) - void simplifyDB(); - lbool solve(const vec& assumps); - lbool solve() { vec tmp; return solve(tmp); } - - double progress_estimate; // Set by 'search()'. - vec model; // If problem is satisfiable, this vector contains the model (if any). - vec conflict; // If problem is unsatisfiable under assumptions, this vector represent the conflict clause expressed in the assumptions. - ClauseId conflict_id; // (In proof logging mode only.) ID for the clause 'conflict' (for proof traverseral). NOTE! The empty clause is always the last clause derived, but for conflicts under assumption, this is not necessarly true. - - // Printing: - // - void printStats(); -}; - - -//================================================================================================= -// Debug: - - -#define L_LIT "%s%d" -#define L_lit(p) sign(p)?"-":"", var(p)+1 - -// Just like 'assert()' but expression will be evaluated in the release version as well. -inline void check(bool expr) { assert(expr); } - - -//================================================================================================= -#endif diff --git a/src/sat/test/SolverTypes.h b/src/sat/test/SolverTypes.h deleted file mode 100644 index 74df73a8..00000000 --- a/src/sat/test/SolverTypes.h +++ /dev/null @@ -1,141 +0,0 @@ -/***********************************************************************************[SolverTypes.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - - -#ifndef SolverTypes_h -#define SolverTypes_h - -#ifndef Global_h -#include "Global.h" -#endif - - -//================================================================================================= -// Variables, literals, clause IDs: - - -// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N, -// so that they can be used as array indices. - -typedef int Var; -#define var_Undef (-1) - - -class Lit { - int x; -public: - Lit() : x(2*var_Undef) {} // (lit_Undef) - explicit Lit(Var var, bool sgn = false) : x((var+var) + (int)sgn) {} - friend Lit operator ~ (Lit p); - - friend bool sign (Lit p); - friend int var (Lit p); - friend int index (Lit p); - friend Lit toLit (int i); - friend Lit unsign(Lit p); - friend Lit id (Lit p, bool sgn); - - friend bool operator == (Lit p, Lit q); - friend bool operator < (Lit p, Lit q); - - uint hash() const { return (uint)x; } -}; -inline Lit operator ~ (Lit p) { Lit q; q.x = p.x ^ 1; return q; } -inline bool sign (Lit p) { return p.x & 1; } -inline int var (Lit p) { return p.x >> 1; } -inline int index (Lit p) { return p.x; } // A "toInt" method that guarantees small, positive integers suitable for array indexing. -inline Lit toLit (int i) { Lit p; p.x = i; return p; } // Inverse of 'index()'. -inline Lit unsign(Lit p) { Lit q; q.x = p.x & ~1; return q; } -inline Lit id (Lit p, bool sgn) { Lit q; q.x = p.x ^ (int)sgn; return q; } -inline bool operator == (Lit p, Lit q) { return index(p) == index(q); } -inline bool operator < (Lit p, Lit q) { return index(p) < index(q); } // '<' guarantees that p, ~p are adjacent in the ordering. - -const Lit lit_Undef(var_Undef, false); // }- Useful special constants. -const Lit lit_Error(var_Undef, true ); // } - -inline int toDimacs(Lit p) { return sign(p) ? -var(p) - 1 : var(p) + 1; } - - -//================================================================================================= -// Clause -- a simple class for representing a clause: - - -typedef int ClauseId; // (might have to use uint64 one day...) -const int ClauseId_NULL = INT_MIN; - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class Clause { - uint size_learnt; - Lit data[1]; -public: - // NOTE: This constructor cannot be used directly (doesn't allocate enough memory). - Clause(bool learnt, const vec& ps, ClauseId id_ = ClauseId_NULL) { - size_learnt = (ps.size() << 1) | (int)learnt; - for (int i = 0; i < ps.size(); i++) data[i] = ps[i]; - if (learnt) activity() = 0; - if (id_ != ClauseId_NULL) id() = id_; } - - // -- use this function instead: - friend Clause* Clause_new(bool, const vec&, ClauseId); - - int size () const { return size_learnt >> 1; } - bool learnt () const { return size_learnt & 1; } - Lit operator [] (int i) const { return data[i]; } - Lit& operator [] (int i) { return data[i]; } - float& activity () const { - void *p = const_cast(&data[size()]); return *((float *)p); - } // return *((float*)&data[size()]); } - ClauseId& id () const { return *((ClauseId*)&data[size() + (int)learnt()]); } -}; - -inline Clause* Clause_new(bool learnt, const vec& ps, ClauseId id = ClauseId_NULL) { - assert(sizeof(Lit) == sizeof(uint)); - assert(sizeof(float) == sizeof(uint)); - assert(sizeof(ClauseId) == sizeof(uint)); - void* mem = xmalloc(sizeof(Clause) + sizeof(uint)*(ps.size() + (int)learnt + (int)(id != ClauseId_NULL))); - return new (mem) Clause(learnt, ps, id); } - - -//================================================================================================= -// GClause -- Generalize clause: - - -// Either a pointer to a clause or a literal. -class GClause { - void* data; - GClause(void* d) : data(d) {} -public: - friend GClause GClause_new(Lit p); - friend GClause GClause_new(Clause* c); - - bool isLit () const { return ((uintp)data & 1) == 1; } - Lit lit () const { return toLit(((intp)data) >> 1); } - Clause* clause () const { return (Clause*)data; } - bool operator == (GClause c) const { return data == c.data; } - bool operator != (GClause c) const { return data != c.data; } -}; -inline GClause GClause_new(Lit p) { return GClause((void*)(((intp)index(p) << 1) + 1)); } -inline GClause GClause_new(Clause* c) { assert(((uintp)c & 1) == 0); return GClause((void*)c); } - -#define GClause_NULL GClause_new((Clause*)NULL) - - -//================================================================================================= -#endif diff --git a/src/sat/test/Sort.h b/src/sat/test/Sort.h deleted file mode 100644 index e4191cc7..00000000 --- a/src/sat/test/Sort.h +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************************************[Sort.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef Sort_h -#define Sort_h - - -//================================================================================================= - - -template -struct LessThan_default { - bool operator () (T x, T y) { return x < y; } -}; - - -//================================================================================================= - - -template -void selectionSort(T* array, int size, LessThan lt) -{ - int i, j, best_i; - T tmp; - - for (i = 0; i < size-1; i++){ - best_i = i; - for (j = i+1; j < size; j++){ - if (lt(array[j], array[best_i])) - best_i = j; - } - tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp; - } -} -template static inline void selectionSort(T* array, int size) { - selectionSort(array, size, LessThan_default()); } - - -template -void sort(T* array, int size, LessThan lt, double& seed) -{ - if (size <= 15) - selectionSort(array, size, lt); - - else{ - T pivot = array[irand(seed, size)]; - T tmp; - int i = -1; - int j = size; - - for(;;){ - do i++; while(lt(array[i], pivot)); - do j--; while(lt(pivot, array[j])); - - if (i >= j) break; - - tmp = array[i]; array[i] = array[j]; array[j] = tmp; - } - - sort(array , i , lt, seed); - sort(&array[i], size-i, lt, seed); - } -} -template void sort(T* array, int size, LessThan lt) { - double seed = 91648253; sort(array, size, lt, seed); } -template static inline void sort(T* array, int size) { - sort(array, size, LessThan_default()); } - - -template -void sortUnique(T* array, int& size, LessThan lt) -{ - int i, j; - T last; - - if (size == 0) return; - - sort(array, size, lt); - - i = 1; - last = array[0]; - for (j = 1; j < size; j++){ - if (lt(last, array[j])){ - last = array[i] = array[j]; - i++; } - } - - size = i; -} -template static inline void sortUnique(T* array, int& size) { - sortUnique(array, size, LessThan_default()); } - - -//================================================================================================= -// For 'vec's: - - -template void sort(vec& v, LessThan lt) { - sort((T*)v, v.size(), lt); } -template void sort(vec& v) { - sort(v, LessThan_default()); } - - -template void sortUnique(vec& v, LessThan lt) { - int size = v.size(); - T* data = v.release(); - sortUnique(data, size, lt); - v.~vec(); - new (&v) vec(data, size); } -template void sortUnique(vec& v) { - sortUnique(v, LessThan_default()); } - - -//================================================================================================= -#endif diff --git a/src/sat/test/VarOrder.h b/src/sat/test/VarOrder.h deleted file mode 100644 index ad6c77ce..00000000 --- a/src/sat/test/VarOrder.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************************[VarOrder.h] -MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef VarOrder_h -#define VarOrder_h - -#include "SolverTypes.h" -#include "Heap.h" - - -//================================================================================================= - - -struct VarOrder_lt { - const vec& activity; - bool operator () (Var x, Var y) { return activity[x] > activity[y]; } - VarOrder_lt(const vec& act) : activity(act) { } -}; - -class VarOrder { - const vec& assigns; // var->val. Pointer to external assignment table. -// const vec& activity; // var->act. Pointer to external activity table. - Heap heap; - double random_seed; // For the internal random number generator - -public: - VarOrder(const vec& ass, const vec& act) : -// assigns(ass), activity(act), heap(VarOrder_lt(act)), random_seed(91648253) - assigns(ass), heap(VarOrder_lt(act)), random_seed(91648253) - { } - - inline void newVar(void); - inline void update(Var x); // Called when variable increased in activity. - inline void undo(Var x); // Called when variable is unassigned and may be selected again. - inline Var select(double random_freq =.0); // Selects a new, unassigned variable (or 'var_Undef' if none exists). -}; - - -void VarOrder::newVar(void) -{ - heap.setBounds(assigns.size()); - heap.insert(assigns.size()-1); -} - - -void VarOrder::update(Var x) -{ - if (heap.inHeap(x)) - heap.increase(x); -} - - -void VarOrder::undo(Var x) -{ - if (!heap.inHeap(x)) - heap.insert(x); -} - - -Var VarOrder::select(double random_var_freq) -{ - // Random decision: - if (drand(random_seed) < random_var_freq && !heap.empty()){ - Var next = irand(random_seed,assigns.size()); - if (toLbool(assigns[next]) == l_Undef) - return next; - } - - // Activity based decision: - while (!heap.empty()){ - Var next = heap.getmin(); - if (toLbool(assigns[next]) == l_Undef) - return next; - } - - return var_Undef; -} - - -//================================================================================================= -#endif diff --git a/src/sat/test/andTest b/src/sat/test/andTest deleted file mode 100644 index a9d47086..00000000 Binary files a/src/sat/test/andTest and /dev/null differ diff --git a/src/sat/test/andTest.cpp b/src/sat/test/andTest.cpp deleted file mode 100644 index 118e56aa..00000000 --- a/src/sat/test/andTest.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include -#include -#include "sat.h" - -using namespace std; - -class Gate -{ -public: - Gate(unsigned i = 0): _gid(i) {} - ~Gate() {} - - Var getVar() const { return _var; } - void setVar(const Var& v) { _var = v; } - -private: - unsigned _gid; // for debugging purpose... - Var _var; -}; - -// -// -vector gates; - -void -initCircuit() -{ - // Init gates - for (size_t i = 0; i < 301; ++i) - gates.push_back(new Gate(i)); // gates[i] - - // POs are not needed in this demo example -} - -void -genProofModel(SatSolver& s) -{ - // Allocate and record variables; No Var ID for POs - for (size_t i = 0, n = gates.size(); i < n; ++i) { - Var v = s.newVar(); - gates[i]->setVar(v); - } - - s.addAigCNF(gates[101]->getVar(), gates[0]->getVar(), false, - gates[1]->getVar(), false); - for (size_t i = 2; i < 100; ++i) { - // AIG(100+i, i, 100+i-1) - s.addAigCNF(gates[100+i]->getVar(), gates[100+i-1]->getVar(), false, - gates[i]->getVar(), false); - } // final output = 199 - - s.addAigCNF(gates[200]->getVar(), gates[99]->getVar(), false, - gates[100]->getVar(), false); - for (int i = 98; i >= 0; --i) { - s.addAigCNF(gates[103+i]->getVar(), gates[103+i-1]->getVar(), false, - gates[i]->getVar(), false); - } // final output = 299 - - s.addXorCNF(gates[300]->getVar(), gates[199]->getVar(), false, - gates[299]->getVar(), false); -} - -void reportResult(const SatSolver& solver, bool result) -{ - solver.printStats(); - cout << (result? "SAT" : "UNSAT") << endl; - if (result) { -// for (size_t i = 0, n = gates.size(); i < n; ++i) - for (size_t i = 0, n = 101; i < n; ++i) - cout << solver.getValue(gates[i]->getVar()) << endl; - } - cout << "output = " << solver.getValue(gates[300]->getVar()) << endl; -} - -int main() -{ - initCircuit(); - - SatSolver solver; - solver.initialize(); - - // - genProofModel(solver); - - bool result; - solver.assumeRelease(); // Clear assumptions - solver.assumeProperty(gates[300]->getVar(), true); // Gate(300) = 1 - result = solver.assumpSolve(); - reportResult(solver, result); -} diff --git a/src/sat/test/andTest.dSYM/Contents/Info.plist b/src/sat/test/andTest.dSYM/Contents/Info.plist deleted file mode 100644 index 1e83c145..00000000 --- a/src/sat/test/andTest.dSYM/Contents/Info.plist +++ /dev/null @@ -1,20 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleIdentifier - com.apple.xcode.dsym.andTest - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - dSYM - CFBundleSignature - ???? - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/src/sat/test/andTest.dSYM/Contents/Resources/DWARF/andTest b/src/sat/test/andTest.dSYM/Contents/Resources/DWARF/andTest deleted file mode 100644 index af6ef5d1..00000000 Binary files a/src/sat/test/andTest.dSYM/Contents/Resources/DWARF/andTest and /dev/null differ diff --git a/src/sat/test/sat.h b/src/sat/test/sat.h deleted file mode 100644 index 7a78d392..00000000 --- a/src/sat/test/sat.h +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** - FileName [ sat.h ] - PackageName [ sat ] - Synopsis [ Define miniSat solver interface functions ] - Author [ Chung-Yang (Ric) Huang, Cheng-Yin Wu ] - Copyright [ Copyleft(c) 2010-present LaDs(III), GIEE, NTU, Taiwan ] -****************************************************************************/ - -#ifndef SAT_H -#define SAT_H - -#include -#include -#include "Solver.h" - -using namespace std; - -/********** MiniSAT_Solver **********/ -enum SatResult -{ - UNSAT = 0, - SAT, - UNDECIDED -}; - -class SatSolver -{ - public : - SatSolver():_solver(0) { } - ~SatSolver() { if (_solver) delete _solver; } - - // Solver initialization and reset - void initialize() { - reset(); - if (_curVar == 0) { _solver->newVar(); ++_curVar; } - } - void reset() { - if (_solver) delete _solver; - _solver = new Solver(); - _assump.clear(); _curVar = 0; - } - - // Constructing proof model - // Return the Var ID of the new Var - inline Var newVar() { _solver->newVar(); return _curVar++; } - // fa/fb = true if it is inverted - void addAigCNF(Var vf, Var va, bool fa, Var vb, bool fb) { - vec lits; - Lit lf = Lit(vf); - Lit la = fa? ~Lit(va): Lit(va); - Lit lb = fb? ~Lit(vb): Lit(vb); - lits.push(la); lits.push(~lf); - _solver->addClause(lits); lits.clear(); - lits.push(lb); lits.push(~lf); - _solver->addClause(lits); lits.clear(); - lits.push(~la); lits.push(~lb); lits.push(lf); - _solver->addClause(lits); lits.clear(); - } - // fa/fb = true if it is inverted - void addXorCNF(Var vf, Var va, bool fa, Var vb, bool fb) { - vec lits; - Lit lf = Lit(vf); - Lit la = fa? ~Lit(va): Lit(va); - Lit lb = fb? ~Lit(vb): Lit(vb); - lits.push(~la); lits.push( lb); lits.push( lf); - _solver->addClause(lits); lits.clear(); - lits.push( la); lits.push(~lb); lits.push( lf); - _solver->addClause(lits); lits.clear(); - lits.push( la); lits.push( lb); lits.push(~lf); - _solver->addClause(lits); lits.clear(); - lits.push(~la); lits.push(~lb); lits.push(~lf); - _solver->addClause(lits); lits.clear(); - } - - // For incremental proof, use "assumeSolve()" - void assumeRelease() { _assump.clear(); } - void assumeProperty(Var prop, bool val) { - _assump.push(val? Lit(prop): ~Lit(prop)); - } - SatResult assumpSolve() { - return lbool2SatResult(_solver->solve(_assump)); - } - - // For one time proof, use "solve" - void assertProperty(Var prop, bool val) { - _solver->addUnit(val? Lit(prop): ~Lit(prop)); - } - bool solve() { _solver->solve(); return _solver->okay(); } - - // Functions about Reporting - // Return 1/0/-1; -1 means unknown value - int getValue(Var v) const { - return (_solver->modelValue(v)==l_True?1: - (_solver->modelValue(v)==l_False?0:-1)); } - void printStats() const { const_cast(_solver)->printStats(); } - - private : - Solver *_solver; // Pointer to a Minisat solver - Var _curVar; // Variable currently - vec _assump; // Assumption List for assumption solve - - static SatResult lbool2SatResult(lbool b) { - if (b == l_False) return UNSAT; - if (b == l_True) return SAT; - return UNDECIDED; - } -}; - -#endif // SAT_H - diff --git a/src/sat/test/satTest b/src/sat/test/satTest deleted file mode 100644 index 6a2c9084..00000000 Binary files a/src/sat/test/satTest and /dev/null differ diff --git a/src/sat/test/satTest.cpp b/src/sat/test/satTest.cpp deleted file mode 100644 index 06489ce4..00000000 --- a/src/sat/test/satTest.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include "sat.h" - -using namespace std; - -class Gate -{ -public: - Gate(unsigned i = 0): _gid(i) {} - ~Gate() {} - - Var getVar() const { return _var; } - void setVar(const Var& v) { _var = v; } - -private: - unsigned _gid; // for debugging purpose... - Var _var; -}; - -// -//[0] PI 1 (a) -//[1] PI 2 (b) -//[2] AIG 4 1 2 -//[3] PI 3 (c) -//[4] AIG 5 1 3 -//[5] AIG 6 !4 !5 -//[6] PO 9 !6 -//[7] AIG 7 !2 !3 -//[8] AIG 8 !7 1 -//[9] PO 10 8 -// -vector gates; - -void -initCircuit() -{ - // Init gates - gates.push_back(new Gate(1)); // gates[0] - gates.push_back(new Gate(2)); // gates[1] - gates.push_back(new Gate(4)); // gates[2] - gates.push_back(new Gate(3)); // gates[3] - gates.push_back(new Gate(5)); // gates[4] - gates.push_back(new Gate(6)); // gates[5] - gates.push_back(new Gate(9)); // gates[6] - gates.push_back(new Gate(7)); // gates[7] - gates.push_back(new Gate(8)); // gates[8] - gates.push_back(new Gate(10)); // gates[9] - - // POs are not needed in this demo example -} - -void -genProofModel(SatSolver& s) -{ - // Allocate and record variables; No Var ID for POs - for (size_t i = 0, n = gates.size(); i < n; ++i) { - Var v = s.newVar(); - gates[i]->setVar(v); - } - - // Hard code the model construction here... - // [2] AIG 4 1 2 ==> [2] = [0] & [1] - s.addAigCNF(gates[2]->getVar(), gates[0]->getVar(), false, - gates[1]->getVar(), false); - // [4] AIG 5 1 3 ==> [4] = [0] & [3] - s.addAigCNF(gates[4]->getVar(), gates[0]->getVar(), false, - gates[3]->getVar(), false); - // [5] AIG 6 !4 !5 ==> [5] = ![2] & ![4] - s.addAigCNF(gates[5]->getVar(), gates[2]->getVar(), true, - gates[4]->getVar(), true); - // [7] AIG 7 !2 !3 ==> [7] = ![1] & ![3] - s.addAigCNF(gates[7]->getVar(), gates[1]->getVar(), true, - gates[3]->getVar(), true); - // [8] AIG 8 !7 1 ==> [8] = ![7] & [0] - s.addAigCNF(gates[8]->getVar(), gates[7]->getVar(), true, - gates[0]->getVar(), false); -} - -void reportResult(const SatSolver& solver, bool result) -{ - solver.printStats(); - cout << (result? "SAT" : "UNSAT") << endl; - if (result) { - for (size_t i = 0, n = gates.size(); i < n; ++i) - cout << solver.getValue(gates[i]->getVar()) << endl; - } -} - -int main() -{ - initCircuit(); - - SatSolver solver; - solver.initialize(); - - // - genProofModel(solver); - - bool result; - // k = Solve(Gate(5) ^ Gate(8)) - Var newV = solver.newVar(); - solver.addXorCNF(newV, gates[5]->getVar(), false, gates[8]->getVar(), false); - solver.assumeRelease(); // Clear assumptions - solver.assumeProperty(newV, true); // k = 1 - result = solver.assumpSolve(); - reportResult(solver, result); -} diff --git a/src/sat/test/satTest2 b/src/sat/test/satTest2 deleted file mode 100644 index bbcd886b..00000000 Binary files a/src/sat/test/satTest2 and /dev/null differ diff --git a/src/sat/test/satTest2.cpp b/src/sat/test/satTest2.cpp deleted file mode 100644 index 94cb19f3..00000000 --- a/src/sat/test/satTest2.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include "sat.h" - -using namespace std; - -class Gate -{ -public: - Gate(unsigned i = 0): _gid(i) {} - ~Gate() {} - - Var getVar() const { return _var; } - void setVar(const Var& v) { _var = v; } - -private: - unsigned _gid; // for debugging purpose... - Var _var; -}; - -// -//[0] PI 1 (a) -//[1] PI 2 (b) -//[2] AIG 4 1 2 -//[3] PI 3 (c) -//[4] AIG 5 1 3 -//[5] AIG 6 !4 !5 -//[6] PO 9 !6 -//[7] AIG 7 !2 !3 -//[8] AIG 8 !7 1 -//[9] PO 10 8 -// -vector gates; - -void -initCircuit() -{ - // Init gates - gates.push_back(new Gate(1)); // gates[0] - gates.push_back(new Gate(2)); // gates[1] - gates.push_back(new Gate(4)); // gates[2] - gates.push_back(new Gate(3)); // gates[3] - gates.push_back(new Gate(5)); // gates[4] - gates.push_back(new Gate(6)); // gates[5] - gates.push_back(new Gate(9)); // gates[6] - gates.push_back(new Gate(7)); // gates[7] - gates.push_back(new Gate(8)); // gates[8] - gates.push_back(new Gate(10)); // gates[9] - - // POs are not needed in this demo example -} - -void -genProofModel(SatSolver& s) -{ - // Allocate and record variables; No Var ID for POs - for (size_t i = 0, n = gates.size(); i < n; ++i) { - Var v = s.newVar(); - gates[i]->setVar(v); - } - - // Hard code the model construction here... - // [2] AIG 4 1 2 ==> [2] = [0] & [1] - s.addAigCNF(gates[2]->getVar(), gates[0]->getVar(), false, - gates[1]->getVar(), false); - // [4] AIG 5 1 3 ==> [4] = [0] & [3] - s.addAigCNF(gates[4]->getVar(), gates[0]->getVar(), false, - gates[3]->getVar(), false); - // [5] AIG 6 !4 !5 ==> [5] = ![2] & ![4] - s.addAigCNF(gates[5]->getVar(), gates[2]->getVar(), true, - gates[4]->getVar(), true); - // [7] AIG 7 !2 !3 ==> [7] = ![1] & ![3] - s.addAigCNF(gates[7]->getVar(), gates[1]->getVar(), true, - gates[3]->getVar(), true); - // [8] AIG 8 !7 1 ==> [8] = ![7] & [0] - s.addAigCNF(gates[8]->getVar(), gates[7]->getVar(), true, - gates[0]->getVar(), false); -} - -void reportResult(const SatSolver& solver, bool result) -{ - solver.printStats(); - cout << (result? "SAT" : "UNSAT") << endl; - if (result) { - for (size_t i = 0, n = gates.size(); i < n; ++i) - cout << solver.getValue(gates[i]->getVar()) << endl; - } -} - -int main() -{ - initCircuit(); - - SatSolver solver; - solver.initialize(); - - // - genProofModel(solver); - - bool result; - // Solve(Gate(3) && Gate(6)) - Var newV = solver.newVar(); - solver.addXorCNF(newV, gates[5]->getVar(), false, gates[8]->getVar(), true); - solver.assumeRelease(); // Clear assumptions - solver.assumeProperty(newV, true); // Gate(3) = 1 - result = solver.assumpSolve(); - reportResult(solver, result); -} diff --git a/src/sat/test/satTest3 b/src/sat/test/satTest3 deleted file mode 100644 index 7302b2c2..00000000 Binary files a/src/sat/test/satTest3 and /dev/null differ diff --git a/src/sat/test/tags b/src/sat/test/tags deleted file mode 100644 index e5c45ed6..00000000 --- a/src/sat/test/tags +++ /dev/null @@ -1,467 +0,0 @@ -!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ -!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ -!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ -!_TAG_PROGRAM_NAME Exuberant Ctags // -!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ -!_TAG_PROGRAM_VERSION 5.6 // -AND itp.h /^ virtual AigPtr AND( const AigPtr & a , const AigPtr & b){return _ref.createAND( a, b);}$/;" f class:SITP -AigCal itp.h /^class AigCal$/;" c -CC_MIN itp.h /^ int CC_MIN;\/\/ $/;" m class:ITPMgr -CONST_MODE itp.h /^ enum CONST_MODE{ ON_THE_FLY , NONE , POST };$/;" g class:ITPMgr -Checker itp.h /^ Checker():TRA_INT(0){}$/;" f struct:Checker -Checker itp.h /^struct Checker : virtual public ProofTraverser $/;" s -Clause SolverTypes.h /^ Clause(bool learnt, const vec& ps, ClauseId id_ = ClauseId_NULL) {$/;" f class:Clause -Clause SolverTypes.h /^class Clause {$/;" c -ClauseId SolverTypes.h /^typedef int ClauseId; \/\/ (might have to use uint64 one day...)$/;" t -ClauseId_NULL SolverTypes.h /^const int ClauseId_NULL = INT_MIN;$/;" v -Clause_new SolverTypes.h /^inline Clause* Clause_new(bool learnt, const vec& ps, ClauseId id = ClauseId_NULL) {$/;" f -DEFAULTS File.h 40;" d -DEFAULTS File.h 48;" d -Datum Global.h /^ typedef T Datum;$/;" t class:vec -Exception_EOF File.h /^class Exception_EOF {};$/;" c -File File.h /^ File(cchar* name, cchar* mode) : DEFAULTS {$/;" f class:File -File File.h /^ File(int fd, FileMode mode, bool own_fd = true) : DEFAULTS {$/;" f class:File -File File.h /^ File(void) : DEFAULTS {}$/;" f class:File -File File.h /^class File {$/;" c -FileMode File.h /^enum FileMode { READ, WRITE };$/;" g -File_BufSize File.h 22;" d -File_h File.h 2;" d -GClause SolverTypes.h /^ GClause(void* d) : data(d) {}$/;" f class:GClause -GClause SolverTypes.h /^class GClause {$/;" c -GClause_NULL SolverTypes.h 135;" d -GClause_new SolverTypes.h /^inline GClause GClause_new(Clause* c) { assert(((uintp)c & 1) == 0); return GClause((void*)c); }$/;" f -GClause_new SolverTypes.h /^inline GClause GClause_new(Lit p) { return GClause((void*)(((intp)index(p) << 1) + 1)); }$/;" f -Gate satTest.cpp /^ Gate(unsigned i = 0): _gid(i) {}$/;" f class:Gate -Gate satTest.cpp /^class Gate$/;" c file: -Global_h Global.h 21;" d -Heap Heap.h /^ Heap(C c) : comp(c) { heap.push(-1); }$/;" f class:Heap -Heap Heap.h /^class Heap {$/;" c -Heap_h Heap.h 21;" d -I64_fmt Global.h 41;" d -I64_fmt Global.h 47;" d -ITE itp.h /^ virtual AigPtr ITE(const AigPtr & c , const AigPtr & t , const AigPtr & f){ return OR( AND(c,t),AND(~c,f)) ; }$/;" f class:AigCal -ITP itp.h /^ ITP(){}$/;" f class:ITP -ITP itp.h /^class ITP : virtual public ProofTraverser $/;" c -ITPMgr itp.h /^ ITPMgr( ):$/;" f class:ITPMgr -ITPMgr itp.h /^class ITPMgr$/;" c -ITP_CONTAINER itp.h /^ int ITP_CONTAINER;$/;" m class:ITPMgr -ITP_H itp.h 2;" d -ITP_PHASE itp.h /^ int ITP_PHASE;$/;" m class:ITPMgr -InterpolantITP itp.h /^class InterpolantITP : virtual public ProofTraverser $/;" c -Key Global.h /^ typedef int Key;$/;" t class:vec -L_LIT Solver.h 205;" d -L_lit Solver.h 206;" d -LessThan_default Sort.h /^struct LessThan_default {$/;" s -Lit SolverTypes.h /^ Lit() : x(2*var_Undef) {} \/\/ (lit_Undef)$/;" f class:Lit -Lit SolverTypes.h /^ explicit Lit(Var var, bool sgn = false) : x((var+var) + (int)sgn) {}$/;" f class:Lit -Lit SolverTypes.h /^class Lit {$/;" c -MITP itp.h /^ MITP( ) :ITP(){}$/;" f class:MITP -MITP itp.h /^class MITP : virtual public ITP , virtual public AigCal , virtual public ProofTraverser $/;" c -MITP_H mitp.h 2;" d -MODE itp.h /^ int MODE;$/;" m class:ITPMgr -MVITP mitp.h /^class MVITP : virtual public ProofTraverser $/;" c -MultiSITP itp.cpp /^MultiSITP::MultiSITP(unsigned n ) : _sitp( n , NULL )$/;" f class:MultiSITP -MultiSITP itp.h /^class MultiSITP : virtual public ProofTraverser $/;" c -NONE itp.h /^ enum CONST_MODE{ ON_THE_FLY , NONE , POST };$/;" e enum:ITPMgr::CONST_MODE -ON_THE_FLY itp.h /^ enum CONST_MODE{ ON_THE_FLY , NONE , POST };$/;" e enum:ITPMgr::CONST_MODE -OR itp.h /^ virtual AigPtr OR( const AigPtr & a , const AigPtr & b){ return ~( AND ( (~a) , (~b)) );}$/;" f class:AigCal -PFT_CONTAINER itp.h /^ int PFT_CONTAINER;$/;" m class:ITPMgr -PITP itp.h /^ PITP():ITP(){}$/;" f class:PITP -PITP itp.h /^class PITP : virtual public ITP , virtual public AigCal , virtual public ProofTraverser $/;" c -POST itp.h /^ enum CONST_MODE{ ON_THE_FLY , NONE , POST };$/;" e enum:ITPMgr::CONST_MODE -Proof Proof.cpp /^Proof::Proof()$/;" f class:Proof -Proof Proof.cpp /^Proof::Proof(ProofTraverser& t)$/;" f class:Proof -Proof Proof.h /^class Proof {$/;" c -ProofTraverser Proof.h /^struct ProofTraverser {$/;" s -Proof_h Proof.h 21;" d -READ File.h /^enum FileMode { READ, WRITE };$/;" e enum:FileMode -SAT_H sat.h 10;" d -SITP itp.cpp /^SITP::SITP( StrashCkt & r , bool p):_ref(r)$/;" f class:SITP -SITP itp.h /^class SITP : virtual public ITP , virtual public AigCal , virtual public InterpolantITP $/;" c -SMITP itp.h /^ SMITP( StrashCkt & k , bool p ):SITP(k,p){}$/;" f class:SMITP -SMITP itp.h /^class SMITP : virtual public SITP , virtual public MITP$/;" c -SPITP itp.h /^ SPITP( StrashCkt & k , bool p):SITP(k,p){}$/;" f class:SPITP -SPITP itp.h /^class SPITP: virtual public SITP , virtual public PITP$/;" c -STATIC_ASSERTION_FAILURE Global.h /^template <> struct STATIC_ASSERTION_FAILURE{};$/;" s -SatSolver sat.h /^ SatSolver() { }$/;" f class:SatSolver -SatSolver sat.h /^class SatSolver$/;" c -SearchParams Solver.h /^ SearchParams(double v = 1, double c = 1, double r = 0) : var_decay(v), clause_decay(c), random_var_freq(r) { }$/;" f struct:SearchParams -SearchParams Solver.h /^struct SearchParams {$/;" s -Solver Solver.h /^ Solver() : ok (true)$/;" f class:Solver -Solver Solver.h /^class Solver {$/;" c -SolverStats Solver.h /^ SolverStats() : starts(0), decisions(0), propagations(0), conflicts(0)$/;" f struct:SolverStats -SolverStats Solver.h /^struct SolverStats {$/;" s -SolverTypes_h SolverTypes.h 22;" d -Solver_h Solver.h 21;" d -Sort_h Sort.h 21;" d -TEMPLATE_FAIL Global.h 58;" d -TRA_INT Proof.h /^ int TRA_INT;$/;" m class:Proof -TRA_INT itp.h /^ int TRA_INT;$/;" m struct:Checker -TempFiles Proof.cpp /^class TempFiles {$/;" c file: -Var SolverTypes.h /^typedef int Var;$/;" t -VarA itp.cpp /^const int ITP::VarA;$/;" m class:ITP file: -VarA itp.h /^ static const int VarA = -1 ;$/;" m class:ITP -VarB itp.cpp /^const int ITP::VarB;$/;" m class:ITP file: -VarB itp.h /^ static const int VarB = -2 ; $/;" m class:ITP -VarOrder VarOrder.h /^ VarOrder(const vec& ass, const vec& act) :$/;" f class:VarOrder -VarOrder VarOrder.h /^class VarOrder {$/;" c -VarOrder_h VarOrder.h 21;" d -VarOrder_lt VarOrder.h /^ VarOrder_lt(const vec& act) : activity(act) { }$/;" f struct:VarOrder_lt -VarOrder_lt VarOrder.h /^struct VarOrder_lt {$/;" s -VarUnknow itp.h /^ static const int VarUnknow = -3 ; $/;" m class:ITP -WRITE File.h /^enum FileMode { READ, WRITE };$/;" e enum:FileMode -__SGI_STL_INTERNAL_RELOPS Global.h 265;" d -_assump sat.h /^ vec _assump; \/\/ Assumption List for assumption solve$/;" m class:SatSolver -_curVar sat.h /^ Var _curVar; \/\/ Variable currently$/;" m class:SatSolver -_gid satTest.cpp /^ unsigned _gid; \/\/ for debugging purpose...$/;" m class:Gate file: -_interpolant itp.h /^ AigPtr _interpolant;$/;" m class:SITP -_interpolant itp.h /^ AigPtr _interpolant; \/\/ constructed $/;" m class:ITPMgr -_inv itp.h /^ bool _inv;$/;" m class:ITP -_itp itp.h /^ SITP * _itp; \/\/ construction $/;" m class:ITPMgr -_pf itp.h /^ Proof * _pf; \/\/ proof $/;" m class:ITPMgr -_pft itp.h /^ ProofTraverser * _pft; \/\/ internal $/;" m class:ITPMgr -_ref itp.h /^ StrashCkt & _ref;$/;" m class:SITP -_sitp itp.h /^ vector _sitp;$/;" m class:MultiSITP -_solver sat.h /^ Solver *_solver; \/\/ Pointer to a Minisat solver$/;" m class:SatSolver -_subITP itp.h /^ vector _subITP;$/;" m class:ITP -_var satTest.cpp /^ Var _var;$/;" m class:Gate file: -activity Solver.h /^ vec activity; \/\/ A heuristic measurement of the activity of a variable.$/;" m class:Solver -activity SolverTypes.h /^ float& activity () const { return *((float*)&data[size()]); }$/;" f class:Clause -activity VarOrder.h /^ const vec& activity; \/\/ var->act. Pointer to external activity table.$/;" m class:VarOrder -activity VarOrder.h /^ const vec& activity;$/;" m struct:VarOrder_lt -addAndCNF sat.h /^ void addAndCNF(Lit f, Lit a, Lit b) {$/;" f class:SatSolver -addBinary Solver.h /^ void addBinary (Lit p, Lit q) { addBinary_tmp [0] = p; addBinary_tmp [1] = q; addClause(addBinary_tmp); }$/;" f class:Solver -addBinary_tmp Solver.h /^ vec addBinary_tmp;$/;" m class:Solver -addClause Solver.h /^ void addClause (const vec& ps , bool A = true) { newClause(ps , false , ClauseId_NULL , A); } $/;" f class:Solver -addRoot Proof.cpp /^ClauseId Proof::addRoot(vec& cl, bool A)$/;" f class:Proof -addTernary Solver.h /^ void addTernary(Lit p, Lit q, Lit r) { addTernary_tmp[0] = p; addTernary_tmp[1] = q; addTernary_tmp[2] = r; addClause(addTernary_tmp); }$/;" f class:Solver -addTernary_tmp Solver.h /^ vec addTernary_tmp;$/;" m class:Solver -addUnit Solver.h /^ void addUnit (Lit p) { addUnit_tmp [0] = p; addClause(addUnit_tmp); }$/;" f class:Solver -addUnit_tmp Solver.h /^ vec addUnit_tmp;$/;" m class:Solver -analyze Solver.cpp /^void Solver::analyze(Clause* confl, vec& out_learnt, int& out_btlevel)$/;" f class:Solver -analyzeFinal Solver.cpp /^void Solver::analyzeFinal(Clause* confl, bool skip_first)$/;" f class:Solver -analyze_removable Solver.cpp /^bool Solver::analyze_removable(Lit p, uint min_level)$/;" f class:Solver -analyze_seen Solver.h /^ vec analyze_seen;$/;" m class:Solver -analyze_stack Solver.h /^ vec analyze_stack;$/;" m class:Solver -analyze_tmpbin Solver.h /^ Clause* analyze_tmpbin;$/;" m class:Solver -analyze_toclear Solver.h /^ vec analyze_toclear;$/;" m class:Solver -assertProperty sat.h /^ void assertProperty(Var prop, bool val) {$/;" f class:SatSolver -assigns Solver.h /^ vec assigns; \/\/ The current assignments (lbool:s stored as char:s).$/;" m class:Solver -assigns VarOrder.h /^ const vec& assigns; \/\/ var->val. Pointer to external assignment table.$/;" m class:VarOrder -assume Solver.cpp /^bool Solver::assume(Lit p) {$/;" f class:Solver -assumeProperty sat.h /^ void assumeProperty(Var prop, bool val) {$/;" f class:SatSolver -assumeRelease sat.h /^ void assumeRelease() { _assump.clear(); }$/;" f class:SatSolver -assumpSolve sat.h /^ bool assumpSolve() { return _solver->solve(_assump); }$/;" f class:SatSolver -base itp.h /^ vector base;$/;" m class:ITP -beginChain Proof.cpp /^void Proof::beginChain(ClauseId start)$/;" f class:Proof -buf File.h /^ uchar* buf; \/\/ Read or write buffer.$/;" m class:File -cancelUntil Solver.cpp /^void Solver::cancelUntil(int level) {$/;" f class:Solver -cap Global.h /^ int cap;$/;" m class:vec -capacity Global.h /^ void capacity (int size) { grow(size); }$/;" f class:vec -cchar Global.h /^typedef const char cchar;$/;" t -chain itp.cpp /^void Checker::chain (const vec& cs, const vec& xs) $/;" f class:Checker -chain itp.cpp /^void MITP::chain( const vec & cs , const vec & xs )$/;" f class:MITP -chain itp.cpp /^void MultiSITP::chain (const vec& cs, const vec& xs)$/;" f class:MultiSITP -chain itp.cpp /^void PITP::chain( const vec & cs , const vec & xs )$/;" f class:PITP -chain_id Proof.h /^ vec chain_id;$/;" m class:Proof -chain_lit Proof.h /^ vec chain_lit;$/;" m class:Proof -check Solver.h /^inline void check(bool expr) { assert(expr); }$/;" f -claBumpActivity Solver.h /^ void claBumpActivity (Clause* c) { if ( (c->activity() += cla_inc) > 1e20 ) claRescaleActivity(); }$/;" f class:Solver -claDecayActivity Solver.h /^ void claDecayActivity () { cla_inc *= cla_decay; }$/;" f class:Solver -claRescaleActivity Solver.cpp /^void Solver::claRescaleActivity()$/;" f class:Solver -cla_decay Solver.h /^ double cla_decay; \/\/ INVERSE decay factor for clause activity: stores 1\/decay.$/;" m class:Solver -cla_inc Solver.h /^ double cla_inc; \/\/ Amount to bump next clause with.$/;" m class:Solver -clause Proof.h /^ vec clause;$/;" m class:Proof -clause SolverTypes.h /^ Clause* clause () const { return (Clause*)data; }$/;" f class:GClause -clause_decay Solver.h /^ double var_decay, clause_decay, random_var_freq; \/\/ (reasonable values are: 0.95, 0.999, 0.02) $/;" m struct:SearchParams -clauses Solver.h /^ vec clauses; \/\/ List of problem clauses.$/;" m class:Solver -clauses itp.h /^ vec< vec > clauses;$/;" m struct:Checker -clauses_literals Solver.h /^ int64 clauses_literals, learnts_literals, max_literals, tot_literals;$/;" m struct:SolverStats -clear Global.h /^void vec::clear(bool dealloc) {$/;" f class:vec -close File.cpp /^void File::close(void)$/;" f class:File -comp Heap.h /^ C comp;$/;" m class:Heap -compress Proof.cpp /^void Proof::compress(Proof& dst, ClauseId goal)$/;" f class:Proof -conflict Solver.h /^ vec conflict; \/\/ If problem is unsatisfiable under assumptions, this vector represent the conflict clause expressed in the assumptions.$/;" m class:Solver -conflict_id Solver.h /^ ClauseId conflict_id; \/\/ (In proof logging mode only.) ID for the clause 'conflict' (for proof traverseral). NOTE! The empty clause is always the last clause derived, but for conflicts under assumption, this is not necessarly true.$/;" m class:Solver -conflicts Solver.h /^ int64 starts, decisions, propagations, conflicts;$/;" m struct:SolverStats -copyTo Global.h /^ void copyTo(vec& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) new (©[i]) T(data[i]); }$/;" f class:vec -cpuTime Global.h /^static inline double cpuTime(void) {$/;" f -data Global.h /^ T* data;$/;" m class:vec -data SolverTypes.h /^ Lit data[1];$/;" m class:Clause -data SolverTypes.h /^ void* data;$/;" m class:GClause -decisionLevel Solver.h /^ int decisionLevel() const { return trail_lim.size(); }$/;" f class:Solver -decisions Solver.h /^ int64 starts, decisions, propagations, conflicts;$/;" m struct:SolverStats -decode64 File.h /^static inline int64 decode64(uint64 val) { return ((val & 1) == 0) ? (int64)(val >> 1) : ~(int64)(val >> 1); }$/;" f -default_params Solver.h /^ SearchParams default_params; \/\/ Restart frequency etc.$/;" m class:Solver -deleted Proof.cpp /^void Proof::deleted(ClauseId gone)$/;" f class:Proof -deleted Proof.h /^ virtual void deleted(ClauseId c){}$/;" f struct:ProofTraverser -deleted itp.cpp /^void Checker::deleted(ClauseId c) $/;" f class:Checker -deleted itp.cpp /^void MultiSITP::deleted(ClauseId c)$/;" f class:MultiSITP -done itp.cpp /^void Checker::done()$/;" f class:Checker -done itp.cpp /^void MultiSITP::done ()$/;" f class:MultiSITP -done itp.cpp /^void SITP::done()$/;" f class:SITP -drand Global.h /^static inline double drand(double& seed) {$/;" f -empty Heap.h /^ bool empty () { return heap.size() == 1; }$/;" f class:Heap -encode64 File.h /^static inline uint64 encode64(int64 val) { return (val >= 0) ? (uint64)val << 1 : (((uint64)(~val) << 1) | 1); }$/;" f -endChain Proof.cpp /^ClauseId Proof::endChain()$/;" f class:Proof -enqueue Solver.cpp /^bool Solver::enqueue(Lit p, Clause* from)$/;" f class:Solver -eof File.h /^ bool eof(void) {$/;" f class:File -expensive_ccmin Solver.h /^ int expensive_ccmin; \/\/ Controls conflict clause minimization. TRUE by default.$/;" m class:Solver -fd File.h /^ int fd; \/\/ Underlying file descriptor.$/;" m class:File -files Proof.cpp /^ vec files; \/\/ For clean-up purposed on abnormal exit.$/;" m class:TempFiles file: -flush File.h /^ void flush(void) {$/;" f class:File -fp Proof.h /^ File fp;$/;" m class:Proof -fp_name Proof.h /^ cchar* fp_name;$/;" m class:Proof -fpos Proof.h /^ int64 fpos;$/;" m class:Proof -genProofModel satTest.cpp /^genProofModel(SatSolver *s)$/;" f -getChar File.h /^ int getChar(void) {$/;" f class:File -getCharQ File.h /^ int getCharQ(void) { \/\/ Quick version with minimal overhead -- don't call this in the wrong mode!$/;" f class:File -getInt File.h /^static inline uint64 getInt (File& in) { return decode64(getUInt(in)); }$/;" f -getMode File.h /^ FileMode getMode(void) {$/;" f class:File -getUInt File.cpp /^uint64 getUInt(File& in)$/;" f -getVar satTest.cpp /^ Var getVar() const { return _var; }$/;" f class:Gate -getmin Heap.h /^ int getmin() {$/;" f class:Heap -grow Global.h /^void vec::grow(int min_cap) {$/;" f class:vec -growTo Global.h /^void vec::growTo(int size) {$/;" f class:vec -growTo Global.h /^void vec::growTo(int size, const T& pad) {$/;" f class:vec -hash SolverTypes.h /^ uint hash() const { return (uint)x; }$/;" f class:Lit -heap Heap.h /^ vec heap; \/\/ heap of ints$/;" m class:Heap -heap VarOrder.h /^ Heap heap;$/;" m class:VarOrder -heapProperty Heap.h /^ bool heapProperty() {$/;" f class:Heap -heapProperty Heap.h /^ bool heapProperty(int i) {$/;" f class:Heap -id SolverTypes.h /^ ClauseId& id () const { return *((ClauseId*)&data[size() + (int)learnt()]); }$/;" f class:Clause -id SolverTypes.h /^inline Lit id (Lit p, bool sgn) { Lit q; q.x = p.x ^ (int)sgn; return q; }$/;" f -id_counter Proof.h /^ ClauseId id_counter;$/;" m class:Proof -inHeap Heap.h /^ bool inHeap (int n) { assert(ok(n)); return indices[n] != 0; }$/;" f class:Heap -increase Heap.h /^ void increase (int n) { assert(ok(n)); assert(inHeap(n)); percolateUp(indices[n]); }$/;" f class:Heap -index SolverTypes.h /^inline int index (Lit p) { return p.x; } \/\/ A "toInt" method that guarantees small, positive integers suitable for array indexing.$/;" f -indices Heap.h /^ vec indices; \/\/ int -> index in heap$/;" m class:Heap -initCircuit satTest.cpp /^initCircuit()$/;" f -initialize sat.h /^ void initialize() {$/;" f class:SatSolver -insert Heap.h /^ void insert(int n) {$/;" f class:Heap -int64 Global.h /^typedef INT64 int64;$/;" t -int64 Global.h /^typedef long long int64;$/;" t -interpolant itp.h /^ virtual AigPtr interpolant(){return _interpolant;}$/;" f class:SITP -intp Global.h /^typedef INT_PTR intp;$/;" t -intp Global.h /^typedef __PTRDIFF_TYPE__ intp;$/;" t -irand Global.h /^static inline int irand(double& seed, int size) {$/;" f -isLit SolverTypes.h /^ bool isLit () const { return ((uintp)data & 1) == 1; }$/;" f class:GClause -itpGen itp.cpp /^AigPtr ITPMgr::itpGen()$/;" f class:ITPMgr -l_False Global.h /^const lbool l_False = toLbool(-1);$/;" v -l_True Global.h /^const lbool l_True = toLbool( 1);$/;" v -l_Undef Global.h /^const lbool l_Undef = toLbool( 0);$/;" v -last Global.h /^ T& last (void) { return data[sz-1]; }$/;" f class:vec -last Global.h /^ const T& last (void) const { return data[sz-1]; }$/;" f class:vec -last Proof.h /^ ClauseId last () { assert(id_counter != ClauseId_NULL); return id_counter - 1; }$/;" f class:Proof -lastToFirst_lt Solver.cpp /^ lastToFirst_lt(const vec& t) : trail_pos(t) {}$/;" f class:lastToFirst_lt -lastToFirst_lt Solver.cpp /^class lastToFirst_lt { \/\/ Helper class to 'analyze' -- order literals from last to first occurance in 'trail[]'.$/;" c file: -lbool Global.h /^ explicit lbool(int v) : value(v) { }$/;" f class:lbool -lbool Global.h /^ lbool() : value(0) { }$/;" f class:lbool -lbool Global.h /^ lbool(bool x) : value((int)x*2-1) { }$/;" f class:lbool -lbool Global.h /^class lbool {$/;" c -learnt SolverTypes.h /^ bool learnt () const { return size_learnt & 1; }$/;" f class:Clause -learnts Solver.h /^ vec learnts; \/\/ List of learnt clauses.$/;" m class:Solver -learnts_literals Solver.h /^ int64 clauses_literals, learnts_literals, max_literals, tot_literals;$/;" m struct:SolverStats -left Heap.h /^static inline int left (int i) { return i+i; }$/;" f -level Solver.h /^ vec level; \/\/ 'level[var]' is the decision level at which assignment was made.$/;" m class:Solver -lit SolverTypes.h /^ Lit lit () const { return toLit(((intp)data) >> 1); }$/;" f class:GClause -locked Solver.h /^ bool locked (const Clause* c) const { return reason[var((*c)[0])] == c; }$/;" f class:Solver -lseek64 File.h 13;" d -main satTest.cpp /^int main()$/;" f -max Global.h /^template static inline T max(T x, T y) { return (x > y) ? x : y; }$/;" f -max_literals Solver.h /^ int64 clauses_literals, learnts_literals, max_literals, tot_literals;$/;" m struct:SolverStats -memReadStat Global.h /^static inline int memReadStat(int field)$/;" f -memUsed Global.h /^static inline int64 memUsed() { return (int64)memReadStat(0) * (int64)getpagesize(); }$/;" f -memUsed Global.h /^static inline int64 memUsed() {$/;" f -min Global.h /^template static inline T min(T x, T y) { return (x < y) ? x : y; }$/;" f -mode File.h /^ FileMode mode; \/\/ Reading or writing.$/;" m class:File -model Solver.h /^ vec model; \/\/ If problem is satisfiable, this vector contains the model (if any).$/;" m class:Solver -moveTo Global.h /^ void moveTo(vec& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }$/;" f class:vec -nAssigns Solver.h /^ int nAssigns() { return trail.size(); }$/;" f class:Solver -nClauses Solver.h /^ int nClauses() { return clauses.size(); }$/;" f class:Solver -nLearnts Solver.h /^ int nLearnts() { return learnts.size(); }$/;" f class:Solver -nVars Solver.h /^ int nVars () { return assigns.size(); }$/;" f class:Solver -newClause Solver.cpp /^void Solver::newClause(const vec& ps_, bool learnt, ClauseId id , bool A)$/;" f class:Solver -newVar Solver.cpp /^Var Solver::newVar() {$/;" f class:Solver -newVar VarOrder.h /^void VarOrder::newVar(void)$/;" f class:VarOrder -newVar sat.h /^ inline Var newVar() { _solver->newVar(); return ++_curVar; }$/;" f class:SatSolver -null File.h /^ bool null(void) { \/\/ TRUE if no file is opened.$/;" f class:File -ok Heap.h /^ bool ok(int n) { return n >= 0 && n < (int)indices.size(); }$/;" f class:Heap -ok Solver.h /^ bool ok; \/\/ If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used!$/;" m class:Solver -okay Solver.h /^ bool okay() { return ok; } \/\/ FALSE means solver is in an conflicting state (must never be used again!)$/;" f class:Solver -open File.cpp /^void File::open(cchar* name, cchar* mode_)$/;" f class:File -open File.cpp /^void File::open(int file_descr, FileMode m, bool own)$/;" f class:File -open Proof.cpp /^ char* open(File& fp)$/;" f class:TempFiles -open64 File.h 14;" d -operator != Global.h /^ bool operator != (const lbool& other) const { return value != other.value; }$/;" f class:lbool -operator != Global.h /^template static inline bool operator != (const T& x, const T& y) { return !(x == y); }$/;" f -operator != SolverTypes.h /^ bool operator != (GClause c) const { return data != c.data; }$/;" f class:GClause -operator () Solver.cpp /^ bool operator () (Lit p, Lit q) { return trail_pos[var(p)] > trail_pos[var(q)]; }$/;" f class:lastToFirst_lt -operator () Solver.cpp /^struct reduceDB_lt { bool operator () (Clause* x, Clause* y) { return x->size() > 2 && (y->size() == 2 || x->activity() < y->activity()); } };$/;" f struct:reduceDB_lt -operator () Sort.h /^ bool operator () (T x, T y) { return x < y; }$/;" f struct:LessThan_default -operator () VarOrder.h /^ bool operator () (Var x, Var y) { return activity[x] > activity[y]; }$/;" f struct:VarOrder_lt -operator < SolverTypes.h /^inline bool operator < (Lit p, Lit q) { return index(p) < index(q); } \/\/ '<' guarantees that p, ~p are adjacent in the ordering.$/;" f -operator <= Global.h /^template static inline bool operator <= (const T& x, const T& y) { return !(y < x); }$/;" f -operator = Global.h /^ vec& operator = (vec& other) { TEMPLATE_FAIL; }$/;" f class:vec -operator == Global.h /^ bool operator == (const lbool& other) const { return value == other.value; }$/;" f class:lbool -operator == SolverTypes.h /^ bool operator == (GClause c) const { return data == c.data; }$/;" f class:GClause -operator == SolverTypes.h /^inline bool operator == (Lit p, Lit q) { return index(p) == index(q); }$/;" f -operator > Global.h /^template static inline bool operator > (const T& x, const T& y) { return y < x; }$/;" f -operator >= Global.h /^template static inline bool operator >= (const T& x, const T& y) { return !(x < y); }$/;" f -operator T* Global.h /^ operator T* (void) { return data; } \/\/ (unsafe but convenient)$/;" f class:vec -operator [] Global.h /^ T& operator [] (int index) { return data[index]; }$/;" f class:vec -operator [] Global.h /^ const T& operator [] (int index) const { return data[index]; }$/;" f class:vec -operator [] SolverTypes.h /^ Lit operator [] (int i) const { return data[i]; }$/;" f class:Clause -operator [] SolverTypes.h /^ Lit& operator [] (int i) { return data[i]; }$/;" f class:Clause -operator [] itp.h /^ SITP & operator[]( unsigned i ){ return * (_sitp[i] ); }$/;" f class:MultiSITP -operator const T* Global.h /^ operator const T* (void) const { return data; }$/;" f class:vec -operator ~ Global.h /^ lbool operator ~ (void) const { return lbool(-value); }$/;" f class:lbool -operator ~ SolverTypes.h /^inline Lit operator ~ (Lit p) { Lit q; q.x = p.x ^ 1; return q; }$/;" f -order Solver.h /^ VarOrder order; \/\/ Keeps track of the decision variable order.$/;" m class:Solver -own_fd File.h /^ bool own_fd; \/\/ Do we own the file descriptor? If so, will close file in destructor.$/;" m class:File -parent Heap.h /^static inline int parent(int i) { return i >> 1; }$/;" f -percolateDown Heap.h /^ inline void percolateDown(int i)$/;" f class:Heap -percolateUp Heap.h /^ inline void percolateUp(int i)$/;" f class:Heap -pfGen itp.cpp /^ProofTraverser * ITPMgr::pfGen( Solver & S , StrashCkt & ckt) $/;" f class:ITPMgr -phase itp.h /^ vector< bool > phase;$/;" m struct:Checker -pop Global.h /^ void pop (void) { sz--, data[sz].~T(); }$/;" f class:vec -pos File.h /^ int pos; \/\/ Current position in buffer$/;" m class:File -printInfo sat.h /^ void printInfo() const {$/;" f class:SatSolver -printSolver sat.h /^ void printSolver() const { cout << "MiniSat ver 2.2.0"; }$/;" f class:SatSolver -progressEstimate Solver.cpp /^double Solver::progressEstimate()$/;" f class:Solver -progress_estimate Solver.h /^ double progress_estimate; \/\/ Set by 'search()'.$/;" m class:Solver -proof Solver.h /^ Proof* proof; \/\/ Set this directly after constructing 'Solver' to enable proof logging. Initialized to NULL.$/;" m class:Solver -propagate Solver.cpp /^Clause* Solver::propagate()$/;" f class:Solver -propagate_tmpbin Solver.h /^ Clause* propagate_tmpbin;$/;" m class:Solver -propagations Solver.h /^ int64 starts, decisions, propagations, conflicts;$/;" m struct:SolverStats -push Global.h /^ void push (const T& elem) { if (sz == cap) grow(sz+1); new (&data[sz]) T(elem); sz++; }$/;" f class:vec -push Global.h /^ void push (void) { if (sz == cap) grow(sz+1); new (&data[sz]) T() ; sz++; }$/;" f class:vec -putChar File.h /^ int putChar(int chr) {$/;" f class:File -putCharQ File.h /^ int putCharQ(int chr) { \/\/ Quick version with minimal overhead -- don't call this in the wrong mode!$/;" f class:File -putInt File.h /^static inline void putInt (File& out, int64 val) { putUInt(out, encode64(val)); }$/;" f -putUInt File.cpp /^void putUInt(File& out, uint64 val)$/;" f -qhead Solver.h /^ int qhead; \/\/ Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).$/;" m class:Solver -random_seed VarOrder.h /^ double random_seed; \/\/ For the internal random number generator$/;" m class:VarOrder -random_var_freq Solver.h /^ double var_decay, clause_decay, random_var_freq; \/\/ (reasonable values are: 0.95, 0.999, 0.02) $/;" m struct:SearchParams -reason Solver.h /^ vec reason; \/\/ 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none.$/;" m class:Solver -reduceDB Solver.cpp /^void Solver::reduceDB()$/;" f class:Solver -reduceDB_lt Solver.cpp /^struct reduceDB_lt { bool operator () (Clause* x, Clause* y) { return x->size() > 2 && (y->size() == 2 || x->activity() < y->activity()); } };$/;" s file: -release Global.h /^ T* release (void) { T* ret = data; data = NULL; sz = 0; cap = 0; return ret; }$/;" f class:vec -releaseDescriptor File.h /^ int releaseDescriptor(void) { \/\/ Don't run UNIX function 'close()' on descriptor in 'File's 'close()'.$/;" f class:File -remove Solver.cpp /^void Solver::remove(Clause* c, bool just_dealloc)$/;" f class:Solver -removeWatch Solver.cpp /^void removeWatch(vec& ws, Clause* elem)$/;" f -reportf Solver.h 28;" d -reset sat.h /^ void reset() {$/;" f class:SatSolver -resetSolverData sat.h /^ void resetSolverData() { _assump.clear(); _curVar = 0; }$/;" f class:SatSolver -resolve Proof.cpp /^void Proof::resolve(ClauseId next, Lit x)$/;" f class:Proof -resolve itp.cpp /^AigPtr MITP::resolve(AigPtr p , Lit l , AigPtr q)$/;" f class:MITP -resolve itp.cpp /^AigPtr PITP::resolve(AigPtr p , Lit l , AigPtr q)$/;" f class:PITP -resolve itp.cpp /^void Checker::resolve(vec& main, vec& other, Lit l)$/;" f class:Checker -right Heap.h /^static inline int right (int i) { return i+i + 1; }$/;" f -root itp.cpp /^void Checker::root (const vec& c , bool A) $/;" f class:Checker -root itp.cpp /^void MITP::root( const vec & c , bool A)$/;" f class:MITP -root itp.cpp /^void MultiSITP::root (const vec& c , bool A)$/;" f class:MultiSITP -root itp.cpp /^void PITP::root( const vec & c , bool A)$/;" f class:PITP -root_level Solver.h /^ int root_level; \/\/ Level of first proper decision.$/;" m class:Solver -save Proof.cpp /^bool Proof::save(cchar* filename)$/;" f class:Proof -search Solver.cpp /^lbool Solver::search(int nof_conflicts, int nof_learnts, const SearchParams& params)$/;" f class:Solver -seek File.cpp /^void File::seek(int64 file_pos, int whence)$/;" f class:File -select VarOrder.h /^Var VarOrder::select(double random_var_freq)$/;" f class:VarOrder -selectionSort Sort.h /^template static inline void selectionSort(T* array, int size) {$/;" f -selectionSort Sort.h /^void selectionSort(T* array, int size, LessThan lt)$/;" f -set itp.h /^ void set( unsigned i , SITP * s ){ _sitp[i] = s ;}$/;" f class:MultiSITP -set itp.h /^ void set( bool i ){_inv = i; }$/;" f class:ITP -setBounds Heap.h /^ void setBounds (int size) { assert(size >= 0); indices.growTo(size,0); }$/;" f class:Heap -setMode File.h /^ void setMode(FileMode m) {$/;" f class:File -setVar satTest.cpp /^ void setVar(const Var& v) { _var = v; }$/;" f class:Gate -shrink Global.h /^ void shrink (int nelems) { assert(nelems <= sz); for (int i = 0; i < nelems; i++) sz--, data[sz].~T(); }$/;" f class:vec -sign SolverTypes.h /^inline bool sign (Lit p) { return p.x & 1; }$/;" f -simpDB_assigns Solver.h /^ int simpDB_assigns; \/\/ Number of top-level assignments since last execution of 'simplifyDB()'.$/;" m class:Solver -simpDB_props Solver.h /^ int64 simpDB_props; \/\/ Remaining number of propagations that must be made before next execution of 'simplifyDB()'.$/;" m class:Solver -simplify Solver.cpp /^bool Solver::simplify(Clause* c) const$/;" f class:Solver -simplifyDB Solver.cpp /^void Solver::simplifyDB()$/;" f class:Solver -size File.h /^ int size; \/\/ Size of buffer (at end of file, less than 'File_BufSize').$/;" m class:File -size Global.h /^ int size (void) const { return sz; }$/;" f class:vec -size SolverTypes.h /^ int size () const { return size_learnt >> 1; }$/;" f class:Clause -size itp.cpp /^unsigned SITP::size() $/;" f class:SITP -size_learnt SolverTypes.h /^ uint size_learnt;$/;" m class:Clause -solve Solver.cpp /^bool Solver::solve(const vec& assumps)$/;" f class:Solver -solve Solver.h /^ bool solve() { vec tmp; return solve(tmp); }$/;" f class:Solver -solve sat.h /^ bool solve() { _solver->solve(); return _solver->okay(); }$/;" f class:SatSolver -sort Sort.h /^template void sort(T* array, int size, LessThan lt) {$/;" f -sort Sort.h /^template void sort(vec& v, LessThan lt) {$/;" f -sort Sort.h /^template static inline void sort(T* array, int size) {$/;" f -sort Sort.h /^template void sort(vec& v) {$/;" f -sort Sort.h /^void sort(T* array, int size, LessThan lt, double& seed)$/;" f -sortUnique Sort.h /^template void sortUnique(vec& v, LessThan lt) {$/;" f -sortUnique Sort.h /^template static inline void sortUnique(T* array, int& size) {$/;" f -sortUnique Sort.h /^template void sortUnique(vec& v) {$/;" f -sortUnique Sort.h /^void sortUnique(T* array, int& size, LessThan lt)$/;" f -starts Solver.h /^ int64 starts, decisions, propagations, conflicts;$/;" m struct:SolverStats -stats Solver.h /^ SolverStats stats;$/;" m class:Solver -sz Global.h /^ int sz;$/;" m class:vec -tell File.cpp /^int64 File::tell(void)$/;" f class:File -temp_files Proof.cpp /^static TempFiles temp_files; \/\/ (should be singleton)$/;" v file: -toDimacs SolverTypes.h /^inline int toDimacs(Lit p) { return sign(p) ? -var(p) - 1 : var(p) + 1; }$/;" f -toInt Global.h /^ int toInt(void) const { return value; }$/;" f class:lbool -toInt Global.h /^inline int toInt (lbool l) { return l.toInt(); }$/;" f -toLbool Global.h /^inline lbool toLbool(int v) { return lbool(v); }$/;" f -toLit SolverTypes.h /^inline Lit toLit (int i) { Lit p; p.x = i; return p; } \/\/ Inverse of 'index()'.$/;" f -totGate satTest.cpp /^vector totGate;$/;" v -tot_literals Solver.h /^ int64 clauses_literals, learnts_literals, max_literals, tot_literals;$/;" m struct:SolverStats -trail Solver.h /^ vec trail; \/\/ Assignment stack; stores all assigments made in the order they were made.$/;" m class:Solver -trail_lim Solver.h /^ vec trail_lim; \/\/ Separator indices for different decision levels in 'trail[]'.$/;" m class:Solver -trail_pos Solver.cpp /^ const vec& trail_pos;$/;" m class:lastToFirst_lt file: -trail_pos Solver.h /^ vec trail_pos; \/\/ 'trail_pos[var]' is the variable's position in 'trail[]'. This supersedes 'level[]' in some sense, and 'level[]' will probably be removed in future releases.$/;" m class:Solver -trav Proof.h /^ ProofTraverser* trav;$/;" m class:Proof -traverse Proof.cpp /^void Proof::traverse(ProofTraverser& trav, ClauseId goal)$/;" f class:Proof -traverse itp.cpp /^void Checker::traverse( ProofTraverser & itp )$/;" f class:Checker -uchar Global.h /^typedef unsigned char uchar;$/;" t -uint64 Global.h /^typedef UINT64 uint64;$/;" t -uint64 Global.h /^typedef unsigned long long uint64;$/;" t -uintp Global.h /^typedef UINT_PTR uintp;$/;" t -uintp Global.h /^typedef unsigned __PTRDIFF_TYPE__ uintp;$/;" t -undo VarOrder.h /^void VarOrder::undo(Var x)$/;" f class:VarOrder -unit_id Solver.h /^ vec unit_id; \/\/ 'unit_id[var]' is the clause ID for the unit literal 'var' or '~var' (if set at toplevel).$/;" m class:Solver -unsign SolverTypes.h /^inline Lit unsign(Lit p) { Lit q; q.x = p.x & ~1; return q; }$/;" f -update VarOrder.h /^void VarOrder::update(Var x)$/;" f class:VarOrder -value Global.h /^ int value;$/;" m class:lbool -value Solver.h /^ lbool value(Lit p) const { return sign(p) ? ~toLbool(assigns[var(p)]) : toLbool(assigns[var(p)]); }$/;" f class:Solver -value Solver.h /^ lbool value(Var x) const { return toLbool(assigns[x]); }$/;" f class:Solver -var SolverTypes.h /^inline int var (Lit p) { return p.x >> 1; }$/;" f -varBumpActivity Solver.h /^ void varBumpActivity(Lit p) {$/;" f class:Solver -varDecayActivity Solver.h /^ void varDecayActivity () { if (var_decay >= 0) var_inc *= var_decay; }$/;" f class:Solver -varRescaleActivity Solver.cpp /^void Solver::varRescaleActivity()$/;" f class:Solver -var_Undef SolverTypes.h 37;" d -var_decay Solver.h /^ double var_decay; \/\/ INVERSE decay factor for variable activity: stores 1\/decay. Use negative value for static variable order.$/;" m class:Solver -var_decay Solver.h /^ double var_decay, clause_decay, random_var_freq; \/\/ (reasonable values are: 0.95, 0.999, 0.02) $/;" m struct:SearchParams -var_inc Solver.h /^ double var_inc; \/\/ Amount to bump next variable with.$/;" m class:Solver -vcs itp.h /^ vec< vec< ClauseId > > vcs;$/;" m struct:Checker -vec Global.h /^ vec (vec& other) { TEMPLATE_FAIL; }$/;" f class:vec -vec Global.h /^ vec(T* array, int size) : data(array), sz(size), cap(size) { } \/\/ (takes ownership of array -- will be deallocated with 'xfree()')$/;" f class:vec -vec Global.h /^ vec(int size) : data(NULL) , sz(0) , cap(0) { growTo(size); }$/;" f class:vec -vec Global.h /^ vec(int size, const T& pad) : data(NULL) , sz(0) , cap(0) { growTo(size, pad); }$/;" f class:vec -vec Global.h /^ vec(void) : data(NULL) , sz(0) , cap(0) { }$/;" f class:vec -vec Global.h /^class vec {$/;" c -verbosity Solver.h /^ int verbosity; \/\/ Verbosity level. 0=silent, 1=some progress report, 2=everything$/;" m class:Solver -vxs itp.h /^ vec< vec > vxs;$/;" m struct:Checker -watches Solver.h /^ vec > watches; \/\/ 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).$/;" m class:Solver -x SolverTypes.h /^ int x;$/;" m class:Lit -xfree Global.h /^template static inline void xfree(T *ptr) {$/;" f -xmalloc Global.h /^template static inline T* xmalloc(size_t size) {$/;" f -xrealloc Global.h /^template static inline T* xrealloc(T* ptr, size_t size) {$/;" f -~AigCal itp.h /^ virtual ~AigCal(){};$/;" f class:AigCal -~File File.h /^ ~File(void) {$/;" f class:File -~Gate satTest.cpp /^ ~Gate() {}$/;" f class:Gate -~ITPMgr itp.cpp /^ITPMgr::~ITPMgr()$/;" f class:ITPMgr -~MITP itp.h /^ virtual ~MITP(){}$/;" f class:MITP -~MultiSITP itp.cpp /^MultiSITP::~MultiSITP()$/;" f class:MultiSITP -~PITP itp.h /^ virtual ~PITP(){}$/;" f class:PITP -~ProofTraverser Proof.h /^ virtual ~ProofTraverser(){}$/;" f struct:ProofTraverser -~SITP itp.h /^ virtual ~SITP(){}$/;" f class:SITP -~SMITP itp.h /^ virtual ~SMITP(){}$/;" f class:SMITP -~SPITP itp.h /^ virtual ~SPITP(){}$/;" f class:SPITP -~SatSolver sat.h /^ ~SatSolver() { }$/;" f class:SatSolver -~Solver Solver.h /^ ~Solver() {$/;" f class:Solver -~TempFiles Proof.cpp /^ ~TempFiles()$/;" f class:TempFiles -~vec Global.h /^ ~vec(void) { clear(true); }$/;" f class:vec diff --git a/src/sim/.depend.mak b/src/sim/.depend.mak deleted file mode 100644 index 4299e5d4..00000000 --- a/src/sim/.depend.mak +++ /dev/null @@ -1,34 +0,0 @@ -gvSimCmd.o: gvSimCmd.cpp gvSimCmd.h ../../include/gvCmdMgr.h \ - ../../include/gvAbcMgr.h ../../include/base/abc/abc.h \ - ../../include/misc/vec/vec.h ../../include/misc/util/abc_global.h \ - ../../include/misc/util/abc_namespaces.h ../../include/misc/vec/vecInt.h \ - ../../include/misc/vec/vecFlt.h ../../include/misc/vec/vecStr.h \ - ../../include/misc/vec/vecPtr.h ../../include/misc/vec/vecVec.h \ - ../../include/misc/vec/vecAtt.h ../../include/misc/vec/vecWrd.h \ - ../../include/misc/vec/vecBit.h ../../include/misc/vec/vecMem.h \ - ../../include/misc/vec/vecWec.h ../../include/aig/hop/hop.h \ - ../../include/aig/gia/gia.h ../../include/misc/vec/vecWec.h \ - ../../include/misc/util/utilCex.h ../../include/misc/st/st.h \ - ../../include/misc/st/stmm.h ../../include/misc/nm/nm.h \ - ../../include/misc/mem/mem.h ../../include/misc/extra/extra.h \ - ../../include/base/main/main.h ../../include/base/abc/abc.h \ - ../../include/base/main/abcapis.h ../../include/base/cmd/cmd.h \ - ../../include/base/io/ioAbc.h ../../include/misc/util/utilNam.h \ - ../../include/base/main/mainInt.h ../../include/base/main/main.h \ - ../../include/misc/tim/tim.h ../../include/map/if/if.h \ - ../../include/misc/vec/vecMem.h ../../include/misc/util/utilTruth.h \ - ../../include/opt/dau/dau.h ../../include/misc/vec/vecHash.h \ - ../../include/aig/aig/aig.h ../../include/proof/ssw/ssw.h \ - ../../include/proof/fra/fra.h ../../include/opt/dar/dar.h \ - ../../include/sat/bsat/satSolver.h ../../include/sat/bsat/satVec.h \ - ../../include/sat/bsat/satClause.h ../../include/misc/util/utilDouble.h \ - ../../include/aig/ioa/ioa.h ../../include/gvAbcNtk.h \ - ../../include/gvModMgr.h ../../include/gvCmdMgr.h ../../include/gvMsg.h \ - ../../include/util.h ../../include/rnGen.h ../../include/myUsage.h \ - ../../include/gvNtk.h ../../include/gvAbcMgr.h \ - ../../include/kernel/sigtools.h ../../include/kernel/yosys.h \ - /usr/include/tcl8.6/tcl.h /usr/include/tcl8.6/tclDecls.h \ - /usr/include/tcl8.6/tclPlatDecls.h ../../include/kernel/hashlib.h \ - ../../include/kernel/log.h ../../include/kernel/rtlil.h \ - ../../include/kernel/constids.inc ../../include/kernel/register.h \ - ../../include/kernel/utils.h ../../include/kernel/yosys.h diff --git a/src/sim/.extheader.mak b/src/sim/.extheader.mak deleted file mode 100644 index 133cb45f..00000000 --- a/src/sim/.extheader.mak +++ /dev/null @@ -1,4 +0,0 @@ -sim.d: ../../include/gvSimCmd.h -../../include/gvSimCmd.h: gvSimCmd.h - @rm -f ../../include/gvSimCmd.h - @ln -fs ../src/sim/gvSimCmd.h ../../include/gvSimCmd.h diff --git a/src/sim/Makefile b/src/sim/Makefile deleted file mode 100644 index 361c9780..00000000 --- a/src/sim/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -PKGFLAG = $(DEBUG_FLAG) -EXTHDRS = gvSimCmd.h - -include ../Makefile.in -include ../Makefile.lib \ No newline at end of file diff --git a/src/sim/gvSimCmd.cpp b/src/sim/gvSimCmd.cpp deleted file mode 100644 index d2bf0cda..00000000 --- a/src/sim/gvSimCmd.cpp +++ /dev/null @@ -1,234 +0,0 @@ -#ifndef GV_SIM_CMD_C -#define GV_SIM_CMD_C - -#include "gvSimCmd.h" -#include "gvAbcMgr.h" -#include "gvModMgr.h" -#include "gvMsg.h" -#include "util.h" -#include -#include - -#include "gvNtk.h" -bool -GVinitSimCmd() { - return (gvCmdMgr->regCmd("RAndom Sim", 2, 1, new GVRandomSimCmd) && - gvCmdMgr->regCmd("SEt SAfe", 2, 2, new GVRandomSetSafe) && - gvCmdMgr->regCmd("SHow", 2, new GVShowCmd)); -} - -//---------------------------------------------------------------------- -// RAndom Sim -//---------------------------------------------------------------------- -GVCmdExecStatus -GVRandomSimCmd ::exec(const string& option) { - gvMsg(GV_MSG_IFO) << "I am GVRandomSimCmd " << endl; - vector options; - GVCmdExec::lexOptions(option, options); - size_t n = options.size(); - - string opt, rst = "reset", rst_n = "reset", clk = "clk", in_file_name, - out_file_name, command = "random_sim ", - vcd_file_name = ".waves.vcd"; - string stimulus_file_name, cycles; - - bool verbose = false, rst_set = false, rst_n_set, clk_set = false; - bool out_file_name_set = false, file_name_set = false; - command += - "-top " + yosys_design->top_module()->name.str().substr( - 1, strlen(yosys_design->top_module()->name.c_str()) - 1); - for (size_t i = 0; i < n; ++i) { - const string& token = options[i]; - if (myStrNCmp("-v", token, 1) == 0) { - verbose = true; - command += " -v "; - continue; - } - if (myStrNCmp("-rst", token, 3) == 0) { - rst_set = true; - ++i; - rst = options[i]; - command += " -reset " + rst; - continue; - } - if (myStrNCmp("-rst_n", token, 4) == 0) { - rst_n_set = true; - ++i; - rst_n = options[i]; - command += " -reset_n " + rst_n; - continue; - } - if (myStrNCmp("-clk", token, 1) == 0) { - clk_set = true; - ++i; - clk = options[i]; - command += " -clk " + clk; - continue; - } - if (myStrNCmp("-sim_cycle", token, 1) == 0) { - rst_n_set = true; - ++i; - cycles = options[i]; - command += " -sim_cycle " + cycles; - continue; - } - if (myStrNCmp("-input", token, 1) == 0) { - ++i; - in_file_name = options[i]; - file_name_set = true; - command += " -input " + in_file_name; - continue; - } - if (myStrNCmp("-output", token, 1) == 0) { - ++i; - out_file_name = options[i]; - command += " -output " + out_file_name; - continue; - } - if (myStrNCmp("-file", token, 1) == 0) { - ++i; - stimulus_file_name = options[i]; - command += " -file " + stimulus_file_name; - continue; - } - if (myStrNCmp("-vcd", token, 4) == 0) { - ++i; - vcd_file_name = options[i]; - command += " -vcd " + vcd_file_name; - continue; - } - } - // load the random_sim plugin in yosys - run_pass("plugin -i ./src/ext/sim.so"); - - if (!file_name_set) command += " -input " + gvModMgr->getInputFileName(); - // cout << "safe =========================== " + gvModMgr -> getSafe() << - // endl; - if (gvModMgr->getSafe() != -1) - command += " -safe " + std::to_string((gvModMgr->getSafe())); - - cout << command << "\n"; - // execute "random_sim" command - run_pass(command); - return GV_CMD_EXEC_DONE; -} - -void -GVRandomSimCmd ::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) - << "Usage: RAndom Sim <-input file_name.v> [sim_cycle num_cycle_sim] " - "[-rst rst_name] [-rst_n rst_n_name] [-clk clk_name] " - "[-output out_file_name] [-v verbose print result] [-file stimulus]" - << endl; -} - -void -GVRandomSimCmd ::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "RAndom Sim: " - << "Conduct random simulation and print the results." - << endl; -} - -//---------------------------------------------------------------------- -// RAndom Sim -//---------------------------------------------------------------------- - -GVCmdExecStatus -GVRandomSetSafe::exec(const string& option) { - gvMsg(GV_MSG_IFO) << "I am GVRandomSetSafe " << endl; - - vector options; - GVCmdExec::lexOptions(option, options); - - if (options.size() != 1) { - gvMsg(GV_MSG_IFO) << "Please enter a valid value!" << endl; - return GV_CMD_EXEC_DONE; - } - gvModMgr->setSafe(stoi(options[0])); - return GV_CMD_EXEC_DONE; -} - -void -GVRandomSetSafe::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) << "Usage: SEt SAfe <#PO>" << endl; -} - -void -GVRandomSetSafe::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "SEt SAfe: " - << "Set safe property for random simulation." << endl; -} - -//---------------------------------------------------------------------- -// SHow -//---------------------------------------------------------------------- -GVCmdExecStatus -GVShowCmd::exec(const string& option) { - gvMsg(GV_MSG_IFO) << "I am GVSHowVCDCmd " << endl; - - vector options; - GVCmdExec::lexOptions(option, options); - size_t n = options.size(); - bool inputFile = false, vcd = false, schematic = false; - - string vcd_file_name = ""; - for (size_t i = 0; i < n; ++i) { - const string& token = options[i]; - if (myStrNCmp("-SCHematic", token, 4) == 0) { - if (schematic) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - schematic = true; - continue; - } else if (myStrNCmp("-Vcd", token, 2) == 0) { - if (vcd) return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - vcd = true; - continue; - } else { - if (vcd) vcd_file_name = token; - else if (!vcd) - return GVCmdExec::errorOption(GV_CMD_OPT_EXTRA, token); - continue; - } - } - - if (vcd) { - ifstream infile; - infile.open(vcd_file_name); - if (!infile.is_open()) { - gvMsg(GV_MSG_IFO) << "[ERROR]: Please input the VCD file name !!\n"; - return GV_CMD_EXEC_NOP; - } else run_command("gtkwave " + vcd_file_name + " &"); - - infile.close(); - } else if (schematic) { - // Problem!! --- (2) - if (!gvModMgr->getInputFileExist()) { - gvMsg(GV_MSG_IFO) << "[ERROR]: Please use command \"READ DESIGN\" " - "to read the file first !!\n "; - return GV_CMD_EXEC_NOP; - } - string top_module_name = - gvRTLDesign->getDesign()->top_module()->name.str().substr( - 1, strlen(yosys_design->top_module()->name.c_str()) - 1); - - run_pass("hierarchy -top " + top_module_name); - run_pass("proc"); - run_pass("opt"); - run_pass("show"); - } - - return GV_CMD_EXEC_DONE; -} -void -GVShowCmd::usage(const bool& verbose) const { - gvMsg(GV_MSG_IFO) - << "Usage: SHow < -Vcd | -SCHematic >" << endl; -} - -void -GVShowCmd::help() const { - gvMsg(GV_MSG_IFO) << setw(20) << left << "SHow : " - << "Show the waveform or schematic." << endl; -} - -#endif diff --git a/src/sim/gvSimCmd.h b/src/sim/gvSimCmd.h deleted file mode 100644 index f2834e41..00000000 --- a/src/sim/gvSimCmd.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef GV_SIM_CMD_H -#define GV_SIM_CMD_H - -#include "gvCmdMgr.h" - -GV_COMMAND(GVRandomSimCmd, GV_CMD_TYPE_SIMULATE); -GV_COMMAND(GVRandomSetSafe, GV_CMD_TYPE_SIMULATE); -GV_COMMAND(GVShowCmd, GV_CMD_TYPE_SIMULATE); - -#endif diff --git a/src/sim/json.hpp b/src/sim/json.hpp deleted file mode 100644 index 805efdd7..00000000 --- a/src/sim/json.hpp +++ /dev/null @@ -1,24640 +0,0 @@ -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - -/****************************************************************************\ - * Note on documentation: The source files contain links to the online * - * documentation of the public API at https://json.nlohmann.me. This URL * - * contains the most recent documentation and should also be applicable to * - * previous versions; documentation for deprecated functions is not * - * removed, but marked deprecated. See "Generate documentation" section in * - * file docs/README.md. * -\****************************************************************************/ - -#ifndef INCLUDE_NLOHMANN_JSON_HPP_ -#define INCLUDE_NLOHMANN_JSON_HPP_ - -#include // all_of, find, for_each -#include // nullptr_t, ptrdiff_t, size_t -#include // hash, less -#include // initializer_list -#ifndef JSON_NO_IO - #include // istream, ostream -#endif // JSON_NO_IO -#include // random_access_iterator_tag -#include // unique_ptr -#include // string, stoi, to_string -#include // declval, forward, move, pair, swap -#include // vector - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// This file contains all macro definitions affecting or depending on the ABI - -#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK - #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) - #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 2 - #warning "Already included a different version of the library!" - #endif - #endif -#endif - -#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) -#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum) -#define NLOHMANN_JSON_VERSION_PATCH 2 // NOLINT(modernize-macro-to-enum) - -#ifndef JSON_DIAGNOSTICS - #define JSON_DIAGNOSTICS 0 -#endif - -#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 -#endif - -#if JSON_DIAGNOSTICS - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag -#else - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS -#endif - -#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp -#else - #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION - #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 -#endif - -// Construct the namespace ABI tags component -#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b -#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \ - NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) - -#define NLOHMANN_JSON_ABI_TAGS \ - NLOHMANN_JSON_ABI_TAGS_CONCAT( \ - NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ - NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON) - -// Construct the namespace version component -#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ - _v ## major ## _ ## minor ## _ ## patch -#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ - NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) - -#if NLOHMANN_JSON_NAMESPACE_NO_VERSION -#define NLOHMANN_JSON_NAMESPACE_VERSION -#else -#define NLOHMANN_JSON_NAMESPACE_VERSION \ - NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ - NLOHMANN_JSON_VERSION_MINOR, \ - NLOHMANN_JSON_VERSION_PATCH) -#endif - -// Combine namespace components -#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b -#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ - NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) - -#ifndef NLOHMANN_JSON_NAMESPACE -#define NLOHMANN_JSON_NAMESPACE \ - nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ - NLOHMANN_JSON_ABI_TAGS, \ - NLOHMANN_JSON_NAMESPACE_VERSION) -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN -#define NLOHMANN_JSON_NAMESPACE_BEGIN \ - namespace nlohmann \ - { \ - inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ - NLOHMANN_JSON_ABI_TAGS, \ - NLOHMANN_JSON_NAMESPACE_VERSION) \ - { -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_END -#define NLOHMANN_JSON_NAMESPACE_END \ - } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ - } // namespace nlohmann -#endif - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // transform -#include // array -#include // forward_list -#include // inserter, front_inserter, end -#include // map -#include // string -#include // tuple, make_tuple -#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible -#include // unordered_map -#include // pair, declval -#include // valarray - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // nullptr_t -#include // exception -#if JSON_DIAGNOSTICS - #include // accumulate -#endif -#include // runtime_error -#include // to_string -#include // vector - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // array -#include // size_t -#include // uint8_t -#include // string - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // declval, pair -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -template struct make_void -{ - using type = void; -}; -template using void_t = typename make_void::type; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -// https://en.cppreference.com/w/cpp/experimental/is_detected -struct nonesuch -{ - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - nonesuch(nonesuch const&&) = delete; - void operator=(nonesuch const&) = delete; - void operator=(nonesuch&&) = delete; -}; - -template class Op, - class... Args> -struct detector -{ - using value_t = std::false_type; - using type = Default; -}; - -template class Op, class... Args> -struct detector>, Op, Args...> -{ - using value_t = std::true_type; - using type = Op; -}; - -template class Op, class... Args> -using is_detected = typename detector::value_t; - -template class Op, class... Args> -struct is_detected_lazy : is_detected { }; - -template class Op, class... Args> -using detected_t = typename detector::type; - -template class Op, class... Args> -using detected_or = detector; - -template class Op, class... Args> -using detected_or_t = typename detected_or::type; - -template class Op, class... Args> -using is_detected_exact = std::is_same>; - -template class Op, class... Args> -using is_detected_convertible = - std::is_convertible, To>; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - - -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson -// SPDX-License-Identifier: MIT - -/* Hedley - https://nemequ.github.io/hedley - * Created by Evan Nemerson - */ - -#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) -#if defined(JSON_HEDLEY_VERSION) - #undef JSON_HEDLEY_VERSION -#endif -#define JSON_HEDLEY_VERSION 15 - -#if defined(JSON_HEDLEY_STRINGIFY_EX) - #undef JSON_HEDLEY_STRINGIFY_EX -#endif -#define JSON_HEDLEY_STRINGIFY_EX(x) #x - -#if defined(JSON_HEDLEY_STRINGIFY) - #undef JSON_HEDLEY_STRINGIFY -#endif -#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) - -#if defined(JSON_HEDLEY_CONCAT_EX) - #undef JSON_HEDLEY_CONCAT_EX -#endif -#define JSON_HEDLEY_CONCAT_EX(a,b) a##b - -#if defined(JSON_HEDLEY_CONCAT) - #undef JSON_HEDLEY_CONCAT -#endif -#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) - -#if defined(JSON_HEDLEY_CONCAT3_EX) - #undef JSON_HEDLEY_CONCAT3_EX -#endif -#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c - -#if defined(JSON_HEDLEY_CONCAT3) - #undef JSON_HEDLEY_CONCAT3 -#endif -#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) - -#if defined(JSON_HEDLEY_VERSION_ENCODE) - #undef JSON_HEDLEY_VERSION_ENCODE -#endif -#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) - #undef JSON_HEDLEY_VERSION_DECODE_MAJOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) - #undef JSON_HEDLEY_VERSION_DECODE_MINOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) - #undef JSON_HEDLEY_VERSION_DECODE_REVISION -#endif -#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) - -#if defined(JSON_HEDLEY_GNUC_VERSION) - #undef JSON_HEDLEY_GNUC_VERSION -#endif -#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#elif defined(__GNUC__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) -#endif - -#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) - #undef JSON_HEDLEY_GNUC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GNUC_VERSION) - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION) - #undef JSON_HEDLEY_MSVC_VERSION -#endif -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) -#elif defined(_MSC_FULL_VER) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) -#elif defined(_MSC_VER) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) - #undef JSON_HEDLEY_MSVC_VERSION_CHECK -#endif -#if !defined(JSON_HEDLEY_MSVC_VERSION) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) -#elif defined(_MSC_VER) && (_MSC_VER >= 1200) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) -#else - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION) - #undef JSON_HEDLEY_INTEL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) -#elif defined(__INTEL_COMPILER) && !defined(__ICL) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_VERSION) - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) - #undef JSON_HEDLEY_INTEL_CL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) - #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) - #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION) - #undef JSON_HEDLEY_PGI_VERSION -#endif -#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) - #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) - #undef JSON_HEDLEY_PGI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PGI_VERSION) - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #undef JSON_HEDLEY_SUNPRO_VERSION -#endif -#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) -#elif defined(__SUNPRO_C) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) -#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) -#elif defined(__SUNPRO_CC) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) - #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION -#endif -#if defined(__EMSCRIPTEN__) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION) - #undef JSON_HEDLEY_ARM_VERSION -#endif -#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) -#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) - #undef JSON_HEDLEY_ARM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_ARM_VERSION) - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION) - #undef JSON_HEDLEY_IBM_VERSION -#endif -#if defined(__ibmxl__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) -#elif defined(__xlC__) && defined(__xlC_ver__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) -#elif defined(__xlC__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) - #undef JSON_HEDLEY_IBM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IBM_VERSION) - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_VERSION) - #undef JSON_HEDLEY_TI_VERSION -#endif -#if \ - defined(__TI_COMPILER_VERSION__) && \ - ( \ - defined(__TMS470__) || defined(__TI_ARM__) || \ - defined(__MSP430__) || \ - defined(__TMS320C2000__) \ - ) -#if (__TI_COMPILER_VERSION__ >= 16000000) - #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif -#endif - -#if defined(JSON_HEDLEY_TI_VERSION_CHECK) - #undef JSON_HEDLEY_TI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_VERSION) - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #undef JSON_HEDLEY_TI_CL2000_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) - #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #undef JSON_HEDLEY_TI_CL430_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) - #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #undef JSON_HEDLEY_TI_ARMCL_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) - #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) - #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #undef JSON_HEDLEY_TI_CL6X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) - #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #undef JSON_HEDLEY_TI_CL7X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) - #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #undef JSON_HEDLEY_TI_CLPRU_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) - #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION) - #undef JSON_HEDLEY_CRAY_VERSION -#endif -#if defined(_CRAYC) - #if defined(_RELEASE_PATCHLEVEL) - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) - #else - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) - #undef JSON_HEDLEY_CRAY_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_CRAY_VERSION) - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION) - #undef JSON_HEDLEY_IAR_VERSION -#endif -#if defined(__IAR_SYSTEMS_ICC__) - #if __VER__ > 1000 - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) - #else - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) - #undef JSON_HEDLEY_IAR_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IAR_VERSION) - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION) - #undef JSON_HEDLEY_TINYC_VERSION -#endif -#if defined(__TINYC__) - #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) - #undef JSON_HEDLEY_TINYC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION) - #undef JSON_HEDLEY_DMC_VERSION -#endif -#if defined(__DMC__) - #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) - #undef JSON_HEDLEY_DMC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_DMC_VERSION) - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #undef JSON_HEDLEY_COMPCERT_VERSION -#endif -#if defined(__COMPCERT_VERSION__) - #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) - #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION) - #undef JSON_HEDLEY_PELLES_VERSION -#endif -#if defined(__POCC__) - #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) - #undef JSON_HEDLEY_PELLES_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PELLES_VERSION) - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) - #undef JSON_HEDLEY_MCST_LCC_VERSION -#endif -#if defined(__LCC__) && defined(__LCC_MINOR__) - #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) - #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) - #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION) - #undef JSON_HEDLEY_GCC_VERSION -#endif -#if \ - defined(JSON_HEDLEY_GNUC_VERSION) && \ - !defined(__clang__) && \ - !defined(JSON_HEDLEY_INTEL_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_ARM_VERSION) && \ - !defined(JSON_HEDLEY_CRAY_VERSION) && \ - !defined(JSON_HEDLEY_TI_VERSION) && \ - !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ - !defined(__COMPCERT__) && \ - !defined(JSON_HEDLEY_MCST_LCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_ATTRIBUTE -#endif -#if \ - defined(__has_attribute) && \ - ( \ - (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ - ) -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) -#else -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE -#endif -#if \ - defined(__has_cpp_attribute) && \ - defined(__cplusplus) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS -#endif -#if !defined(__cplusplus) || !defined(__has_cpp_attribute) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#elif \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ - (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_BUILTIN) - #undef JSON_HEDLEY_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) -#else - #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) - #undef JSON_HEDLEY_GNUC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) - #undef JSON_HEDLEY_GCC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_FEATURE) - #undef JSON_HEDLEY_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) -#else - #define JSON_HEDLEY_HAS_FEATURE(feature) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) - #undef JSON_HEDLEY_GNUC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) - #undef JSON_HEDLEY_GCC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_EXTENSION) - #undef JSON_HEDLEY_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) -#else - #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) - #undef JSON_HEDLEY_GNUC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) - #undef JSON_HEDLEY_GCC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_WARNING) - #undef JSON_HEDLEY_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) -#else - #define JSON_HEDLEY_HAS_WARNING(warning) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) - #undef JSON_HEDLEY_GNUC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_WARNING) - #undef JSON_HEDLEY_GCC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - defined(__clang__) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) - #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_PRAGMA(value) __pragma(value) -#else - #define JSON_HEDLEY_PRAGMA(value) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) - #undef JSON_HEDLEY_DIAGNOSTIC_PUSH -#endif -#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) - #undef JSON_HEDLEY_DIAGNOSTIC_POP -#endif -#if defined(__clang__) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) - #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) -#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_PUSH - #define JSON_HEDLEY_DIAGNOSTIC_POP -#endif - -/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") -# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") -# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# endif -#endif -#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x -#endif - -#if defined(JSON_HEDLEY_CONST_CAST) - #undef JSON_HEDLEY_CONST_CAST -#endif -#if defined(__cplusplus) -# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) -#elif \ - JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_REINTERPRET_CAST) - #undef JSON_HEDLEY_REINTERPRET_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) -#else - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_STATIC_CAST) - #undef JSON_HEDLEY_STATIC_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) -#else - #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_CPP_CAST) - #undef JSON_HEDLEY_CPP_CAST -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ - ((T) (expr)) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("diag_suppress=Pe137") \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) -# endif -#else -# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif - -#if defined(JSON_HEDLEY_DEPRECATED) - #undef JSON_HEDLEY_DEPRECATED -#endif -#if defined(JSON_HEDLEY_DEPRECATED_FOR) - #undef JSON_HEDLEY_DEPRECATED_FOR -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) -#elif \ - (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) -#elif defined(__cplusplus) && (__cplusplus >= 201402L) - #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") -#else - #define JSON_HEDLEY_DEPRECATED(since) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) -#endif - -#if defined(JSON_HEDLEY_UNAVAILABLE) - #undef JSON_HEDLEY_UNAVAILABLE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) -#else - #define JSON_HEDLEY_UNAVAILABLE(available_since) -#endif - -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT -#endif -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) -#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) -#elif defined(_Check_return_) /* SAL */ - #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ -#else - #define JSON_HEDLEY_WARN_UNUSED_RESULT - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) -#endif - -#if defined(JSON_HEDLEY_SENTINEL) - #undef JSON_HEDLEY_SENTINEL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) -#else - #define JSON_HEDLEY_SENTINEL(position) -#endif - -#if defined(JSON_HEDLEY_NO_RETURN) - #undef JSON_HEDLEY_NO_RETURN -#endif -#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NO_RETURN __noreturn -#elif \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L - #define JSON_HEDLEY_NO_RETURN _Noreturn -#elif defined(__cplusplus) && (__cplusplus >= 201103L) - #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#else - #define JSON_HEDLEY_NO_RETURN -#endif - -#if defined(JSON_HEDLEY_NO_ESCAPE) - #undef JSON_HEDLEY_NO_ESCAPE -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) - #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) -#else - #define JSON_HEDLEY_NO_ESCAPE -#endif - -#if defined(JSON_HEDLEY_UNREACHABLE) - #undef JSON_HEDLEY_UNREACHABLE -#endif -#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) - #undef JSON_HEDLEY_UNREACHABLE_RETURN -#endif -#if defined(JSON_HEDLEY_ASSUME) - #undef JSON_HEDLEY_ASSUME -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_ASSUME(expr) __assume(expr) -#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) - #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) -#elif \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #if defined(__cplusplus) - #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) - #else - #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) - #endif -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() -#elif defined(JSON_HEDLEY_ASSUME) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif -#if !defined(JSON_HEDLEY_ASSUME) - #if defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) - #else - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) - #endif -#endif -#if defined(JSON_HEDLEY_UNREACHABLE) - #if \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) - #else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() - #endif -#else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) -#endif -#if !defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif - -JSON_HEDLEY_DIAGNOSTIC_PUSH -#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") - #pragma clang diagnostic ignored "-Wpedantic" -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) - #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -#endif -#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) - #if defined(__clang__) - #pragma clang diagnostic ignored "-Wvariadic-macros" - #elif defined(JSON_HEDLEY_GCC_VERSION) - #pragma GCC diagnostic ignored "-Wvariadic-macros" - #endif -#endif -#if defined(JSON_HEDLEY_NON_NULL) - #undef JSON_HEDLEY_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) -#else - #define JSON_HEDLEY_NON_NULL(...) -#endif -JSON_HEDLEY_DIAGNOSTIC_POP - -#if defined(JSON_HEDLEY_PRINTF_FORMAT) - #undef JSON_HEDLEY_PRINTF_FORMAT -#endif -#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) -#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) -#else - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) -#endif - -#if defined(JSON_HEDLEY_CONSTEXPR) - #undef JSON_HEDLEY_CONSTEXPR -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) - #endif -#endif -#if !defined(JSON_HEDLEY_CONSTEXPR) - #define JSON_HEDLEY_CONSTEXPR -#endif - -#if defined(JSON_HEDLEY_PREDICT) - #undef JSON_HEDLEY_PREDICT -#endif -#if defined(JSON_HEDLEY_LIKELY) - #undef JSON_HEDLEY_LIKELY -#endif -#if defined(JSON_HEDLEY_UNLIKELY) - #undef JSON_HEDLEY_UNLIKELY -#endif -#if defined(JSON_HEDLEY_UNPREDICTABLE) - #undef JSON_HEDLEY_UNPREDICTABLE -#endif -#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) - #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) -#elif \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ - (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ - })) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ - })) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) -#else -# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) -# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) -#endif -#if !defined(JSON_HEDLEY_UNPREDICTABLE) - #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) -#endif - -#if defined(JSON_HEDLEY_MALLOC) - #undef JSON_HEDLEY_MALLOC -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_MALLOC __declspec(restrict) -#else - #define JSON_HEDLEY_MALLOC -#endif - -#if defined(JSON_HEDLEY_PURE) - #undef JSON_HEDLEY_PURE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PURE __attribute__((__pure__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) -# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ - ) -# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") -#else -# define JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_CONST) - #undef JSON_HEDLEY_CONST -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_CONST __attribute__((__const__)) -#elif \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_CONST _Pragma("no_side_effect") -#else - #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_RESTRICT) - #undef JSON_HEDLEY_RESTRICT -#endif -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT restrict -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - defined(__clang__) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_RESTRICT __restrict -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT _Restrict -#else - #define JSON_HEDLEY_RESTRICT -#endif - -#if defined(JSON_HEDLEY_INLINE) - #undef JSON_HEDLEY_INLINE -#endif -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - (defined(__cplusplus) && (__cplusplus >= 199711L)) - #define JSON_HEDLEY_INLINE inline -#elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) - #define JSON_HEDLEY_INLINE __inline__ -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_INLINE __inline -#else - #define JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_ALWAYS_INLINE) - #undef JSON_HEDLEY_ALWAYS_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) -# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_ALWAYS_INLINE __forceinline -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ - ) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") -#else -# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_NEVER_INLINE) - #undef JSON_HEDLEY_NEVER_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#else - #define JSON_HEDLEY_NEVER_INLINE -#endif - -#if defined(JSON_HEDLEY_PRIVATE) - #undef JSON_HEDLEY_PRIVATE -#endif -#if defined(JSON_HEDLEY_PUBLIC) - #undef JSON_HEDLEY_PUBLIC -#endif -#if defined(JSON_HEDLEY_IMPORT) - #undef JSON_HEDLEY_IMPORT -#endif -#if defined(_WIN32) || defined(__CYGWIN__) -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC __declspec(dllexport) -# define JSON_HEDLEY_IMPORT __declspec(dllimport) -#else -# if \ - JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - ( \ - defined(__TI_EABI__) && \ - ( \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ - ) \ - ) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) -# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) -# else -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC -# endif -# define JSON_HEDLEY_IMPORT extern -#endif - -#if defined(JSON_HEDLEY_NO_THROW) - #undef JSON_HEDLEY_NO_THROW -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NO_THROW __declspec(nothrow) -#else - #define JSON_HEDLEY_NO_THROW -#endif - -#if defined(JSON_HEDLEY_FALL_THROUGH) - #undef JSON_HEDLEY_FALL_THROUGH -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) -#elif defined(__fallthrough) /* SAL */ - #define JSON_HEDLEY_FALL_THROUGH __fallthrough -#else - #define JSON_HEDLEY_FALL_THROUGH -#endif - -#if defined(JSON_HEDLEY_RETURNS_NON_NULL) - #undef JSON_HEDLEY_RETURNS_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) -#elif defined(_Ret_notnull_) /* SAL */ - #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ -#else - #define JSON_HEDLEY_RETURNS_NON_NULL -#endif - -#if defined(JSON_HEDLEY_ARRAY_PARAM) - #undef JSON_HEDLEY_ARRAY_PARAM -#endif -#if \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(__STDC_NO_VLA__) && \ - !defined(__cplusplus) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_ARRAY_PARAM(name) (name) -#else - #define JSON_HEDLEY_ARRAY_PARAM(name) -#endif - -#if defined(JSON_HEDLEY_IS_CONSTANT) - #undef JSON_HEDLEY_IS_CONSTANT -#endif -#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) - #undef JSON_HEDLEY_REQUIRE_CONSTEXPR -#endif -/* JSON_HEDLEY_IS_CONSTEXPR_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #undef JSON_HEDLEY_IS_CONSTEXPR_ -#endif -#if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) -#endif -#if !defined(__cplusplus) -# if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) -#else - #include - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) -#endif -# elif \ - ( \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ - !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION)) || \ - (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) -#else - #include - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) -#endif -# elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - defined(JSON_HEDLEY_INTEL_VERSION) || \ - defined(JSON_HEDLEY_TINYC_VERSION) || \ - defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ - defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ - defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ - defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ - defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ - defined(__clang__) -# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ - sizeof(void) != \ - sizeof(*( \ - 1 ? \ - ((void*) ((expr) * 0L) ) : \ -((struct { char v[sizeof(void) * 2]; } *) 1) \ - ) \ - ) \ - ) -# endif -#endif -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) -#else - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) (0) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) -#endif - -#if defined(JSON_HEDLEY_BEGIN_C_DECLS) - #undef JSON_HEDLEY_BEGIN_C_DECLS -#endif -#if defined(JSON_HEDLEY_END_C_DECLS) - #undef JSON_HEDLEY_END_C_DECLS -#endif -#if defined(JSON_HEDLEY_C_DECL) - #undef JSON_HEDLEY_C_DECL -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { - #define JSON_HEDLEY_END_C_DECLS } - #define JSON_HEDLEY_C_DECL extern "C" -#else - #define JSON_HEDLEY_BEGIN_C_DECLS - #define JSON_HEDLEY_END_C_DECLS - #define JSON_HEDLEY_C_DECL -#endif - -#if defined(JSON_HEDLEY_STATIC_ASSERT) - #undef JSON_HEDLEY_STATIC_ASSERT -#endif -#if \ - !defined(__cplusplus) && ( \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ - (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - defined(_Static_assert) \ - ) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) -#elif \ - (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) -#else -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) -#endif - -#if defined(JSON_HEDLEY_NULL) - #undef JSON_HEDLEY_NULL -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) - #elif defined(NULL) - #define JSON_HEDLEY_NULL NULL - #else - #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) - #endif -#elif defined(NULL) - #define JSON_HEDLEY_NULL NULL -#else - #define JSON_HEDLEY_NULL ((void*) 0) -#endif - -#if defined(JSON_HEDLEY_MESSAGE) - #undef JSON_HEDLEY_MESSAGE -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_MESSAGE(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(message msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) -#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_WARNING) - #undef JSON_HEDLEY_WARNING -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_WARNING(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(clang warning msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_REQUIRE) - #undef JSON_HEDLEY_REQUIRE -#endif -#if defined(JSON_HEDLEY_REQUIRE_MSG) - #undef JSON_HEDLEY_REQUIRE_MSG -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) -# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") -# define JSON_HEDLEY_REQUIRE(expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), #expr, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), msg, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) -# endif -#else -# define JSON_HEDLEY_REQUIRE(expr) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) -#endif - -#if defined(JSON_HEDLEY_FLAGS) - #undef JSON_HEDLEY_FLAGS -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) - #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) -#else - #define JSON_HEDLEY_FLAGS -#endif - -#if defined(JSON_HEDLEY_FLAGS_CAST) - #undef JSON_HEDLEY_FLAGS_CAST -#endif -#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) -# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("warning(disable:188)") \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) -#endif - -#if defined(JSON_HEDLEY_EMPTY_BASES) - #undef JSON_HEDLEY_EMPTY_BASES -#endif -#if \ - (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) -#else - #define JSON_HEDLEY_EMPTY_BASES -#endif - -/* Remaining macros are deprecated. */ - -#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK -#endif -#if defined(__clang__) - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) -#else - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) - #undef JSON_HEDLEY_CLANG_HAS_BUILTIN -#endif -#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) - -#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) - #undef JSON_HEDLEY_CLANG_HAS_FEATURE -#endif -#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) - -#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) - #undef JSON_HEDLEY_CLANG_HAS_EXTENSION -#endif -#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) - -#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) - #undef JSON_HEDLEY_CLANG_HAS_WARNING -#endif -#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) - -#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ - - -// This file contains all internal macro definitions (except those affecting ABI) -// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them - -// #include - - -// exclude unsupported compilers -#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) - #if defined(__clang__) - #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 - #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) - #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 - #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #endif -#endif - -// C++ language standard detection -// if the user manually specified the used c++ version this is skipped -#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) - #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) - #define JSON_HAS_CPP_20 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) - #define JSON_HAS_CPP_14 - #endif - // the cpp 11 flag is always specified because it is the minimal required version - #define JSON_HAS_CPP_11 -#endif - -#ifdef __has_include - #if __has_include() - #include - #endif -#endif - -#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) - #ifdef JSON_HAS_CPP_17 - #if defined(__cpp_lib_filesystem) - #define JSON_HAS_FILESYSTEM 1 - #elif defined(__cpp_lib_experimental_filesystem) - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 - #elif !defined(__has_include) - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 - #elif __has_include() - #define JSON_HAS_FILESYSTEM 1 - #elif __has_include() - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 - #endif - - // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ - #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support - #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support - #if defined(__clang_major__) && __clang_major__ < 7 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support - #if defined(_MSC_VER) && _MSC_VER < 1914 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before iOS 13 - #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before macOS Catalina - #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - #endif -#endif - -#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 -#endif - -#ifndef JSON_HAS_FILESYSTEM - #define JSON_HAS_FILESYSTEM 0 -#endif - -#ifndef JSON_HAS_THREE_WAY_COMPARISON - #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ - && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L - #define JSON_HAS_THREE_WAY_COMPARISON 1 - #else - #define JSON_HAS_THREE_WAY_COMPARISON 0 - #endif -#endif - -#ifndef JSON_HAS_RANGES - // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error - #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 - #define JSON_HAS_RANGES 0 - #elif defined(__cpp_lib_ranges) - #define JSON_HAS_RANGES 1 - #else - #define JSON_HAS_RANGES 0 - #endif -#endif - -#ifdef JSON_HAS_CPP_17 - #define JSON_INLINE_VARIABLE inline -#else - #define JSON_INLINE_VARIABLE -#endif - -#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) - #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] -#else - #define JSON_NO_UNIQUE_ADDRESS -#endif - -// disable documentation warnings on clang -#if defined(__clang__) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdocumentation" - #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" -#endif - -// allow disabling exceptions -#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) - #define JSON_THROW(exception) throw exception - #define JSON_TRY try - #define JSON_CATCH(exception) catch(exception) - #define JSON_INTERNAL_CATCH(exception) catch(exception) -#else - #include - #define JSON_THROW(exception) std::abort() - #define JSON_TRY if(true) - #define JSON_CATCH(exception) if(false) - #define JSON_INTERNAL_CATCH(exception) if(false) -#endif - -// override exception macros -#if defined(JSON_THROW_USER) - #undef JSON_THROW - #define JSON_THROW JSON_THROW_USER -#endif -#if defined(JSON_TRY_USER) - #undef JSON_TRY - #define JSON_TRY JSON_TRY_USER -#endif -#if defined(JSON_CATCH_USER) - #undef JSON_CATCH - #define JSON_CATCH JSON_CATCH_USER - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_CATCH_USER -#endif -#if defined(JSON_INTERNAL_CATCH_USER) - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER -#endif - -// allow overriding assert -#if !defined(JSON_ASSERT) - #include // assert - #define JSON_ASSERT(x) assert(x) -#endif - -// allow to access some private functions (needed by the test suite) -#if defined(JSON_TESTS_PRIVATE) - #define JSON_PRIVATE_UNLESS_TESTED public -#else - #define JSON_PRIVATE_UNLESS_TESTED private -#endif - -/*! -@brief macro to briefly define a mapping between an enum and JSON -@def NLOHMANN_JSON_SERIALIZE_ENUM -@since version 3.4.0 -*/ -#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ - template \ - inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [e](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.first == e; \ - }); \ - j = ((it != std::end(m)) ? it : std::begin(m))->second; \ - } \ - template \ - inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [&j](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.second == j; \ - }); \ - e = ((it != std::end(m)) ? it : std::begin(m))->first; \ - } - -// Ugly macros to avoid uglier copy-paste when specializing basic_json. They -// may be removed in the future once the class is split. - -#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ - template class ObjectType, \ - template class ArrayType, \ - class StringType, class BooleanType, class NumberIntegerType, \ - class NumberUnsignedType, class NumberFloatType, \ - template class AllocatorType, \ - template class JSONSerializer, \ - class BinaryType, \ - class CustomBaseClass> - -#define NLOHMANN_BASIC_JSON_TPL \ - basic_json - -// Macros to simplify conversion from/to types - -#define NLOHMANN_JSON_EXPAND( x ) x -#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME -#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ - NLOHMANN_JSON_PASTE64, \ - NLOHMANN_JSON_PASTE63, \ - NLOHMANN_JSON_PASTE62, \ - NLOHMANN_JSON_PASTE61, \ - NLOHMANN_JSON_PASTE60, \ - NLOHMANN_JSON_PASTE59, \ - NLOHMANN_JSON_PASTE58, \ - NLOHMANN_JSON_PASTE57, \ - NLOHMANN_JSON_PASTE56, \ - NLOHMANN_JSON_PASTE55, \ - NLOHMANN_JSON_PASTE54, \ - NLOHMANN_JSON_PASTE53, \ - NLOHMANN_JSON_PASTE52, \ - NLOHMANN_JSON_PASTE51, \ - NLOHMANN_JSON_PASTE50, \ - NLOHMANN_JSON_PASTE49, \ - NLOHMANN_JSON_PASTE48, \ - NLOHMANN_JSON_PASTE47, \ - NLOHMANN_JSON_PASTE46, \ - NLOHMANN_JSON_PASTE45, \ - NLOHMANN_JSON_PASTE44, \ - NLOHMANN_JSON_PASTE43, \ - NLOHMANN_JSON_PASTE42, \ - NLOHMANN_JSON_PASTE41, \ - NLOHMANN_JSON_PASTE40, \ - NLOHMANN_JSON_PASTE39, \ - NLOHMANN_JSON_PASTE38, \ - NLOHMANN_JSON_PASTE37, \ - NLOHMANN_JSON_PASTE36, \ - NLOHMANN_JSON_PASTE35, \ - NLOHMANN_JSON_PASTE34, \ - NLOHMANN_JSON_PASTE33, \ - NLOHMANN_JSON_PASTE32, \ - NLOHMANN_JSON_PASTE31, \ - NLOHMANN_JSON_PASTE30, \ - NLOHMANN_JSON_PASTE29, \ - NLOHMANN_JSON_PASTE28, \ - NLOHMANN_JSON_PASTE27, \ - NLOHMANN_JSON_PASTE26, \ - NLOHMANN_JSON_PASTE25, \ - NLOHMANN_JSON_PASTE24, \ - NLOHMANN_JSON_PASTE23, \ - NLOHMANN_JSON_PASTE22, \ - NLOHMANN_JSON_PASTE21, \ - NLOHMANN_JSON_PASTE20, \ - NLOHMANN_JSON_PASTE19, \ - NLOHMANN_JSON_PASTE18, \ - NLOHMANN_JSON_PASTE17, \ - NLOHMANN_JSON_PASTE16, \ - NLOHMANN_JSON_PASTE15, \ - NLOHMANN_JSON_PASTE14, \ - NLOHMANN_JSON_PASTE13, \ - NLOHMANN_JSON_PASTE12, \ - NLOHMANN_JSON_PASTE11, \ - NLOHMANN_JSON_PASTE10, \ - NLOHMANN_JSON_PASTE9, \ - NLOHMANN_JSON_PASTE8, \ - NLOHMANN_JSON_PASTE7, \ - NLOHMANN_JSON_PASTE6, \ - NLOHMANN_JSON_PASTE5, \ - NLOHMANN_JSON_PASTE4, \ - NLOHMANN_JSON_PASTE3, \ - NLOHMANN_JSON_PASTE2, \ - NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) -#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) -#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) -#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) -#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) -#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) -#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) -#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) -#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) -#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) -#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) -#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) -#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) -#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) -#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) -#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) -#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) -#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) -#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) -#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) -#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) -#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) -#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) -#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) -#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) -#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) -#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) -#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) -#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) -#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) -#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) -#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) -#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) -#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) -#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) -#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) -#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) -#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) -#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) -#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) -#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) -#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) -#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) -#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) -#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) -#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) -#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) -#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) -#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) -#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) -#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) -#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) -#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) -#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) -#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) -#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) -#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) -#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) -#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) - -#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; -#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); -#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1); - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } - - -// inspired from https://stackoverflow.com/a/26745591 -// allows to call any std function as if (e.g. with begin): -// using std::begin; begin(x); -// -// it allows using the detected idiom to retrieve the return type -// of such an expression -#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ - namespace detail { \ - using std::std_name; \ - \ - template \ - using result_of_##std_name = decltype(std_name(std::declval()...)); \ - } \ - \ - namespace detail2 { \ - struct std_name##_tag \ - { \ - }; \ - \ - template \ - std_name##_tag std_name(T&&...); \ - \ - template \ - using result_of_##std_name = decltype(std_name(std::declval()...)); \ - \ - template \ - struct would_call_std_##std_name \ - { \ - static constexpr auto const value = ::nlohmann::detail:: \ - is_detected_exact::value; \ - }; \ - } /* namespace detail2 */ \ - \ - template \ - struct would_call_std_##std_name : detail2::would_call_std_##std_name \ - { \ - } - -#ifndef JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_USE_IMPLICIT_CONVERSIONS 1 -#endif - -#if JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_EXPLICIT -#else - #define JSON_EXPLICIT explicit -#endif - -#ifndef JSON_DISABLE_ENUM_SERIALIZATION - #define JSON_DISABLE_ENUM_SERIALIZATION 0 -#endif - -#ifndef JSON_USE_GLOBAL_UDLS - #define JSON_USE_GLOBAL_UDLS 1 -#endif - -#if JSON_HAS_THREE_WAY_COMPARISON - #include // partial_ordering -#endif - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -/////////////////////////// -// JSON type enumeration // -/////////////////////////// - -/*! -@brief the JSON type enumeration - -This enumeration collects the different JSON types. It is internally used to -distinguish the stored values, and the functions @ref basic_json::is_null(), -@ref basic_json::is_object(), @ref basic_json::is_array(), -@ref basic_json::is_string(), @ref basic_json::is_boolean(), -@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), -@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), -@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and -@ref basic_json::is_structured() rely on it. - -@note There are three enumeration entries (number_integer, number_unsigned, and -number_float), because the library distinguishes these three types for numbers: -@ref basic_json::number_unsigned_t is used for unsigned integers, -@ref basic_json::number_integer_t is used for signed integers, and -@ref basic_json::number_float_t is used for floating-point numbers or to -approximate integers which do not fit in the limits of their respective type. - -@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON -value with the default value for a given type - -@since version 1.0.0 -*/ -enum class value_t : std::uint8_t -{ - null, ///< null value - object, ///< object (unordered set of name/value pairs) - array, ///< array (ordered collection of values) - string, ///< string value - boolean, ///< boolean value - number_integer, ///< number value (signed integer) - number_unsigned, ///< number value (unsigned integer) - number_float, ///< number value (floating-point) - binary, ///< binary array (ordered collection of bytes) - discarded ///< discarded by the parser callback function -}; - -/*! -@brief comparison operator for JSON types - -Returns an ordering that is similar to Python: -- order: null < boolean < number < object < array < string < binary -- furthermore, each type is not smaller than itself -- discarded values are not comparable -- binary is represented as a b"" string in python and directly comparable to a - string; however, making a binary array directly comparable with a string would - be surprising behavior in a JSON file. - -@since version 1.0.0 -*/ -#if JSON_HAS_THREE_WAY_COMPARISON - inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD* -#else - inline bool operator<(const value_t lhs, const value_t rhs) noexcept -#endif -{ - static constexpr std::array order = {{ - 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, - 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, - 6 /* binary */ - } - }; - - const auto l_index = static_cast(lhs); - const auto r_index = static_cast(rhs); -#if JSON_HAS_THREE_WAY_COMPARISON - if (l_index < order.size() && r_index < order.size()) - { - return order[l_index] <=> order[r_index]; // *NOPAD* - } - return std::partial_ordering::unordered; -#else - return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; -#endif -} - -// GCC selects the built-in operator< over an operator rewritten from -// a user-defined spaceship operator -// Clang, MSVC, and ICC select the rewritten candidate -// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200) -#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) -inline bool operator<(const value_t lhs, const value_t rhs) noexcept -{ - return std::is_lt(lhs <=> rhs); // *NOPAD* -} -#endif - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -/*! -@brief replace all occurrences of a substring by another string - -@param[in,out] s the string to manipulate; changed so that all - occurrences of @a f are replaced with @a t -@param[in] f the substring to replace with @a t -@param[in] t the string to replace @a f - -@pre The search string @a f must not be empty. **This precondition is -enforced with an assertion.** - -@since version 2.0.0 -*/ -template -inline void replace_substring(StringType& s, const StringType& f, - const StringType& t) -{ - JSON_ASSERT(!f.empty()); - for (auto pos = s.find(f); // find first occurrence of f - pos != StringType::npos; // make sure f was found - s.replace(pos, f.size(), t), // replace with t, and - pos = s.find(f, pos + t.size())) // find next occurrence of f - {} -} - -/*! - * @brief string escaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to escape - * @return escaped string - * - * Note the order of escaping "~" to "~0" and "/" to "~1" is important. - */ -template -inline StringType escape(StringType s) -{ - replace_substring(s, StringType{"~"}, StringType{"~0"}); - replace_substring(s, StringType{"/"}, StringType{"~1"}); - return s; -} - -/*! - * @brief string unescaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to unescape - * @return unescaped string - * - * Note the order of escaping "~1" to "/" and "~0" to "~" is important. - */ -template -static void unescape(StringType& s) -{ - replace_substring(s, StringType{"~1"}, StringType{"/"}); - replace_substring(s, StringType{"~0"}, StringType{"~"}); -} - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // size_t - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -/// struct to capture the start position of the current token -struct position_t -{ - /// the total number of characters read - std::size_t chars_read_total = 0; - /// the number of characters read in the current line - std::size_t chars_read_current_line = 0; - /// the number of lines read - std::size_t lines_read = 0; - - /// conversion to size_t to preserve SAX interface - constexpr operator size_t() const - { - return chars_read_total; - } -}; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-FileCopyrightText: 2018 The Abseil Authors -// SPDX-License-Identifier: MIT - - - -#include // array -#include // size_t -#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type -#include // index_sequence, make_index_sequence, index_sequence_for - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -template -using uncvref_t = typename std::remove_cv::type>::type; - -#ifdef JSON_HAS_CPP_14 - -// the following utilities are natively available in C++14 -using std::enable_if_t; -using std::index_sequence; -using std::make_index_sequence; -using std::index_sequence_for; - -#else - -// alias templates to reduce boilerplate -template -using enable_if_t = typename std::enable_if::type; - -// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h -// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. - -//// START OF CODE FROM GOOGLE ABSEIL - -// integer_sequence -// -// Class template representing a compile-time integer sequence. An instantiation -// of `integer_sequence` has a sequence of integers encoded in its -// type through its template arguments (which is a common need when -// working with C++11 variadic templates). `absl::integer_sequence` is designed -// to be a drop-in replacement for C++14's `std::integer_sequence`. -// -// Example: -// -// template< class T, T... Ints > -// void user_function(integer_sequence); -// -// int main() -// { -// // user_function's `T` will be deduced to `int` and `Ints...` -// // will be deduced to `0, 1, 2, 3, 4`. -// user_function(make_integer_sequence()); -// } -template -struct integer_sequence -{ - using value_type = T; - static constexpr std::size_t size() noexcept - { - return sizeof...(Ints); - } -}; - -// index_sequence -// -// A helper template for an `integer_sequence` of `size_t`, -// `absl::index_sequence` is designed to be a drop-in replacement for C++14's -// `std::index_sequence`. -template -using index_sequence = integer_sequence; - -namespace utility_internal -{ - -template -struct Extend; - -// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. -template -struct Extend, SeqSize, 0> -{ - using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; -}; - -template -struct Extend, SeqSize, 1> -{ - using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; -}; - -// Recursion helper for 'make_integer_sequence'. -// 'Gen::type' is an alias for 'integer_sequence'. -template -struct Gen -{ - using type = - typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; -}; - -template -struct Gen -{ - using type = integer_sequence; -}; - -} // namespace utility_internal - -// Compile-time sequences of integers - -// make_integer_sequence -// -// This template alias is equivalent to -// `integer_sequence`, and is designed to be a drop-in -// replacement for C++14's `std::make_integer_sequence`. -template -using make_integer_sequence = typename utility_internal::Gen::type; - -// make_index_sequence -// -// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, -// and is designed to be a drop-in replacement for C++14's -// `std::make_index_sequence`. -template -using make_index_sequence = make_integer_sequence; - -// index_sequence_for -// -// Converts a typename pack into an index sequence of the same length, and -// is designed to be a drop-in replacement for C++14's -// `std::index_sequence_for()` -template -using index_sequence_for = make_index_sequence; - -//// END OF CODE FROM GOOGLE ABSEIL - -#endif - -// dispatch utility (taken from ranges-v3) -template struct priority_tag : priority_tag < N - 1 > {}; -template<> struct priority_tag<0> {}; - -// taken from ranges-v3 -template -struct static_const -{ - static JSON_INLINE_VARIABLE constexpr T value{}; -}; - -#ifndef JSON_HAS_CPP_17 - template - constexpr T static_const::value; -#endif - -template -inline constexpr std::array make_array(Args&& ... args) -{ - return std::array {{static_cast(std::forward(args))...}}; -} - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // numeric_limits -#include // false_type, is_constructible, is_integral, is_same, true_type -#include // declval -#include // tuple - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // random_access_iterator_tag - -// #include - -// #include - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -template -struct iterator_types {}; - -template -struct iterator_types < - It, - void_t> -{ - using difference_type = typename It::difference_type; - using value_type = typename It::value_type; - using pointer = typename It::pointer; - using reference = typename It::reference; - using iterator_category = typename It::iterator_category; -}; - -// This is required as some compilers implement std::iterator_traits in a way that -// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. -template -struct iterator_traits -{ -}; - -template -struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> - : iterator_types -{ -}; - -template -struct iterator_traits::value>> -{ - using iterator_category = std::random_access_iterator_tag; - using value_type = T; - using difference_type = ptrdiff_t; - using pointer = T*; - using reference = T&; -}; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN - -NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); - -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN - -NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); - -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - -#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ - #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ - - #include // int64_t, uint64_t - #include // map - #include // allocator - #include // string - #include // vector - - // #include - - - /*! - @brief namespace for Niels Lohmann - @see https://github.com/nlohmann - @since version 1.0.0 - */ - NLOHMANN_JSON_NAMESPACE_BEGIN - - /*! - @brief default JSONSerializer template argument - - This serializer ignores the template arguments and uses ADL - ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) - for serialization. - */ - template - struct adl_serializer; - - /// a class to store JSON values - /// @sa https://json.nlohmann.me/api/basic_json/ - template class ObjectType = - std::map, - template class ArrayType = std::vector, - class StringType = std::string, class BooleanType = bool, - class NumberIntegerType = std::int64_t, - class NumberUnsignedType = std::uint64_t, - class NumberFloatType = double, - template class AllocatorType = std::allocator, - template class JSONSerializer = - adl_serializer, - class BinaryType = std::vector, // cppcheck-suppress syntaxError - class CustomBaseClass = void> - class basic_json; - - /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document - /// @sa https://json.nlohmann.me/api/json_pointer/ - template - class json_pointer; - - /*! - @brief default specialization - @sa https://json.nlohmann.me/api/json/ - */ - using json = basic_json<>; - - /// @brief a minimal map-like container that preserves insertion order - /// @sa https://json.nlohmann.me/api/ordered_map/ - template - struct ordered_map; - - /// @brief specialization that maintains the insertion order of object keys - /// @sa https://json.nlohmann.me/api/ordered_json/ - using ordered_json = basic_json; - - NLOHMANN_JSON_NAMESPACE_END - -#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ - - -NLOHMANN_JSON_NAMESPACE_BEGIN -/*! -@brief detail namespace with internal helper functions - -This namespace collects functions that should not be exposed, -implementations of some @ref basic_json methods, and meta-programming helpers. - -@since version 2.1.0 -*/ -namespace detail -{ - -///////////// -// helpers // -///////////// - -// Note to maintainers: -// -// Every trait in this file expects a non CV-qualified type. -// The only exceptions are in the 'aliases for detected' section -// (i.e. those of the form: decltype(T::member_function(std::declval()))) -// -// In this case, T has to be properly CV-qualified to constraint the function arguments -// (e.g. to_json(BasicJsonType&, const T&)) - -template struct is_basic_json : std::false_type {}; - -NLOHMANN_BASIC_JSON_TPL_DECLARATION -struct is_basic_json : std::true_type {}; - -// used by exceptions create() member functions -// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t -// false_type otherwise -template -struct is_basic_json_context : - std::integral_constant < bool, - is_basic_json::type>::type>::value - || std::is_same::value > -{}; - -////////////////////// -// json_ref helpers // -////////////////////// - -template -class json_ref; - -template -struct is_json_ref : std::false_type {}; - -template -struct is_json_ref> : std::true_type {}; - -////////////////////////// -// aliases for detected // -////////////////////////// - -template -using mapped_type_t = typename T::mapped_type; - -template -using key_type_t = typename T::key_type; - -template -using value_type_t = typename T::value_type; - -template -using difference_type_t = typename T::difference_type; - -template -using pointer_t = typename T::pointer; - -template -using reference_t = typename T::reference; - -template -using iterator_category_t = typename T::iterator_category; - -template -using to_json_function = decltype(T::to_json(std::declval()...)); - -template -using from_json_function = decltype(T::from_json(std::declval()...)); - -template -using get_template_function = decltype(std::declval().template get()); - -// trait checking if JSONSerializer::from_json(json const&, udt&) exists -template -struct has_from_json : std::false_type {}; - -// trait checking if j.get is valid -// use this trait instead of std::is_constructible or std::is_convertible, -// both rely on, or make use of implicit conversions, and thus fail when T -// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) -template -struct is_getable -{ - static constexpr bool value = is_detected::value; -}; - -template -struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -// This trait checks if JSONSerializer::from_json(json const&) exists -// this overload is used for non-default-constructible user-defined-types -template -struct has_non_default_from_json : std::false_type {}; - -template -struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -// This trait checks if BasicJsonType::json_serializer::to_json exists -// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. -template -struct has_to_json : std::false_type {}; - -template -struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -template -using detect_key_compare = typename T::key_compare; - -template -struct has_key_compare : std::integral_constant::value> {}; - -// obtains the actual object key comparator -template -struct actual_object_comparator -{ - using object_t = typename BasicJsonType::object_t; - using object_comparator_t = typename BasicJsonType::default_object_comparator_t; - using type = typename std::conditional < has_key_compare::value, - typename object_t::key_compare, object_comparator_t>::type; -}; - -template -using actual_object_comparator_t = typename actual_object_comparator::type; - -/////////////////// -// is_ functions // -/////////////////// - -// https://en.cppreference.com/w/cpp/types/conjunction -template struct conjunction : std::true_type { }; -template struct conjunction : B { }; -template -struct conjunction -: std::conditional(B::value), conjunction, B>::type {}; - -// https://en.cppreference.com/w/cpp/types/negation -template struct negation : std::integral_constant < bool, !B::value > { }; - -// Reimplementation of is_constructible and is_default_constructible, due to them being broken for -// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). -// This causes compile errors in e.g. clang 3.5 or gcc 4.9. -template -struct is_default_constructible : std::is_default_constructible {}; - -template -struct is_default_constructible> - : conjunction, is_default_constructible> {}; - -template -struct is_default_constructible> - : conjunction, is_default_constructible> {}; - -template -struct is_default_constructible> - : conjunction...> {}; - -template -struct is_default_constructible> - : conjunction...> {}; - - -template -struct is_constructible : std::is_constructible {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - - -template -struct is_iterator_traits : std::false_type {}; - -template -struct is_iterator_traits> -{ - private: - using traits = iterator_traits; - - public: - static constexpr auto value = - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value; -}; - -template -struct is_range -{ - private: - using t_ref = typename std::add_lvalue_reference::type; - - using iterator = detected_t; - using sentinel = detected_t; - - // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator - // and https://en.cppreference.com/w/cpp/iterator/sentinel_for - // but reimplementing these would be too much work, as a lot of other concepts are used underneath - static constexpr auto is_iterator_begin = - is_iterator_traits>::value; - - public: - static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; -}; - -template -using iterator_t = enable_if_t::value, result_of_begin())>>; - -template -using range_value_t = value_type_t>>; - -// The following implementation of is_complete_type is taken from -// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ -// and is written by Xiang Fan who agreed to using it in this library. - -template -struct is_complete_type : std::false_type {}; - -template -struct is_complete_type : std::true_type {}; - -template -struct is_compatible_object_type_impl : std::false_type {}; - -template -struct is_compatible_object_type_impl < - BasicJsonType, CompatibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> -{ - using object_t = typename BasicJsonType::object_t; - - // macOS's is_constructible does not play well with nonesuch... - static constexpr bool value = - is_constructible::value && - is_constructible::value; -}; - -template -struct is_compatible_object_type - : is_compatible_object_type_impl {}; - -template -struct is_constructible_object_type_impl : std::false_type {}; - -template -struct is_constructible_object_type_impl < - BasicJsonType, ConstructibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> -{ - using object_t = typename BasicJsonType::object_t; - - static constexpr bool value = - (is_default_constructible::value && - (std::is_move_assignable::value || - std::is_copy_assignable::value) && - (is_constructible::value && - std::is_same < - typename object_t::mapped_type, - typename ConstructibleObjectType::mapped_type >::value)) || - (has_from_json::value || - has_non_default_from_json < - BasicJsonType, - typename ConstructibleObjectType::mapped_type >::value); -}; - -template -struct is_constructible_object_type - : is_constructible_object_type_impl {}; - -template -struct is_compatible_string_type -{ - static constexpr auto value = - is_constructible::value; -}; - -template -struct is_constructible_string_type -{ - // launder type through decltype() to fix compilation failure on ICPC -#ifdef __INTEL_COMPILER - using laundered_type = decltype(std::declval()); -#else - using laundered_type = ConstructibleStringType; -#endif - - static constexpr auto value = - conjunction < - is_constructible, - is_detected_exact>::value; -}; - -template -struct is_compatible_array_type_impl : std::false_type {}; - -template -struct is_compatible_array_type_impl < - BasicJsonType, CompatibleArrayType, - enable_if_t < - is_detected::value&& - is_iterator_traits>>::value&& -// special case for types like std::filesystem::path whose iterator's value_type are themselves -// c.f. https://github.com/nlohmann/json/pull/3073 - !std::is_same>::value >> -{ - static constexpr bool value = - is_constructible>::value; -}; - -template -struct is_compatible_array_type - : is_compatible_array_type_impl {}; - -template -struct is_constructible_array_type_impl : std::false_type {}; - -template -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t::value >> - : std::true_type {}; - -template -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t < !std::is_same::value&& - !is_compatible_string_type::value&& - is_default_constructible::value&& -(std::is_move_assignable::value || - std::is_copy_assignable::value)&& -is_detected::value&& -is_iterator_traits>>::value&& -is_detected::value&& -// special case for types like std::filesystem::path whose iterator's value_type are themselves -// c.f. https://github.com/nlohmann/json/pull/3073 -!std::is_same>::value&& - is_complete_type < - detected_t>::value >> -{ - using value_type = range_value_t; - - static constexpr bool value = - std::is_same::value || - has_from_json::value || - has_non_default_from_json < - BasicJsonType, - value_type >::value; -}; - -template -struct is_constructible_array_type - : is_constructible_array_type_impl {}; - -template -struct is_compatible_integer_type_impl : std::false_type {}; - -template -struct is_compatible_integer_type_impl < - RealIntegerType, CompatibleNumberIntegerType, - enable_if_t < std::is_integral::value&& - std::is_integral::value&& - !std::is_same::value >> -{ - // is there an assert somewhere on overflows? - using RealLimits = std::numeric_limits; - using CompatibleLimits = std::numeric_limits; - - static constexpr auto value = - is_constructible::value && - CompatibleLimits::is_integer && - RealLimits::is_signed == CompatibleLimits::is_signed; -}; - -template -struct is_compatible_integer_type - : is_compatible_integer_type_impl {}; - -template -struct is_compatible_type_impl: std::false_type {}; - -template -struct is_compatible_type_impl < - BasicJsonType, CompatibleType, - enable_if_t::value >> -{ - static constexpr bool value = - has_to_json::value; -}; - -template -struct is_compatible_type - : is_compatible_type_impl {}; - -template -struct is_constructible_tuple : std::false_type {}; - -template -struct is_constructible_tuple> : conjunction...> {}; - -template -struct is_json_iterator_of : std::false_type {}; - -template -struct is_json_iterator_of : std::true_type {}; - -template -struct is_json_iterator_of : std::true_type -{}; - -// checks if a given type T is a template specialization of Primary -template