diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 679eeee3a..b371a03b5 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -3,6 +3,8 @@ name: Code Coverage on: push: branches: [ master ] + pull_request: + branches: [ master ] schedule: - cron: "0 11 * * *" diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 9665dec7a..c3949d6c5 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -41,7 +41,7 @@ jobs: type=edge type=sha,prefix=ubuntu-20.04-bare-z3-sha- - name: Build and push Bare Z3 Docker Image - uses: docker/build-push-action@v6.3.0 + uses: docker/build-push-action@v6.9.0 with: context: . push: true diff --git a/.github/workflows/msvc-static-build-clang-cl.yml b/.github/workflows/msvc-static-build-clang-cl.yml new file mode 100644 index 000000000..341f873c1 --- /dev/null +++ b/.github/workflows/msvc-static-build-clang-cl.yml @@ -0,0 +1,23 @@ +name: MSVC Clang-CL Static Build + +on: + push: + pull_request: + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + build: + runs-on: windows-2019 + env: + BUILD_TYPE: Release + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + + - name: Build + run: | + cmake -B build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DZ3_BUILD_LIBZ3_SHARED=OFF -DZ3_BUILD_LIBZ3_MSVC_STATIC=ON -T ClangCL -DCMAKE_C_FLAGS="/EHsc" -DCMAKE_CXX_FLAGS="/EHsc" + cmake --build build --config ${{ env.BUILD_TYPE }} --parallel + diff --git a/.gitignore b/.gitignore index 5ffb0874c..9621b4c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,11 @@ callgrind.out.* *.hpp .env .z3-trace +.env +.genaiscript +package-lock.json +package.json +node_modules # OCaml generated files *.a *.o diff --git a/.gitignore.genai b/.gitignore.genai new file mode 100644 index 000000000..254ca5bfe --- /dev/null +++ b/.gitignore.genai @@ -0,0 +1,3 @@ +**/genaiscript.d.ts +**/package-lock.json +**/yarn.lock diff --git a/CMakeLists.txt b/CMakeLists.txt index cdccb8e4b..797087641 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.16) set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cxx_compiler_flags_overrides.cmake") -project(Z3 VERSION 4.13.1.0 LANGUAGES CXX) +project(Z3 VERSION 4.13.3.0 LANGUAGES CXX) ################################################################################ # Project version @@ -178,7 +178,7 @@ include(${PROJECT_SOURCE_DIR}/cmake/z3_add_cxx_flag.cmake) ################################################################################ # C++ language version ################################################################################ -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) ################################################################################ diff --git a/README.md b/README.md index e6db550c0..5350bc38b 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ See [``examples/ml``](examples/ml) for examples. ### ``Python`` -You can install the Python wrapper for Z3 for the latest release from pypi using the command +You can install the Python wrapper for Z3 for the latest release from pypi using the command: ```bash pip install z3-solver @@ -206,7 +206,7 @@ See [``examples/python``](examples/python) for examples. ### ``Julia`` -The Julia package [Z3.jl](https://github.com/ahumenberger/Z3.jl) wraps the C++ API of Z3. Information about updating and building the Julia bindings can be found in [src/api/julia](src/api/julia). +The Julia package [Z3.jl](https://github.com/ahumenberger/Z3.jl) wraps the C API of Z3. A previous version of it wrapped the C++ API: Information about updating and building the Julia bindings can be found in [src/api/julia](src/api/julia). ### ``Web Assembly`` / ``TypeScript`` / ``JavaScript`` @@ -236,4 +236,7 @@ to Z3's C API. For more information, see [MachineArithmetic/README.md](https://g * [Julia](https://github.com/ahumenberger/Z3.jl) * [Smalltalk](https://github.com/shingarov/MachineArithmetic/blob/pure-z3/MachineArithmetic/README.md) (supports Pharo and Smalltalk/X) +## Power Tools +* The [Axiom Profiler](https://github.com/viperproject/axiom-profiler-2) currently developed by ETH Zurich + diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 3830f566f..c35875fed 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -10,6 +10,31 @@ Version 4.next - native word level bit-vector solving. - introduction of simple induction lemmas to handle a limited repertoire of induction proofs. +Version 4.13.2 +============== +- Performance regression fix. #7404 + +Version 4.13.1 +============== +- single-sample cell projection in nlsat was designed by Haokun Li and Bican Xia. +- using simple-checker together with and variable ordering supported by qfnra_tactic was developed by Mengyu Zhao (Linxi) and Shaowei Cai. + + The projection is described in paper by Haokun Li and Bican Xia, [Solving Satisfiability of Polynomial Formulas By Sample - Cell Projection](https://arxiv.org/abs/2003.00409). The code ported from https://github.com/hybridSMT/hybridSMT.git + +- Add API for providing hints for the solver/optimize contexts for which initial values to attempt to use for variables. + The new API function are Z3_solver_set_initial_value and Z3_optimize_set_initial_value, respectively. Supply these functions with a Boolean or numeric variable, and a value. The solver will then attempt to use these values in the initial phase of search. The feature is aimed at resolving nearly similar problems, or problems with a predicted model and the intent is that restarting the solver based on a near solution can avoid prune the space of constraints that are initially infeasible. + The SMTLIB front-end contains the new command (set-initial-value var value). For example, + (declare-const x Int) + (set-initial-value x 10) + (push) + (assert (> x 0)) + (check-sat) + (get-model) + produces a model where x = 10. We use (push) to ensure that z3 doesn't run a + specialized pre-processor that eliminates x, which renders the initialization + without effect. + + Version 4.13.0 ============== - add ARM64 wheels for Python, thanks to Steven Moy, smoy diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 48dcf094a..938f63507 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -43,8 +43,20 @@ jobs: - ${{if eq(variables['runRegressions'], 'True')}}: - template: scripts/test-regressions.yml -- job: LinuxBuildsArm64 - displayName: "ManyLinux ARM64 build" +- job: "ManylinuxPythonBuildAmd64" + displayName: "Python bindings (manylinux Centos AMD64) build" + pool: + vmImage: "ubuntu-latest" + container: "quay.io/pypa/manylinux2014_x86_64:latest" + steps: + - script: "/opt/python/cp38-cp38/bin/python -m venv $PWD/env" + - script: 'echo "##vso[task.prependpath]$PWD/env/bin"' + - script: "pip install build git+https://github.com/rhelmot/auditwheel" + - script: "cd src/api/python && python -m build && AUDITWHEEL_PLAT= auditwheel repair --best-plat dist/*.whl && cd ../../.." + - script: "pip install ./src/api/python/wheelhouse/*.whl && python - &, const _scoped_numeral::numeral&)’\ + 96 | friend bool operator==(_scoped_numeral const & a, numeral const & b) {\ + | ^~~~~~~~\ +/home/nbjorner/z3/src/util/scoped_numeral.h:96:17: note: candidate 2: ‘bool operator==(const _scoped_numeral&, const _scoped_numeral::numeral&)’ (reversed)") + +$`You are an expert C++ programmer. +Your task is to fix the compilation bug reported in the error message ERR. +How should FILE be changed to fix the error message?` diff --git a/genaisrc/gai.genai.mts b/genaisrc/gai.genai.mts new file mode 100644 index 000000000..9de3cf11a --- /dev/null +++ b/genaisrc/gai.genai.mts @@ -0,0 +1,17 @@ +script({ + tools: ["agent_fs", "agent_git", "agent_github"], +}) + +const { + workflow = "latest failed", + failure_run_id = "latest", + branch = await git.defaultBranch(), +} = env.vars + +$`Investigate the status of the ${workflow} workflow and identify the root cause of the failure of run ${failure_run_id} in branch ${branch}. + +- Correlate the failure with the relevant commits, pull requests or issues. +- Compare the source code between the failed run commit and the last successful run commit before that run. + +In your report, include html links to the relevant runs, commits, pull requests or issues. +` diff --git a/genaisrc/gcm.genai.mts b/genaisrc/gcm.genai.mts index b39e9a8e0..d1f97174f 100644 --- a/genaisrc/gcm.genai.mts +++ b/genaisrc/gcm.genai.mts @@ -1,81 +1,75 @@ -import { select, input, confirm } from "@inquirer/prompts" +/** + * git commit flow with auto-generated commit message + */ +script({ + title: "git commit message", + description: "Generate a commit message for all staged changes", +}) // Check for staged changes and stage all changes if none are staged -let diff = await host.exec("git", ["diff", "--cached"]) -if (!diff.stdout) { - const stage = await confirm({ - message: "No staged changes. Stage all changes?", - default: true, - }) - if (stage) { - await host.exec("git", ["add", "."]) - diff = await host.exec("git", [ - "diff", - "--cached", - "--", - ".", - ":!**/genaiscript.d.ts", - ]) - } - if (!diff.stdout) cancel("no staged changes") -} +const diff = await git.diff({ + staged: true, + excludedPaths: "**/genaiscript.d.ts", + askStageOnEmpty: true, +}) +if (!diff) cancel("no staged changes") -console.log(diff.stdout) +// show diff in the console +console.log(diff) let choice let message do { // Generate commit message - message = ( - await runPrompt( - (_) => { - _.def("GIT_DIFF", diff, { maxTokens: 20000 }) - _.$`GIT_DIFF is a diff of all staged changes, coming from the command: + const res = await runPrompt( + (_) => { + _.def("GIT_DIFF", diff, { maxTokens: 20000 }) + _.$`GIT_DIFF is a diff of all staged changes, coming from the command: \`\`\` git diff --cached \`\`\` Please generate a concise, one-line commit message for these changes. -- do NOT add quotes` - }, - { cache: false, temperature: 0.8 } - ) - ).text +- do NOT add quotes +` // TODO: add a better prompt + }, + { cache: false, temperature: 0.8 } + ) + if (res.error) throw res.error + + message = res.text + if (!message) { + console.log("No message generated, did you configure the LLM model?") + break + } // Prompt user for commit message - choice = await select({ - message, - choices: [ - { - name: "commit", - value: "commit", - description: "accept message and commit", - }, - { - name: "edit", - value: "edit", - description: "edit message and commit", - }, - { - name: "regenerate", - value: "regenerate", - description: "regenerate message", - }, - ], - }) + choice = await host.select(message, [ + { + value: "commit", + description: "accept message and commit", + }, + { + value: "edit", + description: "edit message and commit", + }, + { + value: "regenerate", + description: "regenerate message", + }, + ]) // Handle user choice if (choice === "edit") { - message = await input({ - message: "Edit commit message", + message = await host.input("Edit commit message", { required: true, }) choice = "commit" } // Regenerate message if (choice === "commit" && message) { - console.log((await host.exec("git", ["commit", "-m", message])).stdout) - if (await confirm({ message: "Push changes?", default: true })) - console.log((await host.exec("git", ["push"])).stdout) + console.log(await git.exec(["commit", "-m", message])) + if (await host.confirm("Push changes?", { default: true })) + console.log(await git.exec("push")) break } } while (choice !== "commit") diff --git a/genaisrc/genaiscript.d.ts b/genaisrc/genaiscript.d.ts new file mode 100644 index 000000000..e11a3edd7 Binary files /dev/null and b/genaisrc/genaiscript.d.ts differ diff --git a/genaisrc/tsconfig.json b/genaisrc/tsconfig.json new file mode 100644 index 000000000..510eefe8f --- /dev/null +++ b/genaisrc/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "lib": [ + "ES2022" + ], + "target": "ES2023", + "module": "NodeNext", + "moduleDetection": "force", + "moduleResolution": "nodenext", + "checkJs": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "allowImportingTsExtensions": true + }, + "include": [ + "*.mjs", + "*.mts", + "./genaiscript.d.ts" + ] +} \ No newline at end of file diff --git a/scripts/mk_project.py b/scripts/mk_project.py index adb90f22e..545eaebe2 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -8,7 +8,7 @@ from mk_util import * def init_version(): - set_version(4, 13, 1, 0) # express a default build version or pick up ci build version + set_version(4, 13, 3, 0) # express a default build version or pick up ci build version # Z3 Project definition def init_project_def(): diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 3e6da0b22..0177dc564 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -2007,11 +2007,11 @@ class MLComponent(Component): src_dir = self.to_src_dir mk_dir(os.path.join(BUILD_DIR, self.sub_dir)) api_src = get_component(API_COMPONENT).to_src_dir - # remove /GL and -std=c++17; the ocaml tools don't like them. + # remove /GL and -std=c++20; the ocaml tools don't like them. if IS_WINDOWS: out.write('CXXFLAGS_OCAML=$(CXXFLAGS:/GL=)\n') else: - out.write('CXXFLAGS_OCAML=$(subst -std=c++17,,$(CXXFLAGS))\n') + out.write('CXXFLAGS_OCAML=$(subst -std=c++20,,$(CXXFLAGS))\n') substitutions = { 'VERSION': "{}.{}.{}.{}".format(VER_MAJOR, VER_MINOR, VER_BUILD, VER_TWEAK) } @@ -2500,7 +2500,7 @@ def mk_config(): config = open(os.path.join(BUILD_DIR, 'config.mk'), 'w') global CXX, CC, GMP, GUARD_CF, STATIC_BIN, GIT_HASH, CPPFLAGS, CXXFLAGS, LDFLAGS, EXAMP_DEBUG_FLAG, FPMATH_FLAGS, LOG_SYNC, SINGLE_THREADED, IS_ARCH_ARM64 if IS_WINDOWS: - CXXFLAGS = '/nologo /Zi /D WIN32 /D _WINDOWS /EHsc /GS /Gd /std:c++17' + CXXFLAGS = '/nologo /Zi /D WIN32 /D _WINDOWS /EHsc /GS /Gd /std:c++20' config.write( 'CC=cl\n' 'CXX=cl\n' @@ -2616,7 +2616,7 @@ def mk_config(): CPPFLAGS = '%s -D_MP_INTERNAL' % CPPFLAGS if GIT_HASH: CPPFLAGS = '%s -DZ3GITHASH=%s' % (CPPFLAGS, GIT_HASH) - CXXFLAGS = '%s -std=c++17' % CXXFLAGS + CXXFLAGS = '%s -std=c++20' % CXXFLAGS CXXFLAGS = '%s -fvisibility=hidden -fvisibility-inlines-hidden -c' % CXXFLAGS FPMATH = test_fpmath(CXX) CXXFLAGS = '%s %s' % (CXXFLAGS, FPMATH_FLAGS) @@ -2699,7 +2699,7 @@ def mk_config(): config.write('CC=%s\n' % CC) config.write('CXX=%s\n' % CXX) config.write('CXXFLAGS=%s %s\n' % (CPPFLAGS, CXXFLAGS)) - config.write('CFLAGS=%s %s\n' % (CPPFLAGS, CXXFLAGS.replace('-std=c++17', ''))) + config.write('CFLAGS=%s %s\n' % (CPPFLAGS, CXXFLAGS.replace('-std=c++20', ''))) config.write('EXAMP_DEBUG_FLAG=%s\n' % EXAMP_DEBUG_FLAG) config.write('CXX_OUT_FLAG=-o \n') config.write('C_OUT_FLAG=-o \n') diff --git a/scripts/mk_win_dist_cmake.py b/scripts/mk_win_dist_cmake.py index f3c83cfb6..157965184 100644 --- a/scripts/mk_win_dist_cmake.py +++ b/scripts/mk_win_dist_cmake.py @@ -375,10 +375,11 @@ def cp_into_bin(arch): os.path.join(bin_dir, "libz3.lib")) shutil.rmtree(lib_dir) if JAVA_ENABLED: - java_dir = get_java_dist_path(arch) - shutil.copytree(java_dir, - bin_dir, - dirs_exist_ok=True) + java_dir = os.path.join(bin_dir, "java") + for file in os.listdir(java_dir): + src_path = os.path.join(java_dir, file) + dst_path = os.path.join(bin_dir, file) + shutil.copy2(src_path, dst_path) shutil.rmtree(java_dir) def cp_pdb(arch): diff --git a/scripts/nightly.yaml b/scripts/nightly.yaml index 62976cce2..74768fbea 100644 --- a/scripts/nightly.yaml +++ b/scripts/nightly.yaml @@ -1,7 +1,7 @@ variables: Major: '4' Minor: '13' - Patch: '1' + Patch: '3' ReleaseVersion: $(Major).$(Minor).$(Patch) AssemblyVersion: $(Major).$(Minor).$(Patch).$(Build.BuildId) NightlyVersion: $(AssemblyVersion)-$(Build.buildId) @@ -10,7 +10,7 @@ stages: - stage: Build jobs: - job: MacBuild - displayName: "macOS Build" + displayName: "Mac Build" pool: vmImage: "macOS-latest" steps: @@ -35,7 +35,7 @@ stages: targetFolder: $(Build.ArtifactStagingDirectory) - task: PublishPipelineArtifact@0 inputs: - artifactName: 'macOSBuild' + artifactName: 'macOsBuild' targetPath: $(Build.ArtifactStagingDirectory) - job: MacBuildArm64 @@ -80,35 +80,6 @@ stages: artifactName: 'UbuntuBuild' targetPath: $(Build.ArtifactStagingDirectory) - - job: UbuntuBuild20 - displayName: "Ubuntu build 20" - pool: - vmImage: "ubuntu-20.04" - steps: - - task: PythonScript@0 - displayName: Build - inputs: - scriptSource: 'filepath' - scriptPath: scripts/mk_unix_dist.py - arguments: --dotnet-key=$(Build.SourcesDirectory)/resources/z3.snk - - script: git clone https://github.com/z3prover/z3test z3test - displayName: 'Clone z3test' - - task: PythonScript@0 - displayName: Test - inputs: - scriptSource: 'filepath' - scriptPath: z3test/scripts/test_benchmarks.py - arguments: build-dist/z3 z3test/regressions/smt2 - - task: CopyFiles@2 - inputs: - sourceFolder: dist - contents: '*.zip' - targetFolder: $(Build.ArtifactStagingDirectory) - - task: PublishPipelineArtifact@0 - inputs: - artifactName: 'UbuntuBuild20' - targetPath: $(Build.ArtifactStagingDirectory) - - job: UbuntuArm64 displayName: "Ubuntu ARM64 build" pool: @@ -121,7 +92,7 @@ stages: - script: echo '##vso[task.prependpath]/tmp/arm-toolchain/aarch64-none-linux-gnu/libc/usr/bin' - script: echo $PATH - script: stat /tmp/arm-toolchain/bin/aarch64-none-linux-gnu-gcc - - script: python scripts/mk_unix_dist.py --nodotnet --nojava --arch=arm64 + - script: python scripts/mk_unix_dist.py --nodotnet --arch=arm64 - task: CopyFiles@2 inputs: sourceFolder: dist @@ -167,74 +138,59 @@ stages: inputs: artifactName: 'UbuntuDoc' targetPath: $(Build.ArtifactStagingDirectory) - - - job: LinuxBuilds - displayName: "ManyLinux build" - variables: - name: ManyLinux - python: "/opt/python/cp37-cp37m/bin/python" + # TODO copy artifacts + + - job: "ManylinuxPythonBuildAmd64" + displayName: "Python bindings (manylinux Centos AMD64) build" pool: vmImage: "ubuntu-latest" - container: "quay.io/pypa/manylinux_2_28_x86_64:latest" + container: "quay.io/pypa/manylinux2014_x86_64:latest" steps: - - task: PythonScript@0 - displayName: Build - inputs: - scriptSource: 'filepath' - scriptPath: scripts/mk_unix_dist.py - arguments: --nodotnet --nojava - pythonInterpreter: $(python) - - script: git clone https://github.com/z3prover/z3test z3test - displayName: 'Clone z3test' - - task: PythonScript@0 - displayName: Test - inputs: - scriptSource: 'filepath' - scriptPath: z3test/scripts/test_benchmarks.py - arguments: build-dist/z3 z3test/regressions/smt2 - pythonInterpreter: $(python) + - script: "/opt/python/cp38-cp38/bin/python -m venv $PWD/env" + - script: 'echo "##vso[task.prependpath]$PWD/env/bin"' + - script: "pip install build git+https://github.com/rhelmot/auditwheel" # @TODO remove when patches make it upstream + - script: "cd src/api/python && python -m build && AUDITWHEEL_PLAT= auditwheel repair --best-plat dist/*.whl && cd ../../.." + - script: "pip install ./src/api/python/wheelhouse/*.whl && python - get_sort() != to_expr(value)->get_sort()) { + SET_ERROR_CODE(Z3_INVALID_USAGE, "variable and value should have same sort"); + return; + } + ast_manager& m = mk_c(c)->m(); + if (!m.is_value(to_expr(value))) { + SET_ERROR_CODE(Z3_INVALID_USAGE, "a proper value was not supplied"); + return; + } + to_optimize_ptr(o)->initialize_value(to_expr(var), to_expr(value)); + Z3_CATCH; + } }; diff --git a/src/api/api_solver.cpp b/src/api/api_solver.cpp index f18edd96b..f226529de 100644 --- a/src/api/api_solver.cpp +++ b/src/api/api_solver.cpp @@ -1143,5 +1143,23 @@ extern "C" { Z3_CATCH_RETURN(nullptr); } + void Z3_API Z3_solver_set_initial_value(Z3_context c, Z3_solver s, Z3_ast var, Z3_ast value) { + Z3_TRY; + LOG_Z3_solver_set_initial_value(c, s, var, value); + RESET_ERROR_CODE(); + if (to_expr(var)->get_sort() != to_expr(value)->get_sort()) { + SET_ERROR_CODE(Z3_INVALID_USAGE, "variable and value should have same sort"); + return; + } + ast_manager& m = mk_c(c)->m(); + if (!m.is_value(to_expr(value))) { + SET_ERROR_CODE(Z3_INVALID_USAGE, "a proper value was not supplied"); + return; + } + to_solver_ref(s)->user_propagate_initialize_value(to_expr(var), to_expr(value)); + Z3_CATCH; + } + + }; diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 81d5bcaa9..e29bde4a8 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -1603,10 +1603,10 @@ namespace z3 { unsigned i; public: iterator(expr& e, unsigned i): e(e), i(i) {} - bool operator==(iterator const& other) noexcept { + bool operator==(iterator const& other) const noexcept { return i == other.i; } - bool operator!=(iterator const& other) noexcept { + bool operator!=(iterator const& other) const noexcept { return i != other.i; } expr operator*() const { return e.arg(i); } @@ -2865,6 +2865,17 @@ namespace z3 { check_error(); return result; } + void set_initial_value(expr const& var, expr const& value) { + Z3_solver_set_initial_value(ctx(), m_solver, var, value); + check_error(); + } + void set_initial_value(expr const& var, int i) { + set_initial_value(var, ctx().num_val(i, var.get_sort())); + } + void set_initial_value(expr const& var, bool b) { + set_initial_value(var, ctx().bool_val(b)); + } + expr proof() const { Z3_ast r = Z3_solver_get_proof(ctx(), m_solver); check_error(); return expr(ctx(), r); } friend std::ostream & operator<<(std::ostream & out, solver const & s); @@ -2946,10 +2957,10 @@ namespace z3 { expr_vector const * operator->() const { return &(operator*()); } expr_vector const& operator*() const noexcept { return m_cube; } - bool operator==(cube_iterator const& other) noexcept { + bool operator==(cube_iterator const& other) const noexcept { return other.m_end == m_end; }; - bool operator!=(cube_iterator const& other) noexcept { + bool operator!=(cube_iterator const& other) const noexcept { return other.m_end != m_end; }; @@ -3330,6 +3341,17 @@ namespace z3 { handle add(expr const& e, unsigned weight) { return add_soft(e, weight); } + void set_initial_value(expr const& var, expr const& value) { + Z3_optimize_set_initial_value(ctx(), m_opt, var, value); + check_error(); + } + void set_initial_value(expr const& var, int i) { + set_initial_value(var, ctx().num_val(i, var.get_sort())); + } + void set_initial_value(expr const& var, bool b) { + set_initial_value(var, ctx().bool_val(b)); + } + handle maximize(expr const& e) { return handle(Z3_optimize_maximize(ctx(), m_opt, e)); } diff --git a/src/api/js/package-lock.json b/src/api/js/package-lock.json index 0db00bfa0..432e00568 100644 --- a/src/api/js/package-lock.json +++ b/src/api/js/package-lock.json @@ -1,40 +1,78 @@ { "name": "z3-solver", "version": "0.1.0", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@ampproject/remapping": { + "packages": { + "": { + "name": "z3-solver", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "async-mutex": "^0.3.2" + }, + "devDependencies": { + "@types/jest": "^27.5.1", + "@types/node": "^17.0.8", + "@types/prettier": "^2.6.1", + "@types/sprintf-js": "^1.1.2", + "check-engine": "^1.10.1", + "iter-tools": "^7.3.1", + "jest": "^28.1.0", + "npm-run-all": "^4.1.5", + "prettier": "^2.5.1", + "rimraf": "^3.0.2", + "sprintf-js": "^1.1.2", + "ts-expect": "^1.3.0", + "ts-jest": "^28.0.3", + "ts-node": "^10.8.0", + "typedoc": "^0.23.16", + "typescript": "^4.8.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "dev": true, - "requires": { + "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" } }, - "@babel/code-frame": { + "node_modules/@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, - "requires": { + "dependencies": { "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/compat-data": { + "node_modules/@babel/compat-data": { "version": "7.19.4", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "@babel/core": { + "node_modules/@babel/core": { "version": "7.19.3", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", "dev": true, - "requires": { + "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", "@babel/generator": "^7.19.3", @@ -51,80 +89,107 @@ "json5": "^2.2.1", "semver": "^6.3.0" }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "@babel/generator": { + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { "version": "7.19.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.5.tgz", "integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.19.4", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-compilation-targets": { + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { "version": "7.19.3", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", "dev": true, - "requires": { + "dependencies": { "@babel/compat-data": "^7.19.3", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", "semver": "^6.3.0" }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-environment-visitor": { + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-module-imports": { + "node_modules/@babel/helper-module-imports": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-module-transforms": { + "node_modules/@babel/helper-module-transforms": { "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", "@babel/helper-simple-access": "^7.18.6", @@ -133,221 +198,305 @@ "@babel/template": "^7.18.10", "@babel/traverse": "^7.19.0", "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-plugin-utils": { + "node_modules/@babel/helper-plugin-utils": { "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-simple-access": { + "node_modules/@babel/helper-simple-access": { "version": "7.19.4", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.19.4" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-split-export-declaration": { + "node_modules/@babel/helper-split-export-declaration": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-string-parser": { + "node_modules/@babel/helper-string-parser": { "version": "7.19.4", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-validator-identifier": { + "node_modules/@babel/helper-validator-identifier": { "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-validator-option": { + "node_modules/@babel/helper-validator-option": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helpers": { + "node_modules/@babel/helpers": { "version": "7.19.4", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", "dev": true, - "requires": { + "dependencies": { "@babel/template": "^7.18.10", "@babel/traverse": "^7.19.4", "@babel/types": "^7.19.4" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/highlight": { + "node_modules/@babel/highlight": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/parser": { + "node_modules/@babel/parser": { "version": "7.19.4", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==", - "dev": true + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } }, - "@babel/plugin-syntax-async-generators": { + "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-bigint": { + "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-class-properties": { + "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-import-meta": { + "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-json-strings": { + "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-logical-assignment-operators": { + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-nullish-coalescing-operator": { + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-numeric-separator": { + "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-object-rest-spread": { + "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-catch-binding": { + "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-chaining": { + "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-top-level-await": { + "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-typescript": { + "node_modules/@babel/plugin-syntax-typescript": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/runtime": { + "node_modules/@babel/runtime": { "version": "7.19.4", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", "dev": true, - "requires": { + "dependencies": { "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/template": { + "node_modules/@babel/template": { "version": "7.18.10", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.18.6", "@babel/parser": "^7.18.10", "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/traverse": { + "node_modules/@babel/traverse": { "version": "7.23.2", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.22.13", "@babel/generator": "^7.23.0", "@babel/helper-environment-visitor": "^7.22.20", @@ -359,190 +508,243 @@ "debug": "^4.1.0", "globals": "^11.1.0" }, - "dependencies": { - "@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "dev": true, - "requires": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" - } - }, - "@babel/generator": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", - "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", - "dev": true, - "requires": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true - }, - "@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", - "dev": true - }, - "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" - } - }, - "@babel/types": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", - "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } + "engines": { + "node": ">=6.9.0" } }, - "@babel/types": { + "node_modules/@babel/traverse/node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/highlight": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/parser": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/types": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { "version": "7.19.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-string-parser": "^7.19.4", "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@bcoe/v8-coverage": { + "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@cspotcode/source-map-support": { + "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "requires": { + "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } + "engines": { + "node": ">=12" } }, - "@istanbuljs/load-nyc-config": { + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "requires": { + "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "@istanbuljs/schema": { + "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "@jest/console": { + "node_modules/@jest/console": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", "dev": true, - "requires": { + "dependencies": { "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", @@ -550,64 +752,86 @@ "jest-util": "^28.1.3", "slash": "^3.0.0" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@jest/core": { + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/console/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", "dev": true, - "requires": { + "dependencies": { "@jest/console": "^28.1.3", "@jest/reporters": "^28.1.3", "@jest/test-result": "^28.1.3", @@ -638,154 +862,207 @@ "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true } } }, - "@jest/environment": { + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/core/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, - "requires": { + "dependencies": { "@jest/fake-timers": "^28.1.3", "@jest/types": "^28.1.3", "@types/node": "*", "jest-mock": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@jest/expect": { + "node_modules/@jest/expect": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", "dev": true, - "requires": { + "dependencies": { "expect": "^28.1.3", "jest-snapshot": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@jest/expect-utils": { + "node_modules/@jest/expect-utils": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", "dev": true, - "requires": { + "dependencies": { "jest-get-type": "^28.0.2" }, - "dependencies": { - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@jest/fake-timers": { + "node_modules/@jest/expect-utils/node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/fake-timers": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, - "requires": { + "dependencies": { "@jest/types": "^28.1.3", "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", "jest-message-util": "^28.1.3", "jest-mock": "^28.1.3", "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@jest/globals": { + "node_modules/@jest/globals": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", "dev": true, - "requires": { + "dependencies": { "@jest/environment": "^28.1.3", "@jest/expect": "^28.1.3", "@jest/types": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@jest/reporters": { + "node_modules/@jest/reporters": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", "dev": true, - "requires": { + "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@jest/console": "^28.1.3", "@jest/test-result": "^28.1.3", @@ -812,108 +1089,150 @@ "terminal-link": "^2.0.0", "v8-to-istanbul": "^9.0.1" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true } } }, - "@jest/schemas": { + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", "dev": true, - "requires": { + "dependencies": { "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@jest/source-map": { + "node_modules/@jest/source-map": { "version": "28.1.2", "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", "dev": true, - "requires": { + "dependencies": { "@jridgewell/trace-mapping": "^0.3.13", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@jest/test-result": { + "node_modules/@jest/test-result": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", "dev": true, - "requires": { + "dependencies": { "@jest/console": "^28.1.3", "@jest/types": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@jest/test-sequencer": { + "node_modules/@jest/test-sequencer": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", "dev": true, - "requires": { + "dependencies": { "@jest/test-result": "^28.1.3", "graceful-fs": "^4.2.9", "jest-haste-map": "^28.1.3", "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@jest/transform": { + "node_modules/@jest/transform": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", "dev": true, - "requires": { + "dependencies": { "@babel/core": "^7.11.6", "@jest/types": "^28.1.3", "@jridgewell/trace-mapping": "^0.3.13", @@ -930,64 +1249,86 @@ "slash": "^3.0.0", "write-file-atomic": "^4.0.1" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@jest/types": { + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, - "requires": { + "dependencies": { "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -995,150 +1336,181 @@ "@types/yargs": "^17.0.8", "chalk": "^4.0.0" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@jridgewell/gen-mapping": { + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", "dev": true, - "requires": { + "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" } }, - "@jridgewell/resolve-uri": { + "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.0.0" + } }, - "@jridgewell/set-array": { + "node_modules/@jridgewell/set-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.0.0" + } }, - "@jridgewell/sourcemap-codec": { + "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, - "@jridgewell/trace-mapping": { + "node_modules/@jridgewell/trace-mapping": { "version": "0.3.17", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, - "requires": { + "dependencies": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" } }, - "@sinclair/typebox": { + "node_modules/@sinclair/typebox": { "version": "0.24.46", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.46.tgz", "integrity": "sha512-ng4ut1z2MCBhK/NwDVwIQp3pAUOCs/KNaW3cBxdFB2xTDrOuo1xuNmpr/9HHFhxqIvHrs1NTH3KJg6q+JSy1Kw==", "dev": true }, - "@sinonjs/commons": { + "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, - "requires": { + "dependencies": { "type-detect": "4.0.8" } }, - "@sinonjs/fake-timers": { + "node_modules/@sinonjs/fake-timers": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", "dev": true, - "requires": { + "dependencies": { "@sinonjs/commons": "^1.7.0" } }, - "@tsconfig/node10": { + "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", "dev": true }, - "@tsconfig/node12": { + "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true }, - "@tsconfig/node14": { + "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, - "@tsconfig/node16": { + "node_modules/@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, - "@types/babel__core": { + "node_modules/@types/babel__core": { "version": "7.1.19", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", "dev": true, - "requires": { + "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0", "@types/babel__generator": "*", @@ -1146,205 +1518,231 @@ "@types/babel__traverse": "*" } }, - "@types/babel__generator": { + "node_modules/@types/babel__generator": { "version": "7.6.4", "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.0.0" } }, - "@types/babel__template": { + "node_modules/@types/babel__template": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, - "requires": { + "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, - "@types/babel__traverse": { + "node_modules/@types/babel__traverse": { "version": "7.18.2", "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.3.0" } }, - "@types/graceful-fs": { + "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", "dev": true, - "requires": { + "dependencies": { "@types/node": "*" } }, - "@types/istanbul-lib-coverage": { + "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, - "@types/istanbul-lib-report": { + "node_modules/@types/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "dev": true, - "requires": { + "dependencies": { "@types/istanbul-lib-coverage": "*" } }, - "@types/istanbul-reports": { + "node_modules/@types/istanbul-reports": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, - "requires": { + "dependencies": { "@types/istanbul-lib-report": "*" } }, - "@types/jest": { + "node_modules/@types/jest": { "version": "27.5.2", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", "dev": true, - "requires": { + "dependencies": { "jest-matcher-utils": "^27.0.0", "pretty-format": "^27.0.0" } }, - "@types/node": { + "node_modules/@types/node": { "version": "17.0.45", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", "dev": true }, - "@types/prettier": { + "node_modules/@types/prettier": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", "dev": true }, - "@types/sprintf-js": { + "node_modules/@types/sprintf-js": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@types/sprintf-js/-/sprintf-js-1.1.2.tgz", "integrity": "sha512-hkgzYF+qnIl8uTO8rmUSVSfQ8BIfMXC4yJAF4n8BE758YsKBZvFC4NumnAegj7KmylP0liEZNpb9RRGFMbFejA==", "dev": true }, - "@types/stack-utils": { + "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, - "@types/yargs": { + "node_modules/@types/yargs": { "version": "17.0.13", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", "dev": true, - "requires": { + "dependencies": { "@types/yargs-parser": "*" } }, - "@types/yargs-parser": { + "node_modules/@types/yargs-parser": { "version": "21.0.0", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, - "acorn": { + "node_modules/acorn": { "version": "8.8.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, - "acorn-walk": { + "node_modules/acorn-walk": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.4.0" + } }, - "ansi-escapes": { + "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, - "requires": { + "dependencies": { "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "ansi-regex": { + "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "ansi-styles": { + "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "requires": { + "dependencies": { "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "anymatch": { + "node_modules/anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, - "requires": { + "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "arg": { + "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, - "argparse": { + "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - }, "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - } + "sprintf-js": "~1.0.2" } }, - "array-back": { + "node_modules/argparse/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/array-back": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "async-mutex": { + "node_modules/async-mutex": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz", "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==", - "requires": { + "dependencies": { "tslib": "^2.3.1" } }, - "babel-jest": { + "node_modules/babel-jest": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", "dev": true, - "requires": { + "dependencies": { "@jest/transform": "^28.1.3", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", @@ -1353,89 +1751,120 @@ "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "babel-plugin-istanbul": { + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/babel-jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-instrument": "^5.0.4", "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" } }, - "babel-plugin-jest-hoist": { + "node_modules/babel-plugin-jest-hoist": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", "dev": true, - "requires": { + "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", "@types/babel__core": "^7.1.14", "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "babel-preset-current-node-syntax": { + "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, - "requires": { + "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", "@babel/plugin-syntax-class-properties": "^7.8.3", @@ -1448,365 +1877,461 @@ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "babel-preset-jest": { + "node_modules/babel-preset-jest": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", "dev": true, - "requires": { + "dependencies": { "babel-plugin-jest-hoist": "^28.1.3", "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "balanced-match": { + "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "bluebird": { + "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, - "brace-expansion": { + "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "requires": { + "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "braces": { + "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, - "requires": { + "dependencies": { "fill-range": "^7.1.1" }, - "dependencies": { - "fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - } + "engines": { + "node": ">=8" } }, - "browserslist": { + "node_modules/braces/node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { "version": "4.21.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "dev": true, - "requires": { + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { "caniuse-lite": "^1.0.30001400", "electron-to-chromium": "^1.4.251", "node-releases": "^2.0.6", "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "bs-logger": { + "node_modules/bs-logger": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, - "requires": { + "dependencies": { "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" } }, - "bser": { + "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, - "requires": { + "dependencies": { "node-int64": "^0.4.0" } }, - "buffer-from": { + "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "call-bind": { + "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "callsites": { + "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "camelcase": { + "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "caniuse-lite": { + "node_modules/caniuse-lite": { "version": "1.0.30001419", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001419.tgz", "integrity": "sha512-aFO1r+g6R7TW+PNQxKzjITwLOyDhVRLjW0LcwS/HCZGUUKTGNp9+IwLC4xyDSZBygVL/mxaFR3HIV6wEKQuSzw==", - "dev": true + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] }, - "chalk": { + "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "char-regex": { + "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "check-engine": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/check-engine/-/check-engine-1.10.1.tgz", - "integrity": "sha512-KqZ6sV7onqcc81qoK+NsCNjNfik1rRHzmxYJ+tDdCc+6nbpaj0X8SKSzb8lYIcQ+ire5ypMr4YP832/7RH843Q==", "dev": true, - "requires": { - "bluebird": "3.7.2", - "colors": "1.4.0", - "command-line-usage": "6.1.0", - "jsonfile": "6.0.1", - "semver": "7.3.2", - "yargs": "16.1.0" - }, - "dependencies": { - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "yargs": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.0.tgz", - "integrity": "sha512-upWFJOmDdHN0syLuESuvXDmrRcWd1QafJolHskzaw79uZa7/x53gxQKiR07W59GWY1tFhhU/Th9DrtSfpS782g==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.2", - "yargs-parser": "^20.2.2" - } - } + "engines": { + "node": ">=10" } }, - "ci-info": { + "node_modules/check-engine": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/check-engine/-/check-engine-1.14.0.tgz", + "integrity": "sha512-CZZ3UmZKMer4O63yNWit5KLm7FoO69shcdPbkP8Dj4N728jqI7d8YyAigOgKnajVBA7TtaL7BuaMRDXcoYJKxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "3.7.2", + "colors": "1.4.0", + "command-line-usage": "6.1.3", + "jsonfile": "6.1.0", + "semver": "7.5.4", + "yargs": "17.7.1" + }, + "bin": { + "check-engine": "bin/check-engine.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/check-engine/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", "dev": true }, - "cjs-module-lexer": { + "node_modules/cjs-module-lexer": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "co": { + "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } }, - "collect-v8-coverage": { + "node_modules/collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, - "color-convert": { + "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "requires": { + "dependencies": { "color-name": "1.1.3" } }, - "color-name": { + "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "colors": { + "node_modules/colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "command-line-usage": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.0.tgz", - "integrity": "sha512-Ew1clU4pkUeo6AFVDFxCbnN7GIZfXl48HIOQeFQnkO3oOqvpI7wdqtLRwv9iOCZ/7A+z4csVZeiDdEcj8g6Wiw==", "dev": true, - "requires": { - "array-back": "^4.0.0", - "chalk": "^2.4.2", - "table-layout": "^1.0.0", - "typical": "^5.2.0" + "engines": { + "node": ">=0.1.90" } }, - "concat-map": { + "node_modules/command-line-usage": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", + "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "convert-source-map": { + "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, - "create-require": { + "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, - "cross-spawn": { + "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, - "requires": { + "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" } }, - "debug": { + "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "requires": { + "dependencies": { "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "dedent": { + "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, - "deep-extend": { + "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } }, - "deepmerge": { + "node_modules/deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "define-properties": { + "node_modules/define-properties": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, - "requires": { + "dependencies": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "detect-newline": { + "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "diff": { + "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.3.1" + } }, - "diff-sequences": { + "node_modules/diff-sequences": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } }, - "electron-to-chromium": { + "node_modules/electron-to-chromium": { "version": "1.4.282", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.282.tgz", "integrity": "sha512-Dki0WhHNh/br/Xi1vAkueU5mtIc9XLHcMKB6tNfQKk+kPG0TEUjRh5QEMAUbRp30/rYNMFD1zKKvbVzwq/4wmg==", "dev": true }, - "emittery": { + "node_modules/emittery": { "version": "0.10.2", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", - "dev": true + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } }, - "emoji-regex": { + "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "error-ex": { + "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, - "requires": { + "dependencies": { "is-arrayish": "^0.2.1" } }, - "es-abstract": { + "node_modules/es-abstract": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", @@ -1830,43 +2355,68 @@ "string.prototype.trimend": "^1.0.5", "string.prototype.trimstart": "^1.0.5", "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "es-to-primitive": { + "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, - "requires": { + "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "escalade": { + "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "escape-string-regexp": { + "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.0" + } }, - "esprima": { + "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, - "execa": { + "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, - "requires": { + "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", @@ -1877,756 +2427,964 @@ "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "exit": { + "node_modules/execa/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "expect": { + "node_modules/expect": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", "dev": true, - "requires": { + "dependencies": { "@jest/expect-utils": "^28.1.3", "jest-get-type": "^28.0.2", "jest-matcher-utils": "^28.1.3", "jest-message-util": "^28.1.3", "jest-util": "^28.1.3" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "diff-sequences": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", - "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-diff": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", - "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^28.1.1", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - } - }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, - "jest-matcher-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", - "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - } - }, - "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "fast-json-stable-stringify": { + "node_modules/expect/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/expect/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/expect/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/expect/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/expect/node_modules/diff-sequences": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/expect/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/expect/node_modules/jest-diff": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/expect/node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/expect/node_modules/jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/expect/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/expect/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/expect/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/expect/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, - "fb-watchman": { + "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, - "requires": { + "dependencies": { "bser": "2.1.1" } }, - "find-up": { + "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "requires": { + "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "fsevents": { + "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "optional": true + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } }, - "function-bind": { + "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "function.prototype.name": { + "node_modules/function.prototype.name": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", "es-abstract": "^1.19.0", "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "functions-have-names": { + "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "gensync": { + "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "get-caller-file": { + "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, - "get-intrinsic": { + "node_modules/get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "get-package-type": { + "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=8.0.0" + } }, - "get-stream": { + "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "get-symbol-description": { + "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "glob": { + "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "requires": { + "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "globals": { + "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "graceful-fs": { + "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, - "has": { + "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" } }, - "has-bigints": { + "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "has-flag": { + "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "has-property-descriptors": { + "node_modules/has-property-descriptors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", "dev": true, - "requires": { + "dependencies": { "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "has-symbols": { + "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "has-tostringtag": { + "node_modules/has-tostringtag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, - "requires": { + "dependencies": { "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "hosted-git-info": { + "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, - "html-escaper": { + "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "human-signals": { + "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true + "dev": true, + "engines": { + "node": ">=10.17.0" + } }, - "import-local": { + "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, - "requires": { + "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "imurmurhash": { + "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.19" + } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, - "requires": { + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "internal-slot": { + "node_modules/internal-slot": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, - "requires": { + "dependencies": { "get-intrinsic": "^1.1.0", "has": "^1.0.3", "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" } }, - "is-arrayish": { + "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "is-bigint": { + "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, - "requires": { + "dependencies": { "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-boolean-object": { + "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-callable": { + "node_modules/is-callable": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-core-module": { + "node_modules/is-core-module": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", "dev": true, - "requires": { + "dependencies": { "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-date-object": { + "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, - "requires": { + "dependencies": { "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-fullwidth-code-point": { + "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "is-generator-fn": { + "node_modules/is-generator-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "is-negative-zero": { + "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-number": { + "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.12.0" + } }, - "is-number-object": { + "node_modules/is-number-object": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, - "requires": { + "dependencies": { "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-regex": { + "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-shared-array-buffer": { + "node_modules/is-shared-array-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-stream": { + "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "is-string": { + "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, - "requires": { + "dependencies": { "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-symbol": { + "node_modules/is-symbol": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, - "requires": { + "dependencies": { "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-weakref": { + "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "isexe": { + "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "istanbul-lib-coverage": { + "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "istanbul-lib-instrument": { + "node_modules/istanbul-lib-instrument": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, - "requires": { + "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "engines": { + "node": ">=8" } }, - "istanbul-lib-report": { + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, - "requires": { + "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", "supports-color": "^7.1.0" }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": ">=8" } }, - "istanbul-lib-source-maps": { + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, - "requires": { + "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" } }, - "istanbul-reports": { + "node_modules/istanbul-reports": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, - "requires": { + "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "iter-tools": { + "node_modules/iter-tools": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/iter-tools/-/iter-tools-7.5.0.tgz", "integrity": "sha512-L0p/RG3Hwk1urilryDKqU8pQ1t5AaaMc7CHmiwJD/uh63Lv7VyjNng/esstf+Tct1587IpetpcDFdufz8sG+sQ==", "dev": true, - "requires": { + "dependencies": { "@babel/runtime": "^7.12.1" } }, - "jest": { + "node_modules/jest": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", "dev": true, - "requires": { + "dependencies": { "@jest/core": "^28.1.3", "@jest/types": "^28.1.3", "import-local": "^3.0.2", "jest-cli": "^28.1.3" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-cli": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", - "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", - "dev": true, - "requires": { - "@jest/core": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^28.1.3", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true } } }, - "jest-changed-files": { + "node_modules/jest-changed-files": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", "dev": true, - "requires": { + "dependencies": { "execa": "^5.0.0", "p-limit": "^3.1.0" }, - "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-circus": { + "node_modules/jest-changed-files/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-circus": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", "dev": true, - "requires": { + "dependencies": { "@jest/environment": "^28.1.3", "@jest/expect": "^28.1.3", "@jest/test-result": "^28.1.3", @@ -2647,135 +3405,182 @@ "slash": "^3.0.0", "stack-utils": "^2.0.3" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "diff-sequences": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", - "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-diff": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", - "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^28.1.1", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - } - }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, - "jest-matcher-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", - "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-config": { + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-circus/node_modules/diff-sequences": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/jest-diff": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-circus/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", "dev": true, - "requires": { + "dependencies": { "@babel/core": "^7.11.6", "@jest/test-sequencer": "^28.1.3", "@jest/types": "^28.1.3", @@ -2799,421 +3604,574 @@ "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } + "ts-node": { + "optional": true } } }, - "jest-diff": { + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-config/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-config/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", "dev": true, - "requires": { + "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^27.5.1", "jest-get-type": "^27.5.1", "pretty-format": "^27.5.1" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "jest-docblock": { + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { "version": "28.1.1", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz", "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==", "dev": true, - "requires": { + "dependencies": { "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-each": { + "node_modules/jest-each": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", "dev": true, - "requires": { + "dependencies": { "@jest/types": "^28.1.3", "chalk": "^4.0.0", "jest-get-type": "^28.0.2", "jest-util": "^28.1.3", "pretty-format": "^28.1.3" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, - "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-environment-node": { + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-each/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-each/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-node": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", "dev": true, - "requires": { + "dependencies": { "@jest/environment": "^28.1.3", "@jest/fake-timers": "^28.1.3", "@jest/types": "^28.1.3", "@types/node": "*", "jest-mock": "^28.1.3", "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-get-type": { + "node_modules/jest-get-type": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } }, - "jest-haste-map": { + "node_modules/jest-haste-map": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", "dev": true, - "requires": { + "dependencies": { "@jest/types": "^28.1.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", "jest-regex-util": "^28.0.2", "jest-util": "^28.1.3", "jest-worker": "^28.1.3", "micromatch": "^4.0.4", "walker": "^1.0.8" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "jest-leak-detector": { + "node_modules/jest-leak-detector": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", "dev": true, - "requires": { + "dependencies": { "jest-get-type": "^28.0.2", "pretty-format": "^28.1.3" }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, - "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-matcher-utils": { + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-leak-detector/node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-matcher-utils": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "dev": true, - "requires": { + "dependencies": { "chalk": "^4.0.0", "jest-diff": "^27.5.1", "jest-get-type": "^27.5.1", "pretty-format": "^27.5.1" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "jest-message-util": { + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", @@ -3224,112 +4182,158 @@ "slash": "^3.0.0", "stack-utils": "^2.0.3" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-mock": { + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, - "requires": { + "dependencies": { "@jest/types": "^28.1.3", "@types/node": "*" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-pnp-resolver": { + "node_modules/jest-pnp-resolver": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } }, - "jest-regex-util": { + "node_modules/jest-regex-util": { "version": "28.0.2", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", - "dev": true + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } }, - "jest-resolve": { + "node_modules/jest-resolve": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", "dev": true, - "requires": { + "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "jest-haste-map": "^28.1.3", @@ -3340,74 +4344,99 @@ "resolve.exports": "^1.1.0", "slash": "^3.0.0" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-resolve-dependencies": { + "node_modules/jest-resolve-dependencies": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", "dev": true, - "requires": { + "dependencies": { "jest-regex-util": "^28.0.2", "jest-snapshot": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-runner": { + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", "dev": true, - "requires": { + "dependencies": { "@jest/console": "^28.1.3", "@jest/environment": "^28.1.3", "@jest/test-result": "^28.1.3", @@ -3430,73 +4459,101 @@ "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-runtime": { + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", "dev": true, - "requires": { + "dependencies": { "@jest/environment": "^28.1.3", "@jest/fake-timers": "^28.1.3", "@jest/globals": "^28.1.3", @@ -3520,70 +4577,95 @@ "slash": "^3.0.0", "strip-bom": "^4.0.0" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-snapshot": { + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", "dev": true, - "requires": { + "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", @@ -3608,135 +4690,180 @@ "pretty-format": "^28.1.3", "semver": "^7.3.5" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "diff-sequences": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", - "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-diff": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", - "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^28.1.1", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - } - }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, - "jest-matcher-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", - "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - } - }, - "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-util": { + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, - "requires": { + "dependencies": { "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", @@ -3744,64 +4871,86 @@ "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-validate": { + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", "dev": true, - "requires": { + "dependencies": { "@jest/types": "^28.1.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", @@ -3809,102 +4958,140 @@ "leven": "^3.1.0", "pretty-format": "^28.1.3" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, - "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-watcher": { + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-validate/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", "dev": true, - "requires": { + "dependencies": { "@jest/test-result": "^28.1.3", "@jest/types": "^28.1.3", "@types/node": "*", @@ -3914,331 +5101,530 @@ "jest-util": "^28.1.3", "string-length": "^4.0.1" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "jest-worker": { + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", "dev": true, - "requires": { + "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest/node_modules/jest-cli": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", + "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", + "dev": true, + "dependencies": { + "@jest/core": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true } } }, - "js-tokens": { + "node_modules/jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "js-yaml": { + "node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "requires": { + "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "jsesc": { + "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } }, - "json-parse-better-errors": { + "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "json-parse-even-better-errors": { + "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "json5": { + "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } }, - "jsonc-parser": { + "node_modules/jsonc-parser": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "dev": true }, - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "kleur": { + "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "leven": { + "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "lines-and-columns": { + "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, - "load-json-file": { + "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, - "requires": { + "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "locate-path": { + "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "requires": { + "dependencies": { "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" } }, - "lodash.memoize": { + "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, - "lru-cache": { + "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "requires": { + "dependencies": { "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "lunr": { + "node_modules/lunr": { "version": "2.3.9", "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", "dev": true }, - "make-dir": { + "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, - "requires": { + "dependencies": { "semver": "^6.0.0" }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "make-error": { + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "makeerror": { + "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, - "requires": { + "dependencies": { "tmpl": "1.0.5" } }, - "marked": { + "node_modules/marked": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz", "integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==", - "dev": true + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } }, - "memorystream": { + "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.10.0" + } }, - "merge-stream": { + "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, - "requires": { - "braces": "^3.0.2", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" } }, - "mimic-fn": { + "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "minimatch": { + "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "requires": { + "dependencies": { "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "ms": { + "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "natural-compare": { + "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "nice-try": { + "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "node-int64": { + "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "node-releases": { + "node_modules/node-releases": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, - "normalize-package-data": { + "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, - "requires": { + "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, - "normalize-path": { + "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "npm-run-all": { + "node_modules/npm-run-all": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^3.2.1", "chalk": "^2.4.1", "cross-spawn": "^6.0.5", @@ -4248,622 +5634,848 @@ "read-pkg": "^3.0.0", "shell-quote": "^1.6.1", "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" } }, - "npm-run-path": { + "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, - "requires": { + "dependencies": { "path-key": "^3.0.0" }, - "dependencies": { - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - } + "engines": { + "node": ">=8" } }, - "object-inspect": { + "node_modules/npm-run-path/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.1.tgz", "integrity": "sha512-Y/jF6vnvEtOPGiKD1+q+X0CiUYRQtEHp89MLLUJ7TUivtH8Ugn2+3A7Rynqk7BRsAoqeOQWnFnjpDrKSxDgIGA==", - "dev": true + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "object-keys": { + "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + } }, - "object.assign": { + "node_modules/object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", "has-symbols": "^1.0.1", "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "requires": { + "dependencies": { "wrappy": "1" } }, - "onetime": { + "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "requires": { + "dependencies": { "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-limit": { + "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "requires": { + "dependencies": { "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-locate": { + "node_modules/p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "requires": { + "dependencies": { "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "p-try": { + "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "parse-json": { + "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, - "requires": { + "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" } }, - "path-exists": { + "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-key": { + "node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "path-parse": { + "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-type": { + "node_modules/path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, - "requires": { + "dependencies": { "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "picocolors": { + "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "picomatch": { + "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, - "pidtree": { + "node_modules/pidtree": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", - "dev": true + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } }, - "pify": { + "node_modules/pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "pirates": { + "node_modules/pirates": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true + "dev": true, + "engines": { + "node": ">= 6" + } }, - "pkg-dir": { + "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, - "requires": { + "dependencies": { "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "prettier": { + "node_modules/prettier": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } }, - "pretty-format": { + "node_modules/pretty-format": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, - "requires": { + "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "prompts": { + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, - "requires": { + "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" } }, - "react-is": { + "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "read-pkg": { + "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", "dev": true, - "requires": { + "dependencies": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "reduce-flatten": { + "node_modules/reduce-flatten": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "regenerator-runtime": { + "node_modules/regenerator-runtime": { "version": "0.13.10", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==", "dev": true }, - "regexp.prototype.flags": { + "node_modules/regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "require-directory": { + "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "resolve": { + "node_modules/resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", "dev": true, - "requires": { + "dependencies": { "is-core-module": "^2.8.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "resolve-cwd": { + "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, - "requires": { + "dependencies": { "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "resolve-from": { + "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "resolve.exports": { + "node_modules/resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + } }, - "rimraf": { + "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, - "requires": { + "dependencies": { "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } }, - "shebang-command": { + "node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, - "requires": { + "dependencies": { "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "shebang-regex": { + "node_modules/shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "shell-quote": { + "node_modules/shell-quote": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", "dev": true }, - "shiki": { + "node_modules/shiki": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.11.1.tgz", "integrity": "sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==", "dev": true, - "requires": { + "dependencies": { "jsonc-parser": "^3.0.0", "vscode-oniguruma": "^1.6.1", "vscode-textmate": "^6.0.0" } }, - "side-channel": { + "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "signal-exit": { + "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "sisteransi": { + "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, - "slash": { + "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "source-map": { + "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "source-map-support": { + "node_modules/source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, - "requires": { + "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, - "spdx-correct": { + "node_modules/spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, - "requires": { + "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-exceptions": { + "node_modules/spdx-exceptions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, - "spdx-expression-parse": { + "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "requires": { + "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-license-ids": { + "node_modules/spdx-license-ids": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", "dev": true }, - "sprintf-js": { + "node_modules/sprintf-js": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true }, - "stack-utils": { + "node_modules/stack-utils": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, - "requires": { + "dependencies": { "escape-string-regexp": "^2.0.0" }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } + "engines": { + "node": ">=10" } }, - "string-length": { + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, - "requires": { + "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" } }, - "string-width": { + "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { + "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "string.prototype.padend": { + "node_modules/string.prototype.padend": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz", "integrity": "sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "string.prototype.trimend": { + "node_modules/string.prototype.trimend": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "string.prototype.trimstart": { + "node_modules/string.prototype.trimstart": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "strip-ansi": { + "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { + "dependencies": { "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-bom": { + "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "strip-final-newline": { + "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "strip-json-comments": { + "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "supports-color": { + "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "requires": { + "dependencies": { "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "supports-hyperlinks": { + "node_modules/supports-hyperlinks": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "dev": true, - "requires": { + "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": ">=8" } }, - "supports-preserve-symlinks-flag": { + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "table-layout": { + "node_modules/table-layout": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "array-back": "^4.0.1", "deep-extend": "~0.6.0", "typical": "^5.2.0", "wordwrapjs": "^4.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "terminal-link": { + "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", "dev": true, - "requires": { + "dependencies": { "ansi-escapes": "^4.2.1", "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "test-exclude": { + "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "requires": { + "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" } }, - "tmpl": { + "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, - "to-fast-properties": { + "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "to-regex-range": { + "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "requires": { + "dependencies": { "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "ts-expect": { + "node_modules/ts-expect": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-expect/-/ts-expect-1.3.0.tgz", "integrity": "sha512-e4g0EJtAjk64xgnFPD6kTBUtpnMVzDrMb12N1YZV0VvSlhnVT3SGxiYTLdGy8Q5cYHOIC/FAHmZ10eGrAguicQ==", "dev": true }, - "ts-jest": { + "node_modules/ts-jest": { "version": "28.0.8", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz", "integrity": "sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==", "dev": true, - "requires": { + "dependencies": { "bs-logger": "0.x", "fast-json-stable-stringify": "2.x", "jest-util": "^28.0.0", @@ -4873,30 +6485,62 @@ "semver": "7.x", "yargs-parser": "^21.0.1" }, - "dependencies": { - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^28.0.0", + "babel-jest": "^28.0.0", + "jest": "^28.0.0", + "typescript": ">=4.3" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true } } }, - "ts-node": { + "node_modules/ts-jest/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, - "requires": { + "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", @@ -4910,293 +6554,411 @@ "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, - "tslib": { + "node_modules/tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, - "type-detect": { + "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "type-fest": { + "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "typedoc": { + "node_modules/typedoc": { "version": "0.23.16", "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.16.tgz", "integrity": "sha512-rumYsCeNRXlyuZVzefD7050n7ptL2uudsCJg50dY0v/stKniqIlRpvx/F/6expC0/Q6Dbab+g/JpZuB7Sw90FA==", "dev": true, - "requires": { + "dependencies": { "lunr": "^2.3.9", "marked": "^4.0.19", "minimatch": "^5.1.0", "shiki": "^0.11.1" }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 14.14" + }, + "peerDependencies": { + "typescript": "4.6.x || 4.7.x || 4.8.x" } }, - "typescript": { + "node_modules/typedoc/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typescript": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } }, - "typical": { + "node_modules/typical": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "unbox-primitive": { + "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", - "dev": true + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } }, - "update-browserslist-db": { + "node_modules/update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, - "requires": { + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "v8-compile-cache-lib": { + "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, - "v8-to-istanbul": { + "node_modules/v8-to-istanbul": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", "dev": true, - "requires": { + "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" } }, - "validate-npm-package-license": { + "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { + "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, - "vscode-oniguruma": { + "node_modules/vscode-oniguruma": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz", "integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==", "dev": true }, - "vscode-textmate": { + "node_modules/vscode-textmate": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-6.0.0.tgz", "integrity": "sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==", "dev": true }, - "walker": { + "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, - "requires": { + "dependencies": { "makeerror": "1.0.12" } }, - "which": { + "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" } }, - "which-boxed-primitive": { + "node_modules/which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "requires": { + "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", "is-number-object": "^1.0.4", "is-string": "^1.0.5", "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "wordwrapjs": { + "node_modules/wordwrapjs": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "reduce-flatten": "^2.0.0", "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "wrap-ansi": { + "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "wrappy": { + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "write-file-atomic": { + "node_modules/write-file-atomic": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, - "requires": { + "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "y18n": { + "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + } }, - "yallist": { + "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "yargs": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", - "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", + "node_modules/yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" }, - "dependencies": { - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - } + "engines": { + "node": ">=12" } }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true + "node_modules/yargs/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } }, - "yn": { + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "yocto-queue": { + "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/src/api/js/package.json b/src/api/js/package.json index 3e79ba8f4..bc6e006d4 100644 --- a/src/api/js/package.json +++ b/src/api/js/package.json @@ -29,7 +29,7 @@ "clean": "rimraf build 'src/**/*.__GENERATED__.*'", "lint": "prettier -c '{./,src/,scripts/,examples/}**/*.{js,ts}'", "format": "prettier --write '{./,src/,scripts/}**/*.{js,ts}'", - "test": "jest", + "test": "node --expose-gc ./node_modules/.bin/jest", "docs": "typedoc", "check-engine": "check-engine" }, diff --git a/src/api/js/scripts/build-wasm.ts b/src/api/js/scripts/build-wasm.ts index 5bdbdea3b..497b67c10 100644 --- a/src/api/js/scripts/build-wasm.ts +++ b/src/api/js/scripts/build-wasm.ts @@ -69,7 +69,7 @@ const fns = JSON.stringify(exportedFuncs()); const methods = '["ccall","FS","allocate","UTF8ToString","intArrayFromString","ALLOC_NORMAL"]'; const libz3a = path.normalize('../../../build/libz3.a'); spawnSync( - `emcc build/async-fns.cc ${libz3a} --std=c++20 --pre-js src/low-level/async-wrapper.js -g2 -pthread -fexceptions -s WASM_BIGINT -s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=0 -s PTHREAD_POOL_SIZE_STRICT=0 -s MODULARIZE=1 -s 'EXPORT_NAME="initZ3"' -s EXPORTED_RUNTIME_METHODS=${methods} -s EXPORTED_FUNCTIONS=${fns} -s DISABLE_EXCEPTION_CATCHING=0 -s SAFE_HEAP=0 -s DEMANGLE_SUPPORT=1 -s TOTAL_MEMORY=1GB -s TOTAL_STACK=20MB -I z3/src/api/ -o build/z3-built.js`, + `emcc build/async-fns.cc ${libz3a} --std=c++20 --pre-js src/low-level/async-wrapper.js -g2 -pthread -fexceptions -s WASM_BIGINT -s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=0 -s PTHREAD_POOL_SIZE_STRICT=0 -s MODULARIZE=1 -s 'EXPORT_NAME="initZ3"' -s EXPORTED_RUNTIME_METHODS=${methods} -s EXPORTED_FUNCTIONS=${fns} -s DISABLE_EXCEPTION_CATCHING=0 -s SAFE_HEAP=0 -s DEMANGLE_SUPPORT=1 -s TOTAL_MEMORY=2GB -s TOTAL_STACK=20MB -I z3/src/api/ -o build/z3-built.js`, ); fs.rmSync(ccWrapperPath); diff --git a/src/api/js/src/high-level/high-level.test.ts b/src/api/js/src/high-level/high-level.test.ts index 99f95e5b4..f36291764 100644 --- a/src/api/js/src/high-level/high-level.test.ts +++ b/src/api/js/src/high-level/high-level.test.ts @@ -4,6 +4,12 @@ import { init, killThreads } from '../jest'; import { Arith, Bool, Model, Quantifier, Z3AssertionError, Z3HighLevel, AstVector } from './types'; import { expectType } from 'ts-expect'; +// this should not be necessary but there may be a Jest bug +// https://github.com/jestjs/jest/issues/7874 +afterEach(() => { + global.gc && global.gc(); +}); + /** * Generate all possible solutions from given assumptions. * @@ -355,6 +361,7 @@ describe('high-level', () => { }); }); + describe('bitvectors', () => { it('can do simple proofs', async () => { const { BitVec, Concat, Implies, isBitVecVal } = api.Context('main'); @@ -373,7 +380,7 @@ describe('high-level', () => { const y = BitVec.const('y', 32); await prove(Implies(Concat(x, y).eq(Concat(y, x)), x.eq(y))); - }); + }, 10_000 /* timeout ms */); it('finds x and y such that: x ^ y - 103 == x * y', async () => { const { BitVec, isBitVecVal } = api.Context('main'); @@ -393,6 +400,7 @@ describe('high-level', () => { }); }); + describe('arrays', () => { it('Example 1', async () => { const Z3 = api.Context('main'); @@ -447,7 +455,7 @@ describe('high-level', () => { await prove(Eq(arr2.select(0), FIVE_VAL)); await prove(Not(Eq(arr2.select(0), BitVec.val(6, 256)))); await prove(Eq(arr2.store(idx, val).select(idx), constArr.store(idx, val).select(idx))); - }); + }, 10_000 /* timeout ms */); it('Finds arrays that differ but that sum to the same', async () => { const Z3 = api.Context('main'); diff --git a/src/api/julia/README.md b/src/api/julia/README.md index 12e846191..f64b0c4ab 100644 --- a/src/api/julia/README.md +++ b/src/api/julia/README.md @@ -1,6 +1,8 @@ # Julia bindings -The Julia package [Z3.jl](https://github.com/ahumenberger/Z3.jl) provides and interface to Z3 by exposing its C++ API via [CxxWrap.jl](https://github.com/JuliaInterop/CxxWrap.jl). The bindings therefore consist of a [C++ part](z3jl.cpp) and a [Julia part](https://github.com/ahumenberger/Z3.jl). The C++ part defines the Z3 types/methods which are exposed. The resulting library is loaded in the Julia part via CxxWrap.jl which creates the corresponding Julia types/methods. +The Julia package [Z3.jl](https://github.com/ahumenberger/Z3.jl) provides and interface to Z3 by exposing its C API. + +A previous version exposed the C++ API via [CxxWrap.jl](https://github.com/JuliaInterop/CxxWrap.jl). The bindings therefore consisted of a [C++ part](z3jl.cpp) and a [Julia part](https://github.com/ahumenberger/Z3.jl). The C++ part defines the Z3 types/methods which are exposed. The resulting library is loaded in the Julia part via CxxWrap.jl which creates the corresponding Julia types/methods. ## Building the C++ part diff --git a/src/api/python/pyproject.toml b/src/api/python/pyproject.toml index a9f2676a7..ead5d1b2d 100644 --- a/src/api/python/pyproject.toml +++ b/src/api/python/pyproject.toml @@ -1,3 +1,3 @@ [build-system] -requires = ["setuptools>=46.4.0", "wheel", "cmake"] +requires = ["setuptools>=70", "cmake"] build-backend = "setuptools.build_meta" diff --git a/src/api/python/setup.py b/src/api/python/setup.py index c7af0e646..11ba42cf8 100644 --- a/src/api/python/setup.py +++ b/src/api/python/setup.py @@ -7,18 +7,17 @@ import multiprocessing import re import glob from setuptools import setup -from distutils.util import get_platform -from distutils.errors import LibError -from distutils.command.build import build as _build -from distutils.command.sdist import sdist as _sdist -from distutils.command.clean import clean as _clean +from setuptools.command.build import build as _build +from setuptools.command.sdist import sdist as _sdist +from setuptools.command.bdist_wheel import bdist_wheel as _bdist_wheel from setuptools.command.develop import develop as _develop -from setuptools.command.bdist_egg import bdist_egg as _bdist_egg +class LibError(Exception): + pass build_env = dict(os.environ) build_env['PYTHON'] = sys.executable -build_env['CXXFLAGS'] = build_env.get('CXXFLAGS', '') + " -std=c++17" +build_env['CXXFLAGS'] = build_env.get('CXXFLAGS', '') + " -std=c++20" # determine where we're building and where sources are ROOT_DIR = os.path.abspath(os.path.dirname(__file__)) @@ -33,6 +32,8 @@ if RELEASE_DIR is None: HEADER_DIRS = [os.path.join(SRC_DIR, 'src', 'api'), os.path.join(SRC_DIR, 'src', 'api', 'c++')] RELEASE_METADATA = None BUILD_PLATFORM = sys.platform + BUILD_ARCH = os.environ.get("Z3_CROSS_COMPILING", platform.machine()) + BUILD_OS_VERSION = platform.mac_ver()[0].split(".") else: if not os.path.isdir(RELEASE_DIR): raise Exception("RELEASE_DIR (%s) is not a directory!" % RELEASE_DIR) @@ -43,6 +44,11 @@ else: raise Exception("RELEASE_DIR (%s) must be in the format z3-version-arch-os[-osversion] so we can extract metadata from it. Sorry!" % RELEASE_DIR) RELEASE_METADATA.pop(0) BUILD_PLATFORM = RELEASE_METADATA[2] + BUILD_ARCH = RELEASE_METADATA[1] + if len(RELEASE_METADATA) == 4: + BUILD_OS_VERSION = RELEASE_METADATA[3].split(".") + else: + BUILD_OS_VERSION = None # determine where destinations are LIBS_DIR = os.path.join(ROOT_DIR, 'z3', 'lib') @@ -50,7 +56,7 @@ HEADERS_DIR = os.path.join(ROOT_DIR, 'z3', 'include') BINS_DIR = os.path.join(ROOT_DIR, 'bin') # determine platform-specific filenames -if BUILD_PLATFORM in ('darwin', 'osx'): +if BUILD_PLATFORM in ('sequoia','darwin', 'osx'): LIBRARY_FILE = "libz3.dylib" EXECUTABLE_FILE = "z3" elif BUILD_PLATFORM in ('win32', 'cygwin', 'win'): @@ -193,7 +199,7 @@ def _copy_bins(): link_name = None if BUILD_PLATFORM in ('win32', 'cygwin', 'win'): pass # TODO: When windows VMs work on M1, fill this in - elif BUILD_PLATFORM in ('darwin', 'osx'): + elif BUILD_PLATFORM in ('sequoia', 'darwin', 'osx'): split = LIBRARY_FILE.split('.') link_name = split[0] + '.' + major_minor + '.' + split[1] else: @@ -238,111 +244,41 @@ class develop(_develop): self.execute(_copy_bins, (), msg="Copying binaries") _develop.run(self) -class bdist_egg(_bdist_egg): - def run(self): - self.run_command('build') - _bdist_egg.run(self) - class sdist(_sdist): def run(self): self.execute(_clean_bins, (), msg="Cleaning binary files and headers") self.execute(_copy_sources, (), msg="Copying source files") _sdist.run(self) -class clean(_clean): - def run(self): - self.execute(_clean_bins, (), msg="Cleaning binary files and headers") - self.execute(_clean_native_build, (), msg="Cleaning native build") - _clean.run(self) +class bdist_wheel(_bdist_wheel): + def finalize_options(self): + if BUILD_ARCH is not None and BUILD_PLATFORM is not None: + os_version_tag = '_'.join(BUILD_OS_VERSION[:2]) if BUILD_OS_VERSION is not None else 'xxxxxx' + TAGS = { + # linux tags cannot be deployed - they must be auditwheel'd to pick the right compatibility tag based on imported libc symbol versions + ("linux", "x86_64"): "linux_x86_64", + ("linux", "aarch64"): "linux_aarch64", + # windows arm64 is not supported by pypi yet + ("win", "x64"): "win_amd64", + ("win", "x86"): "win32", + ("osx", "x64"): f"macosx_{os_version_tag}_x86_64", + ("osx", "arm64"): f"macosx_{os_version_tag}_arm64", + ("darwin", "x86_64"): f"macosx_{os_version_tag}_x86_64", + ("darwin", "x64"): f"macosx_{os_version_tag}_x86_64", + ("darwin", "arm64"): f"macosx_{os_version_tag}_arm64", + ("sequoia", "x64"): f"macosx_{os_version_tag}_x86_64", + ("sequoia", "x86_64"): f"macosx_{os_version_tag}_x86_64", + ("sequoia", "arm64"): f"macosx_{os_version_tag}_arm64", + } # type: dict[tuple[str, str], str] + self.plat_name = TAGS[(BUILD_PLATFORM, BUILD_ARCH)] + return super().finalize_options() -# the build directory needs to exist -#try: os.makedirs(os.path.join(ROOT_DIR, 'build')) -#except OSError: pass - -# platform.freedesktop_os_release was added in 3.10 -os_id = '' -if hasattr(platform, 'freedesktop_os_release'): - try: - osr = platform.freedesktop_os_release() - print(osr) - os_id = osr['ID'] - except OSError: - pass - -if 'bdist_wheel' in sys.argv and '--plat-name' not in sys.argv: - if RELEASE_DIR is None: - name = get_platform() - if 'linux' in name: - # linux_* platform tags are disallowed because the python ecosystem is fubar - # linux builds should be built in the centos 5 vm for maximum compatibility - # see https://github.com/pypa/manylinux - # see also https://github.com/angr/angr-dev/blob/master/admin/bdist.py - plat_name = 'manylinux_2_28_' + platform.machine() - elif 'mingw' in name: - if platform.architecture()[0] == '64bit': - plat_name = 'win_amd64' - else: - plat_name ='win32' - else: - # https://www.python.org/dev/peps/pep-0425/ - plat_name = name.replace('.', '_').replace('-', '_') - else: - # extract the architecture of the release from the directory name - arch = RELEASE_METADATA[1] - distos = RELEASE_METADATA[2] - if distos in ('debian', 'ubuntu'): - raise Exception( - "Linux binary distributions must be built on centos to conform to PEP 513 or alpine if targeting musl" - ) - elif distos == 'glibc': - if arch == 'x64': - plat_name = 'manylinux_2_28_x86_64' - elif arch == 'arm64' or arch == 'aarch64': - # context on why are we match on arm64 - # but use aarch64 on the plat_name is - # due to a workaround current python - # legacy build doesn't support aarch64 - # so using the currently supported arm64 - # build and simply rename it to aarch64 - # see full context on #7148 - plat_name = 'manylinux_2_28_aarch64' - else: - plat_name = 'manylinux_2_28_i686' - elif distos == 'linux' and os_id == 'alpine': - if arch == 'x64': - plat_name = 'musllinux_1_1_x86_64' - else: - plat_name = 'musllinux_1_1_i686' - elif distos == 'win': - if arch == 'x64': - plat_name = 'win_amd64' - else: - plat_name = 'win32' - elif distos == 'osx': - osver = RELEASE_METADATA[3] - if osver.count('.') > 1: - osver = '.'.join(osver.split('.')[:2]) - if osver.startswith("11"): - osver = "11_0" - if arch == 'x64': - plat_name ='macosx_%s_x86_64' % osver.replace('.', '_') - elif arch == 'arm64': - plat_name ='macosx_%s_arm64' % osver.replace('.', '_') - else: - raise Exception(f"idk how os {distos} {osver} works. what goes here?") - else: - raise Exception(f"idk how to translate between this z3 release os {distos} and the python naming scheme") - - idx = sys.argv.index('bdist_wheel') + 1 - sys.argv.insert(idx, '--plat-name') - sys.argv.insert(idx + 1, plat_name) - sys.argv.insert(idx + 2, '--universal') # supports py2+py3. if --plat-name is not specified this will also mean that the package can be installed on any machine regardless of architecture, so watch out! setup( name='z3-solver', version=_z3_version(), description='an efficient SMT solver library', - long_description='Z3 is a theorem prover from Microsoft Research with support for bitvectors, booleans, arrays, floating point numbers, strings, and other data types.\n\nFor documentation, please read http://z3prover.github.io/api/html/z3.html\n\nIn the event of technical difficulties related to configuration, compilation, or installation, please submit issues to https://github.com/z3prover/z3.git', + long_description='Z3 is a theorem prover from Microsoft Research with support for bitvectors, booleans, arrays, floating point numbers, strings, and other data types.\n\nFor documentation, please read http://z3prover.github.io/api/html/z3.html', author="The Z3 Theorem Prover Project", maintainer="Audrey Dutcher and Nikolaj Bjorner", maintainer_email="audrey@rhelmot.io", @@ -356,5 +292,5 @@ setup( 'z3': [os.path.join('lib', '*'), os.path.join('include', '*.h'), os.path.join('include', 'c++', '*.h')] }, data_files=[('bin',[os.path.join('bin',EXECUTABLE_FILE)])], - cmdclass={'build': build, 'develop': develop, 'sdist': sdist, 'bdist_egg': bdist_egg, 'clean': clean}, + cmdclass={'build': build, 'develop': develop, 'sdist': sdist, 'bdist_wheel': bdist_wheel}, ) diff --git a/src/api/python/z3/z3.py b/src/api/python/z3/z3.py index c3f40a52b..5c2a35995 100644 --- a/src/api/python/z3/z3.py +++ b/src/api/python/z3/z3.py @@ -6798,7 +6798,7 @@ class Statistics: sat >>> st = s.statistics() >>> len(st) - 6 + 7 """ return int(Z3_stats_size(self.ctx.ref(), self.stats)) @@ -6812,11 +6812,11 @@ class Statistics: sat >>> st = s.statistics() >>> len(st) - 6 + 7 >>> st[0] ('nlsat propagations', 2) >>> st[1] - ('nlsat stages', 2) + ('nlsat restarts', 1) """ if idx >= len(self): raise IndexError @@ -7353,6 +7353,13 @@ class Solver(Z3PPObject): Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels) return trail, levels + def set_initial_value(self, var, value): + """initialize the solver's state by setting the initial value of var to value + """ + s = var.sort() + value = s.cast(value) + Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast) + def trail(self): """Return trail of the solver state after a check() call. """ @@ -7926,9 +7933,12 @@ _on_model_eh = on_model_eh_type(_global_on_model) class Optimize(Z3PPObject): """Optimize API provides methods for solving using objective functions and weighted soft constraints""" - def __init__(self, ctx=None): + def __init__(self, optimize=None, ctx=None): self.ctx = _get_ctx(ctx) - self.optimize = Z3_mk_optimize(self.ctx.ref()) + if optimize is None: + self.optimize = Z3_mk_optimize(self.ctx.ref()) + else: + self.optimize = optimize self._on_models_id = None Z3_optimize_inc_ref(self.ctx.ref(), self.optimize) @@ -8029,6 +8039,13 @@ class Optimize(Z3PPObject): return [asoft(a) for a in arg] return asoft(arg) + def set_initial_value(self, var, value): + """initialize the solver's state by setting the initial value of var to value + """ + s = var.sort() + value = s.cast(value) + Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast) + def maximize(self, arg): """Add objective function to maximize.""" return OptimizeObjective( @@ -10220,7 +10237,7 @@ def FPs(names, fpsort, ctx=None): >>> x.ebits() 8 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z) - x + y * z + (x + y) * z """ ctx = _get_ctx(ctx) if isinstance(names, str): diff --git a/src/api/python/z3/z3printer.py b/src/api/python/z3/z3printer.py index 2da5f89da..d7ee17f4a 100644 --- a/src/api/python/z3/z3printer.py +++ b/src/api/python/z3/z3printer.py @@ -1412,8 +1412,10 @@ class HTMLFormatter(Formatter): ys_pp = group(seq(ys)) if a.is_forall(): header = "∀" - else: + elif a.is_exists(): header = "∃" + else: + header = "λ" return group(compose(to_format(header, 1), indent(1, compose(ys_pp, to_format(" :"), line_break(), body_pp)))) diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 1f0daf8b5..6c3efe7fc 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -7241,6 +7241,18 @@ extern "C" { bool Z3_API Z3_solver_propagate_consequence(Z3_context c, Z3_solver_callback cb, unsigned num_fixed, Z3_ast const* fixed, unsigned num_eqs, Z3_ast const* eq_lhs, Z3_ast const* eq_rhs, Z3_ast conseq); + + /** + \brief provide an initialization hint to the solver. The initialization hint is used to calibrate an initial value of the expression that + represents a variable. If the variable is Boolean, the initial phase is set according to \c value. If the variable is an integer or real, + the initial Simplex tableau is recalibrated to attempt to follow the value assignment. + + def_API('Z3_solver_set_initial_value', VOID, (_in(CONTEXT), _in(SOLVER), _in(AST), _in(AST))) + */ + + void Z3_API Z3_solver_set_initial_value(Z3_context c, Z3_solver s, Z3_ast v, Z3_ast val); + + /** \brief Check whether the assertions in a given solver are consistent or not. diff --git a/src/api/z3_optimization.h b/src/api/z3_optimization.h index 8bf0e9da5..4e585efb2 100644 --- a/src/api/z3_optimization.h +++ b/src/api/z3_optimization.h @@ -139,6 +139,18 @@ extern "C" { */ void Z3_API Z3_optimize_pop(Z3_context c, Z3_optimize d); + /** + \brief provide an initialization hint to the solver. + The initialization hint is used to calibrate an initial value of the expression that + represents a variable. If the variable is Boolean, the initial phase is set + according to \c value. If the variable is an integer or real, + the initial Simplex tableau is recalibrated to attempt to follow the value assignment. + + def_API('Z3_optimize_set_initial_value', VOID, (_in(CONTEXT), _in(OPTIMIZE), _in(AST), _in(AST))) + */ + + void Z3_API Z3_optimize_set_initial_value(Z3_context c, Z3_optimize o, Z3_ast v, Z3_ast val); + /** \brief Check consistency and produce optimal values. \param c - context diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index 67a605869..8e2cbef82 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -34,9 +34,6 @@ struct arith_decl_plugin::algebraic_numbers_wrapper { m_nums(m_amanager) { } - ~algebraic_numbers_wrapper() { - } - unsigned mk_id(algebraic_numbers::anum const & val) { SASSERT(!m_amanager.is_rational(val)); unsigned idx = m_id_gen.mk(); diff --git a/src/ast/array_decl_plugin.cpp b/src/ast/array_decl_plugin.cpp index bd9d954c7..c013036f4 100644 --- a/src/ast/array_decl_plugin.cpp +++ b/src/ast/array_decl_plugin.cpp @@ -577,9 +577,9 @@ void array_decl_plugin::get_sort_names(svector& sort_names, symbol void array_decl_plugin::get_op_names(svector& op_names, symbol const & logic) { op_names.push_back(builtin_name("store",OP_STORE)); op_names.push_back(builtin_name("select",OP_SELECT)); + op_names.push_back(builtin_name("const",OP_CONST_ARRAY)); // github issue #7383 if (logic == symbol::null || logic == symbol("HORN") || logic == symbol("ALL")) { // none of the SMT2 logics support these extensions - op_names.push_back(builtin_name("const",OP_CONST_ARRAY)); op_names.push_back(builtin_name("map",OP_ARRAY_MAP)); op_names.push_back(builtin_name("default",OP_ARRAY_DEFAULT)); op_names.push_back(builtin_name("union",OP_SET_UNION)); diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 4295e9ec5..c4f87e5da 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -58,7 +58,7 @@ parameter::parameter(parameter const& other) : m_val(other.m_val) { } void parameter::init_eh(ast_manager & m) { - if (is_ast()) { + if (is_ast()) { m.inc_ref(get_ast()); } } @@ -1008,7 +1008,8 @@ sort* basic_decl_plugin::join(unsigned n, expr* const* es) { } sort* basic_decl_plugin::join(sort* s1, sort* s2) { - if (s1 == s2) return s1; + if (s1 == s2) + return s1; if (s1->get_family_id() == arith_family_id && s2->get_family_id() == arith_family_id) { if (s1->get_decl_kind() == REAL_SORT) { @@ -1016,6 +1017,10 @@ sort* basic_decl_plugin::join(sort* s1, sort* s2) { } return s2; } + if (s1 == m_bool_sort && s2->get_family_id() == arith_family_id) + return s2; + if (s2 == m_bool_sort && s1->get_family_id() == arith_family_id) + return s1; std::ostringstream buffer; buffer << "Sorts " << mk_pp(s1, *m_manager) << " and " << mk_pp(s2, *m_manager) << " are incompatible"; throw ast_exception(buffer.str()); diff --git a/src/ast/ast_pp_dot.cpp b/src/ast/ast_pp_dot.cpp index 47da4d4f4..1298239a2 100644 --- a/src/ast/ast_pp_dot.cpp +++ b/src/ast/ast_pp_dot.cpp @@ -45,8 +45,6 @@ struct ast_pp_dot_st { m_printed(), m_to_print(), m_first(true) {} - - ~ast_pp_dot_st() {}; void push_term(const expr * a) { m_to_print.push_back(a); } diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index 0da4f1c12..68936ac49 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -31,6 +31,7 @@ Revision History: #include "ast/datatype_decl_plugin.h" #include "ast/seq_decl_plugin.h" #include "ast/fpa_decl_plugin.h" +#include "ast/recfun_decl_plugin.h" #include "ast/for_each_ast.h" #include "ast/decl_collector.h" #include "math/polynomial/algebraic_numbers.h" @@ -1000,6 +1001,18 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) { } } + vector> recfuns; + recfun::util u(m); + for (auto f : decls.get_rec_decls()) + recfuns.push_back({f, u.get_def(f).get_rhs()}); + + + if (!recfuns.empty()) { + smt2_pp_environment_dbg env(m); + ast_smt2_pp_recdefs(strm, recfuns, env); + } + + #endif for (expr* a : m_assumptions) { diff --git a/src/ast/ast_trail.h b/src/ast/ast_trail.h index 5a76dd537..18c8961e6 100644 --- a/src/ast/ast_trail.h +++ b/src/ast/ast_trail.h @@ -33,8 +33,7 @@ class ast2ast_trailmap { public: ast2ast_trailmap(ast_manager& m): m_domain(m), - m_range(m), - m_map() + m_range(m) {} bool find(S* s, T*& t) { diff --git a/src/ast/bv_decl_plugin.cpp b/src/ast/bv_decl_plugin.cpp index aee03ed62..ded118047 100644 --- a/src/ast/bv_decl_plugin.cpp +++ b/src/ast/bv_decl_plugin.cpp @@ -927,7 +927,7 @@ sort * bv_util::mk_sort(unsigned bv_size) { } unsigned bv_util::get_int2bv_size(parameter const& p) { - int sz; + int sz = 0; VERIFY(m_plugin->get_int2bv_size(1, &p, sz)); return static_cast(sz); } @@ -951,4 +951,4 @@ app* bv_util::mk_bv_rotate_left(expr* arg, unsigned n) { app* bv_util::mk_bv_rotate_right(expr* arg, unsigned n) { parameter p(n); return m_manager.mk_app(get_fid(), OP_ROTATE_RIGHT, 1, &p, 1, &arg); -} \ No newline at end of file +} diff --git a/src/ast/converters/generic_model_converter.cpp b/src/ast/converters/generic_model_converter.cpp index c50d86cae..03624c9de 100644 --- a/src/ast/converters/generic_model_converter.cpp +++ b/src/ast/converters/generic_model_converter.cpp @@ -22,6 +22,7 @@ Notes: #include "ast/for_each_expr.h" #include "ast/ast_util.h" #include "ast/occurs.h" +#include "ast/bv_decl_plugin.h" #include "ast/rewriter/expr_safe_replace.h" #include "ast/rewriter/th_rewriter.h" #include "ast/converters/generic_model_converter.h" @@ -130,6 +131,54 @@ generic_model_converter * generic_model_converter::copy(ast_translation & transl return res; } +void generic_model_converter::convert_initialize_value(vector> & var2value) { + if (var2value.empty() || m_entries.empty()) + return; + for (unsigned i = 0; i < var2value.size(); ++i) { + auto& [var, value] = var2value[i]; + for (auto const& e : m_entries) { + switch (e.m_instruction) { + case HIDE: + break; + case ADD: + if (is_uninterp_const(var) && e.m_f == to_app(var)->get_decl()) + convert_initialize_value(e.m_def, i, var2value); + break; + } + } + } +} + +void generic_model_converter::convert_initialize_value(expr* def, unsigned i, vector>& var2value) { + + // var = if(c, th, el) = value + // th = value => c = true + // el = value => c = false + expr* c = nullptr, *th = nullptr, *el = nullptr; + auto& [var, value] = var2value[i]; + if (m.is_ite(def, c, th, el)) { + if (value == th) { + var = c; + value = m.mk_true(); + return; + } + if (value == el) { + var = c; + value = m.mk_false(); + return; + } + } + + // var = def = value + // => def = value + if (is_uninterp(def)) { + var = def; + return; + } + +} + + void generic_model_converter::set_env(ast_pp_util* visitor) { if (!visitor) { diff --git a/src/ast/converters/generic_model_converter.h b/src/ast/converters/generic_model_converter.h index 0bc6b21b4..18ec16fe0 100644 --- a/src/ast/converters/generic_model_converter.h +++ b/src/ast/converters/generic_model_converter.h @@ -37,6 +37,7 @@ private: vector m_entries; expr_ref simplify_def(entry const& e); + void convert_initialize_value(expr* def, unsigned i, vector>& var2value); public: generic_model_converter(ast_manager & m, char const* orig) : m(m), m_orig(orig) {} @@ -61,6 +62,8 @@ public: model_converter * translate(ast_translation & translator) override { return copy(translator); } + void convert_initialize_value(vector>& var2value) override; + generic_model_converter* copy(ast_translation & translator); void set_env(ast_pp_util* visitor) override; diff --git a/src/ast/converters/model_converter.cpp b/src/ast/converters/model_converter.cpp index d053394ca..c309bbb79 100644 --- a/src/ast/converters/model_converter.cpp +++ b/src/ast/converters/model_converter.cpp @@ -107,6 +107,12 @@ public: m_c2->get_units(fmls); m_c1->get_units(fmls); } + + void convert_initialize_value(vector>& var2value) override { + m_c2->convert_initialize_value(var2value); + m_c1->convert_initialize_value(var2value); + } + char const * get_name() const override { return "concat-model-converter"; } diff --git a/src/ast/converters/model_converter.h b/src/ast/converters/model_converter.h index 720324919..baf5e422d 100644 --- a/src/ast/converters/model_converter.h +++ b/src/ast/converters/model_converter.h @@ -71,9 +71,6 @@ protected: void display_del(std::ostream& out, func_decl* f) const; void display_add(std::ostream& out, ast_manager& m); public: - - model_converter() {} - void set_completion(bool f) { m_completion = f; } virtual void operator()(model_ref & m) = 0; @@ -86,6 +83,8 @@ public: virtual void set_env(ast_pp_util* visitor); + virtual void convert_initialize_value(vector> & var2value) { } + /** \brief we are adding a formula to the context of the model converter. The operator has as side effect of adding definitions as assertions to the diff --git a/src/ast/datatype_decl_plugin.cpp b/src/ast/datatype_decl_plugin.cpp index a4ddbdaed..e5ab4a806 100644 --- a/src/ast/datatype_decl_plugin.cpp +++ b/src/ast/datatype_decl_plugin.cpp @@ -220,17 +220,33 @@ namespace datatype { } namespace decl { - + plugin::~plugin() { finalize(); } void plugin::finalize() { - for (auto& kv : m_defs) { - dealloc(kv.m_value); - } + for (auto& kv : m_defs) + dealloc(kv.m_value); m_defs.reset(); m_util = nullptr; // force deletion + reset(); + } + + void plugin::reset() { + m_datatype2constructors.reset(); + m_datatype2nonrec_constructor.reset(); + m_constructor2accessors.reset(); + m_constructor2recognizer.reset(); + m_recognizer2constructor.reset(); + m_accessor2constructor.reset(); + m_is_recursive.reset(); + m_is_enum.reset(); + std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc >()); + m_vectors.reset(); + dealloc(m_asts); + m_asts = nullptr; + ++m_start; } util & plugin::u() const { @@ -578,6 +594,7 @@ namespace datatype { if (m_defs.find(s, d)) dealloc(d); m_defs.remove(s); + reset(); } bool plugin::is_value_visit(bool unique, expr * arg, ptr_buffer & todo) const { @@ -799,7 +816,7 @@ namespace datatype { for (unsigned i = 0; i < n; ++i) { sort* ps = get_datatype_parameter_sort(s, i); sz = get_sort_size(params, ps); - m_refs.push_back(sz); + plugin().m_refs.push_back(sz); S.insert(d.params().get(i), sz); } auto ss = d.sort_size(); @@ -896,7 +913,7 @@ namespace datatype { } TRACE("datatype", tout << "set sort size " << s << "\n";); d.set_sort_size(param_size::size::mk_plus(s_add)); - m_refs.reset(); + plugin().m_refs.reset(); } } @@ -1008,9 +1025,7 @@ namespace datatype { util::util(ast_manager & m): m(m), m_family_id(null_family_id), - m_plugin(nullptr), - m_asts(m), - m_start(0) { + m_plugin(nullptr) { } @@ -1025,26 +1040,21 @@ namespace datatype { return m_family_id; } - - util::~util() { - std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc >()); - } - ptr_vector const * util::get_datatype_constructors(sort * ty) { SASSERT(is_datatype(ty)); ptr_vector * r = nullptr; - if (m_datatype2constructors.find(ty, r)) + if (plugin().m_datatype2constructors.find(ty, r)) return r; r = alloc(ptr_vector); - m_asts.push_back(ty); - m_vectors.push_back(r); - m_datatype2constructors.insert(ty, r); + plugin().add_ast(ty); + plugin().m_vectors.push_back(r); + plugin().m_datatype2constructors.insert(ty, r); if (!is_declared(ty)) m.raise_exception("datatype constructors have not been created"); def const& d = get_def(ty); for (constructor const* c : d) { func_decl_ref f = c->instantiate(ty); - m_asts.push_back(f); + plugin().add_ast(f); r->push_back(f); } return r; @@ -1053,13 +1063,13 @@ namespace datatype { ptr_vector const * util::get_constructor_accessors(func_decl * con) { SASSERT(is_constructor(con)); ptr_vector * res = nullptr; - if (m_constructor2accessors.find(con, res)) { + if (plugin().m_constructor2accessors.find(con, res)) { return res; } res = alloc(ptr_vector); - m_asts.push_back(con); - m_vectors.push_back(res); - m_constructor2accessors.insert(con, res); + plugin().add_ast(con); + plugin().m_vectors.push_back(res); + plugin().m_constructor2accessors.insert(con, res); sort * datatype = con->get_range(); def const& d = get_def(datatype); for (constructor const* c : d) { @@ -1067,7 +1077,7 @@ namespace datatype { for (accessor const* a : *c) { func_decl_ref fn = a->instantiate(datatype); res->push_back(fn); - m_asts.push_back(fn); + plugin().add_ast(fn); } break; } @@ -1086,7 +1096,7 @@ namespace datatype { func_decl * util::get_constructor_recognizer(func_decl * con) { SASSERT(is_constructor(con)); func_decl * d = nullptr; - if (m_constructor2recognizer.find(con, d)) + if (plugin().m_constructor2recognizer.find(con, d)) return d; sort * datatype = con->get_range(); def const& dd = get_def(datatype); @@ -1097,9 +1107,9 @@ namespace datatype { parameter ps[2] = { parameter(con), parameter(r) }; d = m.mk_func_decl(fid(), OP_DT_RECOGNISER, 2, ps, 1, &datatype); SASSERT(d); - m_asts.push_back(con); - m_asts.push_back(d); - m_constructor2recognizer.insert(con, d); + plugin().add_ast(con); + plugin().add_ast(d); + plugin().m_constructor2recognizer.insert(con, d); return d; } @@ -1120,10 +1130,10 @@ namespace datatype { bool util::is_recursive(sort * ty) { SASSERT(is_datatype(ty)); bool r = false; - if (!m_is_recursive.find(ty, r)) { + if (!plugin().m_is_recursive.find(ty, r)) { r = is_recursive_core(ty); - m_is_recursive.insert(ty, r); - m_asts.push_back(ty); + plugin().m_is_recursive.insert(ty, r); + plugin().add_ast(ty); } return r; } @@ -1147,21 +1157,21 @@ namespace datatype { if (!is_datatype(s)) return false; bool r = false; - if (m_is_enum.find(s, r)) + if (plugin().m_is_enum.find(s, r)) return r; ptr_vector const& cnstrs = *get_datatype_constructors(s); r = true; for (unsigned i = 0; r && i < cnstrs.size(); ++i) r = cnstrs[i]->get_arity() == 0; - m_is_enum.insert(s, r); - m_asts.push_back(s); + plugin().m_is_enum.insert(s, r); + plugin().add_ast(s); return r; } func_decl * util::get_accessor_constructor(func_decl * accessor) { SASSERT(is_accessor(accessor)); func_decl * r = nullptr; - if (m_accessor2constructor.find(accessor, r)) + if (plugin().m_accessor2constructor.find(accessor, r)) return r; sort * datatype = accessor->get_domain(0); symbol c_id = accessor->get_parameter(1).get_symbol(); @@ -1174,26 +1184,15 @@ namespace datatype { } } r = fn; - m_accessor2constructor.insert(accessor, r); - m_asts.push_back(accessor); - m_asts.push_back(r); + plugin().m_accessor2constructor.insert(accessor, r); + plugin().add_ast(accessor); + plugin().add_ast(r); return r; } void util::reset() { - m_datatype2constructors.reset(); - m_datatype2nonrec_constructor.reset(); - m_constructor2accessors.reset(); - m_constructor2recognizer.reset(); - m_recognizer2constructor.reset(); - m_accessor2constructor.reset(); - m_is_recursive.reset(); - m_is_enum.reset(); - std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc >()); - m_vectors.reset(); - m_asts.reset(); - ++m_start; + plugin().reset(); } @@ -1205,7 +1204,7 @@ namespace datatype { func_decl * util::get_non_rec_constructor(sort * ty) { SASSERT(is_datatype(ty)); cnstr_depth cd; - if (m_datatype2nonrec_constructor.find(ty, cd)) + if (plugin().m_datatype2nonrec_constructor.find(ty, cd)) return cd.first; ptr_vector forbidden_set; forbidden_set.push_back(ty); @@ -1222,7 +1221,7 @@ namespace datatype { each T_i is not a datatype or it is a datatype t not in forbidden_set, and get_non_rec_constructor_core(T_i, forbidden_set union { T_i }) */ - util::cnstr_depth util::get_non_rec_constructor_core(sort * ty, ptr_vector & forbidden_set) { + cnstr_depth util::get_non_rec_constructor_core(sort * ty, ptr_vector & forbidden_set) { // We must select a constructor c(T_1, ..., T_n):T such that // 1) T_i's are not recursive // If there is no such constructor, then we select one that @@ -1231,7 +1230,7 @@ namespace datatype { ptr_vector const& constructors = *get_datatype_constructors(ty); array_util autil(m); cnstr_depth result(nullptr, 0); - if (m_datatype2nonrec_constructor.find(ty, result)) + if (plugin().m_datatype2nonrec_constructor.find(ty, result)) return result; TRACE("util_bug", tout << "get-non-rec constructor: " << sort_ref(ty, m) << "\n"; tout << "forbidden: "; @@ -1273,9 +1272,9 @@ namespace datatype { } } if (result.first) { - m_asts.push_back(result.first); - m_asts.push_back(ty); - m_datatype2nonrec_constructor.insert(ty, result); + plugin().add_ast(result.first); + plugin().add_ast(ty); + plugin().m_datatype2nonrec_constructor.insert(ty, result); } return result; } @@ -1291,6 +1290,7 @@ namespace datatype { IF_VERBOSE(0, verbose_stream() << f->get_name() << "\n"); for (constructor* c : d) IF_VERBOSE(0, verbose_stream() << "!= " << c->name() << "\n"); + return UINT_MAX; SASSERT(false); UNREACHABLE(); return 0; diff --git a/src/ast/datatype_decl_plugin.h b/src/ast/datatype_decl_plugin.h index 341f3669b..dcca78970 100644 --- a/src/ast/datatype_decl_plugin.h +++ b/src/ast/datatype_decl_plugin.h @@ -198,6 +198,8 @@ namespace datatype { def* translate(ast_translation& tr, util& u); }; + typedef std::pair cnstr_depth; + namespace decl { class plugin : public decl_plugin { @@ -213,6 +215,7 @@ namespace datatype { void log_axiom_definitions(symbol const& s, sort * new_sort); + public: plugin(): m_id_counter(0), m_class_id(0), m_has_nested_rec(false) {} ~plugin() override; @@ -259,6 +262,25 @@ namespace datatype { bool has_nested_rec() const { return m_has_nested_rec; } + void reset(); + + + obj_map*> m_datatype2constructors; + obj_map m_datatype2nonrec_constructor; + obj_map*> m_constructor2accessors; + obj_map m_constructor2recognizer; + obj_map m_recognizer2constructor; + obj_map m_accessor2constructor; + obj_map m_is_recursive; + obj_map m_is_enum; + mutable obj_map m_is_fully_interp; + mutable ast_ref_vector* m_asts = nullptr; + sref_vector m_refs; + ptr_vector > m_vectors; + unsigned m_start = 0; + mutable ptr_vector m_fully_interp_trail; + void add_ast(ast* a) const { if (!m_asts) m_asts = alloc(ast_ref_vector, *m_manager); m_asts->push_back(a); } + private: bool is_value_visit(bool unique, expr * arg, ptr_buffer & todo) const; bool is_value_aux(bool unique, app * arg) const; @@ -295,25 +317,10 @@ namespace datatype { ast_manager & m; mutable family_id m_family_id; mutable decl::plugin* m_plugin; - typedef std::pair cnstr_depth; + family_id fid() const; - - obj_map *> m_datatype2constructors; - obj_map m_datatype2nonrec_constructor; - obj_map *> m_constructor2accessors; - obj_map m_constructor2recognizer; - obj_map m_recognizer2constructor; - obj_map m_accessor2constructor; - obj_map m_is_recursive; - obj_map m_is_enum; - mutable obj_map m_is_fully_interp; - mutable ast_ref_vector m_asts; - sref_vector m_refs; - ptr_vector > m_vectors; - unsigned m_start; - mutable ptr_vector m_fully_interp_trail; - + cnstr_depth get_non_rec_constructor_core(sort * ty, ptr_vector & forbidden_set); friend class decl::plugin; @@ -331,7 +338,6 @@ namespace datatype { public: util(ast_manager & m); - ~util(); ast_manager & get_manager() const { return m; } // sort * mk_datatype_sort(symbol const& name, unsigned n, sort* const* params); bool is_datatype(sort const* s) const { return is_sort_of(s, fid(), DATATYPE_SORT); } diff --git a/src/ast/euf/euf_ac_plugin.cpp b/src/ast/euf/euf_ac_plugin.cpp index 174ef363b..0c890a26f 100644 --- a/src/ast/euf/euf_ac_plugin.cpp +++ b/src/ast/euf/euf_ac_plugin.cpp @@ -440,8 +440,9 @@ namespace euf { TRACE("plugin", tout << "propagate " << eq_id << ": " << eq_pp(*this, m_eqs[eq_id]) << "\n"); // simplify eq using processed - for (auto other_eq : backward_iterator(eq_id)) - TRACE("plugin", tout << "backward iterator " << eq_id << " vs " << other_eq << " " << is_processed(other_eq) << "\n"); + TRACE("plugin", + for (auto other_eq : backward_iterator(eq_id)) + tout << "backward iterator " << eq_id << " vs " << other_eq << " " << is_processed(other_eq) << "\n"); for (auto other_eq : backward_iterator(eq_id)) if (is_processed(other_eq) && backward_simplify(eq_id, other_eq)) goto loop_start; @@ -907,7 +908,6 @@ namespace euf { m_dst_r.reset(); m_dst_r.append(monomial(dst.r).m_nodes); unsigned src_r_size = m_src_r.size(); - unsigned dst_r_size = m_dst_r.size(); SASSERT(src_r_size == monomial(src.r).size()); // dst_r contains C // src_r contains E diff --git a/src/ast/euf/euf_ac_plugin.h b/src/ast/euf/euf_ac_plugin.h index 0f5b9ffcc..809ac55cf 100644 --- a/src/ast/euf/euf_ac_plugin.h +++ b/src/ast/euf/euf_ac_plugin.h @@ -47,7 +47,6 @@ namespace euf { unsigned_vector eqs; // equality occurrences unsigned root_id() const { return root->n->get_id(); } - ~node() {} static node* mk(region& r, enode* n); }; @@ -62,8 +61,7 @@ namespace euf { node* operator*() { return m_first; } iterator& operator++() { if (!m_last) m_last = m_first; m_first = m_first->next; return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } - bool operator==(iterator const& other) const { return m_last == other.m_last && m_first == other.m_first; } - bool operator!=(iterator const& other) const { return !(*this == other); } + bool operator!=(iterator const& other) const { return m_last != other.m_last || m_first != other.m_first; } }; equiv(node& _n) :n(_n) {} equiv(node* _n) :n(*_n) {} @@ -270,8 +268,6 @@ namespace euf { ac_plugin(egraph& g, unsigned fid, unsigned op); ac_plugin(egraph& g, func_decl* f); - - ~ac_plugin() override {} theory_id get_id() const override { return m_fid; } diff --git a/src/ast/euf/euf_arith_plugin.h b/src/ast/euf/euf_arith_plugin.h index 4c2a88d36..0cc122d99 100644 --- a/src/ast/euf/euf_arith_plugin.h +++ b/src/ast/euf/euf_arith_plugin.h @@ -33,8 +33,6 @@ namespace euf { public: arith_plugin(egraph& g); - ~arith_plugin() override {} - theory_id get_id() const override { return a.get_family_id(); } void register_node(enode* n) override; diff --git a/src/ast/euf/euf_bv_plugin.h b/src/ast/euf/euf_bv_plugin.h index ec2c0b448..6bf48df2a 100644 --- a/src/ast/euf/euf_bv_plugin.h +++ b/src/ast/euf/euf_bv_plugin.h @@ -95,8 +95,6 @@ namespace euf { public: bv_plugin(egraph& g); - ~bv_plugin() override {} - theory_id get_id() const override { return bv.get_family_id(); } void register_node(enode* n) override; diff --git a/src/ast/euf/euf_egraph.cpp b/src/ast/euf/euf_egraph.cpp index 21bc14ba4..eaa290bbf 100644 --- a/src/ast/euf/euf_egraph.cpp +++ b/src/ast/euf/euf_egraph.cpp @@ -107,8 +107,8 @@ namespace euf { void egraph::update_children(enode* n) { for (enode* child : enode_args(n)) child->get_root()->add_parent(n); - for (enode* child : enode_args(n)) - SASSERT(child->get_root()->m_parents.back() == n); + DEBUG_CODE(for (enode* child : enode_args(n)) + SASSERT(child->get_root()->m_parents.back() == n);); m_updates.push_back(update_record(n, update_record::update_children())); } diff --git a/src/ast/euf/euf_enode.h b/src/ast/euf/euf_enode.h index 50a7ce479..af22a5b2c 100644 --- a/src/ast/euf/euf_enode.h +++ b/src/ast/euf/euf_enode.h @@ -280,8 +280,7 @@ namespace euf { enode* operator*() { return m_first; } iterator& operator++() { if (!m_last) m_last = m_first; m_first = m_first->m_next; return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } - bool operator==(iterator const& other) const { return m_last == other.m_last && m_first == other.m_first; } - bool operator!=(iterator const& other) const { return !(*this == other); } + bool operator!=(iterator const& other) const { return m_last != other.m_last || m_first != other.m_first; } }; enode_class(enode & _n):n(_n) {} enode_class(enode * _n):n(*_n) {} @@ -300,8 +299,7 @@ namespace euf { th_var_list const& operator*() { return *m_th_vars; } iterator& operator++() { m_th_vars = m_th_vars->get_next(); return *this; } iterator operator++(int) { iterator tmp = *this; ++* this; return tmp; } - bool operator==(iterator const& other) const { return m_th_vars == other.m_th_vars; } - bool operator!=(iterator const& other) const { return !(*this == other); } + bool operator!=(iterator const& other) const { return m_th_vars != other.m_th_vars; } }; enode_th_vars(enode& _n) :n(_n) {} enode_th_vars(enode* _n) :n(*_n) {} diff --git a/src/ast/euf/euf_specrel_plugin.h b/src/ast/euf/euf_specrel_plugin.h index ae93bd2a5..5e3578ccf 100644 --- a/src/ast/euf/euf_specrel_plugin.h +++ b/src/ast/euf/euf_specrel_plugin.h @@ -34,8 +34,6 @@ namespace euf { public: specrel_plugin(egraph& g); - - ~specrel_plugin() override {} theory_id get_id() const override { return sp.get_family_id(); } diff --git a/src/ast/expr2polynomial.cpp b/src/ast/expr2polynomial.cpp index a69d5b436..3bcd7367a 100644 --- a/src/ast/expr2polynomial.cpp +++ b/src/ast/expr2polynomial.cpp @@ -504,9 +504,6 @@ default_expr2polynomial::default_expr2polynomial(ast_manager & am, polynomial::m expr2polynomial(am, pm, nullptr) { } -default_expr2polynomial::~default_expr2polynomial() { -} - bool default_expr2polynomial::is_int(polynomial::var x) const { return m_is_int[x]; } diff --git a/src/ast/expr2polynomial.h b/src/ast/expr2polynomial.h index 1d89587c4..b3356e9e0 100644 --- a/src/ast/expr2polynomial.h +++ b/src/ast/expr2polynomial.h @@ -102,7 +102,6 @@ class default_expr2polynomial : public expr2polynomial { bool_vector m_is_int; public: default_expr2polynomial(ast_manager & am, polynomial::manager & pm); - ~default_expr2polynomial() override; bool is_int(polynomial::var x) const override; protected: polynomial::var mk_var(bool is_int) override; diff --git a/src/ast/for_each_expr.cpp b/src/ast/for_each_expr.cpp index 8feb217db..ebad5760c 100644 --- a/src/ast/for_each_expr.cpp +++ b/src/ast/for_each_expr.cpp @@ -146,20 +146,16 @@ subterms::iterator& subterms::iterator::operator++() { return *this; } -bool subterms::iterator::operator==(iterator const& other) const { +bool subterms::iterator::operator!=(iterator const& other) const { // ignore state of visited if (other.m_esp->size() != m_esp->size()) { - return false; + return true; } for (unsigned i = m_esp->size(); i-- > 0; ) { if (m_esp->get(i) != other.m_esp->get(i)) - return false; + return true; } - return true; -} - -bool subterms::iterator::operator!=(iterator const& other) const { - return !(*this == other); + return false; } @@ -216,18 +212,14 @@ subterms_postorder::iterator& subterms_postorder::iterator::operator++() { return *this; } -bool subterms_postorder::iterator::operator==(iterator const& other) const { +bool subterms_postorder::iterator::operator!=(iterator const& other) const { // ignore state of visited if (other.m_es.size() != m_es.size()) { - return false; + return true; } for (unsigned i = m_es.size(); i-- > 0; ) { if (m_es.get(i) != other.m_es.get(i)) - return false; + return true; } - return true; -} - -bool subterms_postorder::iterator::operator!=(iterator const& other) const { - return !(*this == other); + return false; } diff --git a/src/ast/for_each_expr.h b/src/ast/for_each_expr.h index 77b01e939..97a171755 100644 --- a/src/ast/for_each_expr.h +++ b/src/ast/for_each_expr.h @@ -190,7 +190,6 @@ public: expr* operator*(); iterator operator++(int); iterator& operator++(); - bool operator==(iterator const& other) const; bool operator!=(iterator const& other) const; }; @@ -220,7 +219,6 @@ public: expr* operator*(); iterator operator++(int); iterator& operator++(); - bool operator==(iterator const& other) const; bool operator!=(iterator const& other) const; }; static subterms_postorder all(expr_ref_vector const& es) { return subterms_postorder(es, true); } diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 25a0e77ad..d138cc082 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2692,7 +2692,7 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * SASSERT(tmp_rat.is_int32()); SASSERT(sz == 3); - mpf_rounding_mode mrm; + mpf_rounding_mode mrm = MPF_ROUND_TOWARD_ZERO; switch ((BV_RM_VAL)tmp_rat.get_unsigned()) { case BV_RM_TIES_TO_AWAY: mrm = MPF_ROUND_NEAREST_TAWAY; break; case BV_RM_TIES_TO_EVEN: mrm = MPF_ROUND_NEAREST_TEVEN; break; diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 42467c219..f68de5e32 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -36,9 +36,6 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { fpa2bv_rewriter_cfg(ast_manager & m, fpa2bv_converter & c, params_ref const & p); - ~fpa2bv_rewriter_cfg() { - } - void cleanup_buffers() { m_out.finalize(); } diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index 76e44278d..3bdc19d5e 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -47,9 +47,6 @@ void fpa_decl_plugin::set_manager(ast_manager * m, family_id id) { m_bv_plugin = static_cast(m_manager->get_plugin(m_bv_fid)); } -fpa_decl_plugin::~fpa_decl_plugin() { -} - unsigned fpa_decl_plugin::mk_id(mpf const & v) { unsigned new_id = m_id_gen.mk(); m_values.reserve(new_id+1); @@ -961,9 +958,6 @@ fpa_util::fpa_util(ast_manager & m): m_plugin = static_cast(m.get_plugin(m_fid)); } -fpa_util::~fpa_util() { -} - sort * fpa_util::mk_float_sort(unsigned ebits, unsigned sbits) { parameter ps[2] = { parameter(ebits), parameter(sbits) }; return m().mk_sort(m_fid, FLOATING_POINT_SORT, 2, ps); diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index 0357efa47..39b3fc33c 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -175,7 +175,6 @@ public: bool is_float_sort(sort * s) const { return is_sort_of(s, m_family_id, FLOATING_POINT_SORT); } bool is_rm_sort(sort * s) const { return is_sort_of(s, m_family_id, ROUNDING_MODE_SORT); } - ~fpa_decl_plugin() override; void finalize() override; decl_plugin * mk_fresh() override; @@ -216,7 +215,6 @@ class fpa_util { public: fpa_util(ast_manager & m); - ~fpa_util(); ast_manager & m() const { return m_manager; } mpf_manager & fm() const { return m_plugin->fm(); } diff --git a/src/ast/has_free_vars.cpp b/src/ast/has_free_vars.cpp index b1b74c7da..c5f3db027 100644 --- a/src/ast/has_free_vars.cpp +++ b/src/ast/has_free_vars.cpp @@ -30,7 +30,7 @@ class contains_vars::imp { void visit(expr * n, unsigned delta, bool & visited) { expr_delta_pair e(n, delta); - if (!m_cache.contains(e)) { + if (!is_ground(n) && !m_cache.contains(e)) { m_todo.push_back(e); visited = false; } @@ -74,6 +74,7 @@ public: m_todo.push_back(expr_delta_pair(n, begin)); while (!m_todo.empty()) { expr_delta_pair e = m_todo.back(); + if (visit_children(e.m_node, e.m_delta)) { m_cache.insert(e); m_todo.pop_back(); diff --git a/src/ast/macros/cond_macro.h b/src/ast/macros/cond_macro.h index 7e8064ac6..0dc3c1e0b 100644 --- a/src/ast/macros/cond_macro.h +++ b/src/ast/macros/cond_macro.h @@ -39,10 +39,7 @@ public: m_weight(weight) { SASSERT(!m_hint || !m_cond); } - - ~cond_macro() { - } - + func_decl * get_f() const { return m_f; } expr * get_def() const { return m_def; } diff --git a/src/ast/macros/macro_finder.cpp b/src/ast/macros/macro_finder.cpp index bc63aae8e..3006e383c 100644 --- a/src/ast/macros/macro_finder.cpp +++ b/src/ast/macros/macro_finder.cpp @@ -269,9 +269,6 @@ macro_finder::macro_finder(ast_manager & m, macro_manager & mm): m_autil(m) { } -macro_finder::~macro_finder() { -} - bool macro_finder::expand_macros(expr_ref_vector const& exprs, proof_ref_vector const& prs, expr_dependency_ref_vector const& deps, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps) { TRACE("macro_finder", tout << "starting expand_macros:\n"; m_macro_manager.display(tout);); diff --git a/src/ast/macros/macro_finder.h b/src/ast/macros/macro_finder.h index 91e5deeb9..fe2722172 100644 --- a/src/ast/macros/macro_finder.h +++ b/src/ast/macros/macro_finder.h @@ -43,7 +43,6 @@ class macro_finder { public: macro_finder(ast_manager & m, macro_manager & mm); - ~macro_finder(); void operator()(expr_ref_vector const& exprs, proof_ref_vector const& prs, expr_dependency_ref_vector const& deps, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps); void operator()(unsigned n, justified_expr const* fmls, vector& new_fmls); }; diff --git a/src/ast/macros/macro_manager.cpp b/src/ast/macros/macro_manager.cpp index b7c94b1b5..824573d46 100644 --- a/src/ast/macros/macro_manager.cpp +++ b/src/ast/macros/macro_manager.cpp @@ -41,9 +41,6 @@ macro_manager::macro_manager(ast_manager & m): m_util.set_forbidden_set(&m_forbidden_set); } -macro_manager::~macro_manager() { -} - void macro_manager::push_scope() { m_scopes.push_back(scope()); scope & s = m_scopes.back(); diff --git a/src/ast/macros/macro_manager.h b/src/ast/macros/macro_manager.h index 758e3c1a7..9d8831c30 100644 --- a/src/ast/macros/macro_manager.h +++ b/src/ast/macros/macro_manager.h @@ -64,7 +64,6 @@ class macro_manager { public: macro_manager(ast_manager & m); - ~macro_manager(); void copy_to(macro_manager& dst); ast_manager & get_manager() const { return m; } macro_util & get_util() { return m_util; } diff --git a/src/ast/macros/quasi_macros.cpp b/src/ast/macros/quasi_macros.cpp index dff36278d..b65daf063 100644 --- a/src/ast/macros/quasi_macros.cpp +++ b/src/ast/macros/quasi_macros.cpp @@ -31,9 +31,6 @@ quasi_macros::quasi_macros(ast_manager & m, macro_manager & mm) : m_new_qsorts(m) { } -quasi_macros::~quasi_macros() { -} - void quasi_macros::find_occurrences(expr * e) { unsigned j; m_todo.reset(); diff --git a/src/ast/macros/quasi_macros.h b/src/ast/macros/quasi_macros.h index 4441f432e..2b5350cf0 100644 --- a/src/ast/macros/quasi_macros.h +++ b/src/ast/macros/quasi_macros.h @@ -60,7 +60,6 @@ class quasi_macros { public: quasi_macros(ast_manager & m, macro_manager & mm); - ~quasi_macros(); /** \brief Find pure function macros and apply them. diff --git a/src/ast/normal_forms/defined_names.cpp b/src/ast/normal_forms/defined_names.cpp index c931c6fad..4e9ee6263 100644 --- a/src/ast/normal_forms/defined_names.cpp +++ b/src/ast/normal_forms/defined_names.cpp @@ -57,7 +57,7 @@ struct defined_names::impl { unsigned_vector m_lims; //!< Backtracking support. impl(ast_manager & m, char const * prefix); - virtual ~impl(); + virtual ~impl() = default; app * gen_name(expr * e, sort_ref_buffer & var_sorts, buffer & var_names); void cache_new_name(expr * e, app * name); @@ -90,9 +90,6 @@ defined_names::impl::impl(ast_manager & m, char const * prefix): m_z3name = prefix; } -defined_names::impl::~impl() { -} - /** \brief Given an expression \c e that may contain free variables, return an application (sk x_1 ... x_n), where sk is a fresh variable name, and x_i's are the free variables of \c e. diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp index 1f0ce6781..9b4ea1346 100644 --- a/src/ast/normal_forms/nnf.cpp +++ b/src/ast/normal_forms/nnf.cpp @@ -69,6 +69,7 @@ class skolemizer { typedef act_cache cache; ast_manager & m; + var_subst m_subst; symbol m_sk_hack; bool m_sk_hack_enabled; cache m_cache; @@ -128,7 +129,6 @@ class skolemizer { // // (VAR 0) should be in the last position of substitution. // - var_subst s(m); SASSERT(is_well_sorted(m, q->get_expr())); expr_ref tmp(m); expr * body = q->get_expr(); @@ -146,7 +146,7 @@ class skolemizer { } } } - r = s(body, substitution); + r = m_subst(body, substitution); p = nullptr; if (m_proofs_enabled) { if (q->get_kind() == forall_k) @@ -159,6 +159,7 @@ class skolemizer { public: skolemizer(ast_manager & m): m(m), + m_subst(m), m_sk_hack("sk_hack"), m_sk_hack_enabled(false), m_cache(m), diff --git a/src/ast/pattern/expr_pattern_match.cpp b/src/ast/pattern/expr_pattern_match.cpp index 8ae0dcbf2..2fbd99bdf 100644 --- a/src/ast/pattern/expr_pattern_match.cpp +++ b/src/ast/pattern/expr_pattern_match.cpp @@ -41,9 +41,6 @@ expr_pattern_match::expr_pattern_match(ast_manager & manager): m_manager(manager), m_precompiled(manager) { } -expr_pattern_match::~expr_pattern_match() { -} - bool expr_pattern_match::match_quantifier(quantifier* qf, app_ref_vector& patterns, unsigned& weight) { if (m_regs.empty()) { diff --git a/src/ast/pattern/expr_pattern_match.h b/src/ast/pattern/expr_pattern_match.h index 2fd0b4b73..11939e1de 100644 --- a/src/ast/pattern/expr_pattern_match.h +++ b/src/ast/pattern/expr_pattern_match.h @@ -116,7 +116,6 @@ class expr_pattern_match { public: expr_pattern_match(ast_manager & manager); - ~expr_pattern_match(); bool match_quantifier(quantifier * qf, app_ref_vector & patterns, unsigned & weight); bool match_quantifier_index(quantifier* qf, app_ref_vector & patterns, unsigned& index); unsigned initialize(quantifier* qf); diff --git a/src/ast/pattern/pattern_inference.h b/src/ast/pattern/pattern_inference.h index 8d179ba33..09c4e333b 100644 --- a/src/ast/pattern/pattern_inference.h +++ b/src/ast/pattern/pattern_inference.h @@ -114,9 +114,9 @@ class pattern_inference_cfg : public default_rewriter_cfg { // class collect { struct entry { - expr * m_node; - unsigned m_delta; - entry():m_node(nullptr), m_delta(0) {} + expr * m_node = nullptr; + unsigned m_delta = 0; + entry() = default; entry(expr * n, unsigned d):m_node(n), m_delta(d) {} unsigned hash() const { return hash_u_u(m_node->get_id(), m_delta); diff --git a/src/ast/proofs/proof_utils.h b/src/ast/proofs/proof_utils.h index cc1744d4e..dbb9dfac0 100644 --- a/src/ast/proofs/proof_utils.h +++ b/src/ast/proofs/proof_utils.h @@ -230,7 +230,7 @@ public: << "New pf: " << mk_pp(newp, m) << "\n";); } - proof *r; + proof *r = nullptr; VERIFY(cache.find(pr, r)); DEBUG_CODE( diff --git a/src/ast/recfun_decl_plugin.cpp b/src/ast/recfun_decl_plugin.cpp index 37e5d359e..79c6fa066 100644 --- a/src/ast/recfun_decl_plugin.cpp +++ b/src/ast/recfun_decl_plugin.cpp @@ -170,8 +170,6 @@ namespace recfun { vector m_branches; public: - case_state() : m_reg(), m_branches() {} - bool empty() const { return m_branches.empty(); } branch pop_branch() { @@ -242,23 +240,18 @@ namespace recfun { { VERIFY(m_cases.empty() && "cases cannot already be computed"); SASSERT(n_vars == m_domain.size()); - TRACEFN("compute cases " << mk_pp(rhs, m)); - unsigned case_idx = 0; - - std::string name("case-"); - name.append(m_name.str()); - - m_vars.append(n_vars, vars); - m_rhs = rhs; - if (!is_macro) for (expr* e : subterms::all(m_rhs)) if (is_lambda(e)) throw default_exception("recursive definitions with lambdas are not supported"); - + + + unsigned case_idx = 0; expr_ref_vector conditions(m); + m_vars.append(n_vars, vars); + m_rhs = rhs; // is the function a macro (unconditional body)? if (is_macro || n_vars == 0 || !contains_ite(u, rhs)) { @@ -267,7 +260,6 @@ namespace recfun { return; } - // analyze control flow of `rhs`, accumulating guards and // rebuilding a `ite`-free RHS on the fly for each path in `rhs`. @@ -368,9 +360,6 @@ namespace recfun { m_plugin(dynamic_cast(m.get_plugin(m_fid))) { } - util::~util() { - } - def * util::decl_fun(symbol const& name, unsigned n, sort *const * domain, sort * range, bool is_generated) { return alloc(def, m(), m_fid, name, n, domain, range, is_generated); } @@ -419,7 +408,6 @@ namespace recfun { } namespace decl { - plugin::plugin() : decl_plugin(), m_defs(), m_case_defs() {} plugin::~plugin() { finalize(); } void plugin::finalize() { diff --git a/src/ast/recfun_decl_plugin.h b/src/ast/recfun_decl_plugin.h index e078c7ef9..d9fe07dcf 100644 --- a/src/ast/recfun_decl_plugin.h +++ b/src/ast/recfun_decl_plugin.h @@ -173,7 +173,6 @@ namespace recfun { void compute_scores(expr* e, obj_map& scores); public: - plugin(); ~plugin() override; void finalize() override; @@ -238,7 +237,6 @@ namespace recfun { public: util(ast_manager &m); - ~util(); ast_manager & m() { return m_manager; } family_id get_family_id() const { return m_fid; } diff --git a/src/ast/rewriter/bv_rewriter.cpp b/src/ast/rewriter/bv_rewriter.cpp index db87cd008..7b54f76a1 100644 --- a/src/ast/rewriter/bv_rewriter.cpp +++ b/src/ast/rewriter/bv_rewriter.cpp @@ -109,17 +109,20 @@ br_status bv_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * cons break; case OP_BNEG_OVFL: SASSERT(num_args == 1); - return mk_bvneg_overflow(args[0], result); - + st = mk_bvneg_overflow(args[0], result); + break; case OP_BSHL: SASSERT(num_args == 2); - return mk_bv_shl(args[0], args[1], result); + st = mk_bv_shl(args[0], args[1], result); + break; case OP_BLSHR: SASSERT(num_args == 2); - return mk_bv_lshr(args[0], args[1], result); + st = mk_bv_lshr(args[0], args[1], result); + break; case OP_BASHR: SASSERT(num_args == 2); - return mk_bv_ashr(args[0], args[1], result); + st = mk_bv_ashr(args[0], args[1], result); + break; case OP_BSDIV: SASSERT(num_args == 2); return mk_bv_sdiv(args[0], args[1], result); @@ -151,13 +154,16 @@ br_status bv_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * cons SASSERT(num_args == 2); return mk_bv_smod_i(args[0], args[1], result); case OP_CONCAT: - return mk_concat(num_args, args, result); + st = mk_concat(num_args, args, result); + break; case OP_EXTRACT: SASSERT(num_args == 1); - return mk_extract(m_util.get_extract_high(f), m_util.get_extract_low(f), args[0], result); + st = mk_extract(m_util.get_extract_high(f), m_util.get_extract_low(f), args[0], result); + break; case OP_REPEAT: SASSERT(num_args == 1); - return mk_repeat(f->get_parameter(0).get_int(), args[0], result); + st = mk_repeat(f->get_parameter(0).get_int(), args[0], result); + break; case OP_ZERO_EXT: SASSERT(num_args == 1); return mk_zero_extend(f->get_parameter(0).get_int(), args[0], result); @@ -596,28 +602,45 @@ br_status bv_rewriter::mk_leq_core(bool is_signed, expr * a, expr * b, expr_ref // // a <=_u #x000f // - unsigned bv_sz = m_util.get_bv_size(b); - unsigned i = bv_sz; - unsigned first_non_zero = UINT_MAX; - while (i > 0) { - --i; - if (!is_zero_bit(b, i)) { - first_non_zero = i; - break; - } - } + unsigned bv_sz = m_util.get_bv_size(a); + auto last_non_zero = [&](expr* x) { + for (unsigned i = bv_sz; i-- > 0; ) + if (!is_zero_bit(x, i)) + return i; + return UINT_MAX; + }; + + unsigned lnz = last_non_zero(b); - if (first_non_zero == UINT_MAX) { + if (lnz == UINT_MAX) { // all bits are zero result = m.mk_eq(a, mk_zero(bv_sz)); return BR_REWRITE1; } - else if (first_non_zero < bv_sz - 1 && m_le2extract) { - result = m.mk_and(m.mk_eq(m_mk_extract(bv_sz - 1, first_non_zero + 1, a), mk_zero(bv_sz - first_non_zero - 1)), - m_util.mk_ule(m_mk_extract(first_non_zero, 0, a), m_mk_extract(first_non_zero, 0, b))); + else if (lnz < bv_sz - 1 && m_le2extract) { + // a[sz-1:lnz+1] = 0 & a[lnz:0] <= b[lnz:0] + result = m.mk_and(m.mk_eq(m_mk_extract(bv_sz - 1, lnz + 1, a), mk_zero(bv_sz - lnz - 1)), + m_util.mk_ule(m_mk_extract(lnz, 0, a), m_mk_extract(lnz, 0, b))); + return BR_REWRITE3; } + + lnz = last_non_zero(a); + + if (lnz == UINT_MAX) { + // all bits are zero + result = m.mk_true(); + return BR_DONE; + } + else if (lnz < bv_sz - 1 && m_le2extract) { + // use the equivalence to simplify: + // #x000f <=_u b <=> b[sz-1:lnz+1] != 0 or #xf <= b[lnz:0]) + + result = m.mk_implies(m.mk_eq(m_mk_extract(bv_sz - 1, lnz + 1, b), mk_zero(bv_sz - lnz - 1)), + m_util.mk_ule(m_mk_extract(lnz, 0, a), m_mk_extract(lnz, 0, b))); + return BR_REWRITE_FULL; + } } #endif @@ -1422,19 +1445,50 @@ br_status bv_rewriter::mk_bv_smod_core(expr * arg1, expr * arg2, bool hi_div0, e br_status bv_rewriter::mk_int2bv(unsigned bv_size, expr * arg, expr_ref & result) { numeral val; bool is_int; - + expr* x; if (m_autil.is_numeral(arg, val, is_int)) { val = m_util.norm(val, bv_size); result = mk_numeral(val, bv_size); return BR_DONE; } - // (int2bv (bv2int x)) --> x - if (m_util.is_bv2int(arg) && bv_size == get_bv_size(to_app(arg)->get_arg(0))) { - result = to_app(arg)->get_arg(0); + // int2bv (bv2int x) --> x + if (m_util.is_bv2int(arg, x) && bv_size == get_bv_size(x)) { + result = x; return BR_DONE; } + // int2bv (bv2int x) --> 0000x + if (m_util.is_bv2int(arg, x) && bv_size > get_bv_size(x)) { + mk_zero_extend(bv_size - get_bv_size(x), x, result); + return BR_REWRITE1; + } + + // int2bv (bv2int x) --> x[sz-1:0] + if (m_util.is_bv2int(arg, x) && bv_size < get_bv_size(x)) { + result = m_mk_extract(bv_size - 1, 0, x); + return BR_REWRITE1; + } + +#if 0 + // int2bv (a + b) --> int2bv(a) + int2bv(b) + if (m_autil.is_add(arg)) { + expr_ref_vector args(m); + for (expr* e : *to_app(arg)) + args.push_back(m_util.mk_int2bv(bv_size, e)); + result = m_util.mk_bv_add(args); + return BR_REWRITE3; + } + // int2bv (a * b) --> int2bv(a) * int2bv(b) + if (m_autil.is_mul(arg)) { + expr_ref_vector args(m); + for (expr* e : *to_app(arg)) + args.push_back(m_util.mk_int2bv(bv_size, e)); + result = m_util.mk_bv_mul(args); + return BR_REWRITE3; + } +#endif + return BR_FAILED; } @@ -2717,6 +2771,27 @@ bool bv_rewriter::is_urem_any(expr * e, expr * & dividend, expr * & divisor) { return true; } +br_status bv_rewriter::mk_eq_bv2int(expr* lhs, expr* rhs, expr_ref& result) { + rational r; + expr* x, *y; + if (m_autil.is_numeral(lhs)) + std::swap(lhs, rhs); + + if (m_autil.is_numeral(rhs, r) && m_util.is_bv2int(lhs, x)) { + unsigned bv_size = m_util.get_bv_size(x); + if (0 <= r && r < rational::power_of_two(bv_size)) + result = m.mk_eq(m_util.mk_numeral(r, bv_size), x); + else + result = m.mk_false(); + return BR_REWRITE1; + } + if (m_util.is_bv2int(lhs, x) && m_util.is_bv2int(rhs, y)) { + result = m.mk_eq(x, y); + return BR_REWRITE1; + } + return BR_FAILED; +} + br_status bv_rewriter::mk_eq_core(expr * lhs, expr * rhs, expr_ref & result) { if (lhs == rhs) { result = m.mk_true(); @@ -2760,6 +2835,7 @@ br_status bv_rewriter::mk_eq_core(expr * lhs, expr * rhs, expr_ref & result) { return st; } + if (m_blast_eq_value) { st = mk_blast_eq_value(lhs, rhs, result); if (st != BR_FAILED) diff --git a/src/ast/rewriter/bv_rewriter.h b/src/ast/rewriter/bv_rewriter.h index 0fb4cdd99..bcf797353 100644 --- a/src/ast/rewriter/bv_rewriter.h +++ b/src/ast/rewriter/bv_rewriter.h @@ -203,6 +203,7 @@ public: bool is_urem_any(expr * e, expr * & dividend, expr * & divisor); br_status mk_eq_core(expr * lhs, expr * rhs, expr_ref & result); + br_status mk_eq_bv2int(expr* lhs, expr* rhs, expr_ref& result); br_status mk_ite_core(expr * c, expr * t, expr * e, expr_ref & result); br_status mk_distinct(unsigned num_args, expr * const * args, expr_ref & result); diff --git a/src/ast/rewriter/factor_equivs.h b/src/ast/rewriter/factor_equivs.h index 7c58f4abd..d4d566ed6 100644 --- a/src/ast/rewriter/factor_equivs.h +++ b/src/ast/rewriter/factor_equivs.h @@ -103,11 +103,10 @@ public: m_first = false; return *this; } - bool operator==(const iterator& o) { + bool operator!=(const iterator& o) const { SASSERT(&m_ouf == &o.m_ouf); - return m_first == o.m_first && m_curr_id == o.m_curr_id; + return m_first != o.m_first || m_curr_id != o.m_curr_id; } - bool operator!=(const iterator& o) {return !(*this == o);} }; iterator begin(OBJ*o) { @@ -152,11 +151,10 @@ public: m_ouf.m_uf.is_root(m_rootnb) != true); return *this; } - bool operator==(const equiv_iterator& o) { + bool operator!=(const equiv_iterator& o) const { SASSERT(&m_ouf == &o.m_ouf); - return m_rootnb == o.m_rootnb; + return m_rootnb != o.m_rootnb; } - bool operator!=(const equiv_iterator& o) {return !(*this == o);} }; equiv_iterator begin() {return equiv_iterator(*this, 0);} diff --git a/src/ast/rewriter/inj_axiom.cpp b/src/ast/rewriter/inj_axiom.cpp index bdf784230..a46e60e5c 100644 --- a/src/ast/rewriter/inj_axiom.cpp +++ b/src/ast/rewriter/inj_axiom.cpp @@ -74,6 +74,7 @@ bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result) { } } if (found_vars && !has_free_vars(q)) { + (void)num_vars; TRACE("inj_axiom", tout << "Cadidate for simplification:\n" << mk_ll_pp(q, m) << mk_pp(app1, m) << "\n" << mk_pp(app2, m) << "\n" << mk_pp(var1, m) << "\n" << mk_pp(var2, m) << "\nnum_vars: " << num_vars << "\n";); diff --git a/src/ast/rewriter/label_rewriter.cpp b/src/ast/rewriter/label_rewriter.cpp index 8adefb896..548d4fa82 100644 --- a/src/ast/rewriter/label_rewriter.cpp +++ b/src/ast/rewriter/label_rewriter.cpp @@ -26,8 +26,6 @@ label_rewriter::label_rewriter(ast_manager & m) : m_label_fid(m.get_label_family_id()), m_rwr(m, false, *this) {} -label_rewriter::~label_rewriter() {} - br_status label_rewriter::reduce_app( func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { diff --git a/src/ast/rewriter/label_rewriter.h b/src/ast/rewriter/label_rewriter.h index 8bec62ed6..a4720853c 100644 --- a/src/ast/rewriter/label_rewriter.h +++ b/src/ast/rewriter/label_rewriter.h @@ -27,7 +27,6 @@ class label_rewriter : public default_rewriter_cfg { rewriter_tpl m_rwr; public: label_rewriter(ast_manager & m); - ~label_rewriter(); br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr); diff --git a/src/ast/rewriter/rewriter.h b/src/ast/rewriter/rewriter.h index cd89bb2f9..1afa19f84 100644 --- a/src/ast/rewriter/rewriter.h +++ b/src/ast/rewriter/rewriter.h @@ -346,8 +346,6 @@ public: ast_manager & m() const { return this->m_manager; } Config & cfg() { return m_cfg; } Config const & cfg() const { return m_cfg; } - - ~rewriter_tpl() override {}; void reset(); void cleanup(); diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index 50f0bc05a..7e39931f4 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -2060,6 +2060,10 @@ br_status seq_rewriter::mk_seq_replace_all(expr* a, expr* b, expr* c, expr_ref& result = m().mk_ite(str().mk_is_empty(b), str().mk_empty(a->get_sort()), c); return BR_REWRITE2; } + if (str().is_empty(a) && str().is_empty(c)) { + result = a; + return BR_DONE; + } zstring s1, s2; expr_ref_vector strs(m()); if (str().is_string(a, s1) && str().is_string(b, s2)) { diff --git a/src/ast/rewriter/th_rewriter.cpp b/src/ast/rewriter/th_rewriter.cpp index 844c51940..3af887008 100644 --- a/src/ast/rewriter/th_rewriter.cpp +++ b/src/ast/rewriter/th_rewriter.cpp @@ -59,6 +59,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg { bv_util m_bv_util; der m_der; expr_safe_replace m_rep; + unused_vars_eliminator m_elim_unused_vars; expr_ref_vector m_pinned; // substitution support expr_dependency_ref m_used_dependencies; // set of dependencies of used substitutions @@ -685,9 +686,18 @@ struct th_rewriter_cfg : public default_rewriter_cfg { st = m_seq_rw.mk_eq_core(a, b, result); if (st != BR_FAILED) return st; + st = extended_bv_eq(a, b, result); + if (st != BR_FAILED) + return st; return apply_tamagotchi(a, b, result); } + br_status extended_bv_eq(expr* a, expr* b, expr_ref& result) { + if (m_bv_util.is_bv2int(a) || m_bv_util.is_bv2int(b)) + return m_bv_rw.mk_eq_bv2int(a, b, result); + return BR_FAILED; + } + expr_ref mk_eq(expr* a, expr* b) { expr_ref result(m()); br_status st = reduce_eq(a, b, result); @@ -820,8 +830,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg { } } SASSERT(old_q->get_sort() == q1->get_sort()); - result = elim_unused_vars(m(), q1, params_ref()); - + result = m_elim_unused_vars(q1); result_pr = nullptr; @@ -878,6 +887,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg { m_bv_util(m), m_der(m), m_rep(m), + m_elim_unused_vars(m, params_ref()), m_pinned(m), m_used_dependencies(m) { updt_local_params(p); diff --git a/src/ast/rewriter/var_subst.cpp b/src/ast/rewriter/var_subst.cpp index ec33bd265..820a235d8 100644 --- a/src/ast/rewriter/var_subst.cpp +++ b/src/ast/rewriter/var_subst.cpp @@ -52,6 +52,24 @@ expr_ref var_subst::operator()(expr * n, unsigned num_args, expr * const * args) rep(n, result); return result; } + if (is_app(n) && all_of(*to_app(n), [&](expr* arg) { return is_ground(arg) || is_var(arg); })) { + ptr_buffer new_args; + for (auto arg : *to_app(n)) { + if (is_ground(arg)) + new_args.push_back(arg); + else { + unsigned idx = to_var(arg)->get_idx(); + expr* new_arg = nullptr; + if (idx < num_args) + new_arg = m_std_order ? args[num_args - idx - 1] : args[idx]; + if (!new_arg) + new_arg = arg; + new_args.push_back(new_arg); + } + } + result = m.mk_app(to_app(n)->get_decl(), new_args.size(), new_args.data()); + return result; + } SASSERT(is_well_sorted(result.m(), n)); m_reducer.reset(); if (m_std_order) diff --git a/src/ast/rewriter/var_subst.h b/src/ast/rewriter/var_subst.h index e9d39740d..aa905cb0e 100644 --- a/src/ast/rewriter/var_subst.h +++ b/src/ast/rewriter/var_subst.h @@ -94,7 +94,7 @@ class expr_free_vars { ptr_vector m_sorts; ptr_vector m_todo; public: - expr_free_vars() {} + expr_free_vars() = default; expr_free_vars(expr* e) { (*this)(e); } void reset(); void operator()(expr* e); diff --git a/src/ast/seq_decl_plugin.h b/src/ast/seq_decl_plugin.h index c6550d33a..c08ed6f7a 100644 --- a/src/ast/seq_decl_plugin.h +++ b/src/ast/seq_decl_plugin.h @@ -446,7 +446,7 @@ public: /* Default constructor of invalid info. */ - info() {} + info() = default; /* Used for constructing either an invalid info that is only used to indicate uninitialized entry, or valid but unknown info value. diff --git a/src/ast/simplifiers/dominator_simplifier.cpp b/src/ast/simplifiers/dominator_simplifier.cpp index 2ef4528ab..0f9d70786 100644 --- a/src/ast/simplifiers/dominator_simplifier.cpp +++ b/src/ast/simplifiers/dominator_simplifier.cpp @@ -187,8 +187,8 @@ expr_ref dominator_simplifier::simplify_and_or(bool is_and, app * e) { } expr_ref dominator_simplifier::simplify_not(app * e) { - expr *ee; - ENSURE(m.is_not(e, ee)); + expr *ee = nullptr; + VERIFY(m.is_not(e, ee)); unsigned old_lvl = scope_level(); expr_ref t = simplify_rec(ee); local_pop(scope_level() - old_lvl); diff --git a/src/ast/simplifiers/linear_equation.h b/src/ast/simplifiers/linear_equation.h index 5220a1e46..662c8c9fc 100644 --- a/src/ast/simplifiers/linear_equation.h +++ b/src/ast/simplifiers/linear_equation.h @@ -35,7 +35,7 @@ private: mpz * m_as; // precise coefficients double * m_approx_as; // approximated coefficients var * m_xs; // var ids - linear_equation() {} + linear_equation() = default; public: unsigned size() const { return m_size; } mpz const & a(unsigned idx) const { SASSERT(idx < m_size); return m_as[idx]; } diff --git a/src/ast/simplifiers/reduce_args_simplifier.cpp b/src/ast/simplifiers/reduce_args_simplifier.cpp index f9c788792..96607734b 100644 --- a/src/ast/simplifiers/reduce_args_simplifier.cpp +++ b/src/ast/simplifiers/reduce_args_simplifier.cpp @@ -375,8 +375,6 @@ public: m_bv(m) {} - ~reduce_args_simplifier() override {} - char const* name() const override { return "reduce-args"; } void collect_statistics(statistics& st) const override { diff --git a/src/ast/sls/bvsls_opt_engine.cpp b/src/ast/sls/bvsls_opt_engine.cpp index 7dc71cd8c..2f006dc9f 100644 --- a/src/ast/sls/bvsls_opt_engine.cpp +++ b/src/ast/sls/bvsls_opt_engine.cpp @@ -28,10 +28,6 @@ bvsls_opt_engine::bvsls_opt_engine(ast_manager & m, params_ref const & p) : m_best_model = alloc(model, m); } -bvsls_opt_engine::~bvsls_opt_engine() -{ -} - bvsls_opt_engine::optimization_result bvsls_opt_engine::optimize( expr_ref const & objective, model_ref initial_model, diff --git a/src/ast/sls/bvsls_opt_engine.h b/src/ast/sls/bvsls_opt_engine.h index 423dfd6a3..1ad362598 100644 --- a/src/ast/sls/bvsls_opt_engine.h +++ b/src/ast/sls/bvsls_opt_engine.h @@ -31,7 +31,6 @@ class bvsls_opt_engine : public sls_engine { public: bvsls_opt_engine(ast_manager & m, params_ref const & p); - ~bvsls_opt_engine(); class optimization_result { public: diff --git a/src/ast/sls/sls_bv_valuation.h b/src/ast/sls/sls_bv_valuation.h index 4f7c8f902..9156c934f 100644 --- a/src/ast/sls/sls_bv_valuation.h +++ b/src/ast/sls/sls_bv_valuation.h @@ -31,7 +31,7 @@ namespace sls { unsigned nw = 0; unsigned mask = 0; - bvect() {} + bvect() = default; bvect(unsigned sz) : svector(sz, (unsigned)0) {} void set_bw(unsigned bw); diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index c93e4432f..beb3aa0bb 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -318,6 +318,22 @@ UNARY_CMD(echo_cmd, "echo", "", "display the given string", CPK_STRING, else ctx.regular_stream() << arg << std::endl;); +class set_initial_value_cmd : public cmd { + expr* m_var = nullptr, *m_value = nullptr; +public: + set_initial_value_cmd(): cmd("set-initial-value") {} + char const* get_usage() const override { return " "; } + char const* get_descr(cmd_context& ctx) const override { return "set an initial value for search as a hint to the solver"; } + unsigned get_arity() const override { return 2; } + void prepare(cmd_context& ctx) override { m_var = m_value = nullptr; } + cmd_arg_kind next_arg_kind(cmd_context& ctx) const override { return CPK_EXPR; } + void set_next_arg(cmd_context& ctx, expr* e) override { if (m_var) m_value = e; else m_var = e; } + void execute(cmd_context& ctx) override { + SASSERT(m_var && m_value); + ctx.set_initial_value(m_var, m_value); + } +}; + class set_get_option_cmd : public cmd { protected: symbol m_true; @@ -893,6 +909,7 @@ void install_basic_cmds(cmd_context & ctx) { ctx.insert(alloc(get_option_cmd)); ctx.insert(alloc(get_info_cmd)); ctx.insert(alloc(set_info_cmd)); + ctx.insert(alloc(set_initial_value_cmd)); ctx.insert(alloc(get_consequences_cmd)); ctx.insert(alloc(builtin_cmd, "assert", "", "assert term.")); ctx.insert(alloc(builtin_cmd, "check-sat", "*", "check if the current context is satisfiable. If a list of boolean constants B is provided, then check if the current context is consistent with assigning every constant in B to true.")); diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 231c78bc2..577cc95b6 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -33,7 +33,6 @@ Notes: #include "ast/fpa_decl_plugin.h" #include "ast/special_relations_decl_plugin.h" #include "ast/ast_pp.h" -#include "ast/rewriter/var_subst.h" #include "ast/pp.h" #include "ast/ast_smt2_pp.h" #include "ast/ast_ll_pp.h" @@ -52,6 +51,7 @@ Notes: #include "solver/smt_logics.h" #include "cmd_context/basic_cmds.h" #include "cmd_context/cmd_context.h" +#include "solver/slice_solver.h" #include func_decls::func_decls(ast_manager & m, func_decl * f): @@ -406,8 +406,7 @@ void cmd_context::insert_macro(symbol const& s, unsigned arity, sort*const* doma recfun::promise_def d = p.ensure_def(s, arity, domain, t->get_sort(), false); // recursive functions have opposite calling convention from macros! - var_subst sub(m(), true); - expr_ref tt = sub(t, rvars); + expr_ref tt = std_subst()(t, rvars); p.set_definition(replace, d, true, vars.size(), vars.data(), tt); register_fun(s, d.get_def()->get_decl()); } @@ -461,7 +460,6 @@ bool cmd_context::macros_find(symbol const& s, unsigned n, expr*const* args, exp if (eq) { t = d.m_body; t = sub(t); - verbose_stream() << "macro " << t << "\n"; ptr_buffer domain; for (unsigned i = 0; i < n; ++i) domain.push_back(args[i]->get_sort()); @@ -629,6 +627,7 @@ cmd_context::~cmd_context() { finalize_cmds(); finalize_tactic_manager(); m_proof_cmds = nullptr; + m_var2values.reset(); reset(true); m_mcs.reset(); m_solver = nullptr; @@ -654,6 +653,8 @@ void cmd_context::set_opt(opt_wrapper* opt) { m_opt = opt; for (unsigned i = 0; i < m_scopes.size(); ++i) m_opt->push(); + for (auto const& [var, value] : m_var2values) + m_opt->initialize_value(var, value); m_opt->set_logic(m_logic); } @@ -1254,9 +1255,8 @@ bool cmd_context::try_mk_macro_app(symbol const & s, unsigned num_args, expr * c tout << "s: " << s << "\n"; tout << "body:\n" << mk_ismt2_pp(_t, m()) << "\n"; tout << "args:\n"; for (unsigned i = 0; i < num_args; i++) tout << mk_ismt2_pp(args[i], m()) << "\n" << mk_pp(args[i]->get_sort(), m()) << "\n";); - var_subst subst(m(), false); scoped_rlimit no_limit(m().limit(), 0); - result = subst(_t, coerced_args); + result = rev_subst()(_t, coerced_args); if (well_sorted_check_enabled() && !is_well_sorted(m(), result)) throw cmd_exception("invalid macro application, sort mismatch ", s); return true; @@ -1515,12 +1515,15 @@ void cmd_context::reset(bool finalize) { m_opt = nullptr; m_pp_env = nullptr; m_dt_eh = nullptr; + m_std_subst = nullptr; + m_rev_subst = nullptr; if (m_manager) { dealloc(m_pmanager); m_pmanager = nullptr; if (m_own_manager) { dealloc(m_manager); m_manager = nullptr; + m_manager_initialized = false; } else { @@ -1874,6 +1877,17 @@ void cmd_context::display_dimacs() { } } +void cmd_context::set_initial_value(expr* var, expr* value) { + if (get_opt()) { + get_opt()->initialize_value(var, value); + return; + } + if (get_solver()) + get_solver()->user_propagate_initialize_value(var, value); + m_var2values.push_back({expr_ref(var, m()), expr_ref(value, m())}); +} + + void cmd_context::display_model(model_ref& mdl) { if (mdl) { if (mc0()) (*mc0())(mdl); @@ -2244,6 +2258,7 @@ void cmd_context::mk_solver() { params_ref p; m_params.get_solver_params(p, proofs_enabled, models_enabled, unsat_core_enabled); m_solver = (*m_solver_factory)(m(), p, proofs_enabled, models_enabled, unsat_core_enabled, m_logic); + m_solver = mk_slice_solver(m_solver.get()); } @@ -2450,9 +2465,6 @@ cmd_context::dt_eh::dt_eh(cmd_context & owner): m_dt_util(owner.m()) { } -cmd_context::dt_eh::~dt_eh() { -} - void cmd_context::dt_eh::operator()(sort * dt, pdecl* pd) { TRACE("new_dt_eh", tout << "new datatype: "; m_owner.pm().display(tout, dt); tout << "\n";); for (func_decl * c : *m_dt_util.get_datatype_constructors(dt)) { diff --git a/src/cmd_context/cmd_context.h b/src/cmd_context/cmd_context.h index c07d888c7..dde1d7962 100644 --- a/src/cmd_context/cmd_context.h +++ b/src/cmd_context/cmd_context.h @@ -33,6 +33,7 @@ Notes: #include "ast/datatype_decl_plugin.h" #include "ast/recfun_decl_plugin.h" #include "ast/rewriter/seq_rewriter.h" +#include "ast/rewriter/var_subst.h" #include "ast/converters/generic_model_converter.h" #include "solver/solver.h" #include "solver/check_logic.h" @@ -47,7 +48,7 @@ class func_decls { bool signatures_collide(func_decl* f, func_decl* g) const; bool signatures_collide(unsigned n, sort*const* domain, sort* range, func_decl* g) const; public: - func_decls() {} + func_decls() = default; func_decls(ast_manager & m, func_decl * f); void finalize(ast_manager & m); bool contains(func_decl * f) const; @@ -173,6 +174,8 @@ public: virtual void set_logic(symbol const& s) = 0; virtual void get_box_model(model_ref& mdl, unsigned index) = 0; virtual void updt_params(params_ref const& p) = 0; + virtual void initialize_value(expr* var, expr* value) = 0; + }; class ast_context_params : public context_params { @@ -260,6 +263,7 @@ protected: scoped_ptr_vector m_extra_builtin_decls; // make sure that dynamically allocated builtin_decls are deleted dictionary m_object_refs; // anything that can be named. dictionary m_user_tactic_decls; + vector> m_var2values; dictionary m_func_decls; obj_map m_func_decl2alias; @@ -277,6 +281,7 @@ protected: ptr_vector m_assertions; std::vector m_assertion_strings; ptr_vector m_assertion_names; // named assertions are represented using boolean variables. + scoped_ptr m_std_subst, m_rev_subst; struct scope { unsigned m_func_decls_stack_lim; @@ -302,7 +307,6 @@ protected: public: void reset() { m_dt_util.reset(); } dt_eh(cmd_context & owner); - ~dt_eh() override; void operator()(sort * dt, pdecl* pd) override; }; @@ -315,6 +319,9 @@ protected: scoped_ptr m_pp_env; pp_env & get_pp_env() const; + var_subst& std_subst() { if (!m_std_subst) m_std_subst = alloc(var_subst, m(), true); return *m_std_subst; } + var_subst& rev_subst() { if (!m_rev_subst) m_rev_subst = alloc(var_subst, m(), false); return *m_rev_subst; } + void register_builtin_sorts(decl_plugin * p); void register_builtin_ops(decl_plugin * p); void load_plugin(symbol const & name, bool install_names, svector& fids); @@ -419,6 +426,7 @@ public: solver* get_solver() { return m_solver.get(); } void set_solver(solver* s) { m_solver = s; } void set_proof_cmds(proof_cmds* pc) { m_proof_cmds = pc; } + void set_initial_value(expr* var, expr* value); void set_solver_factory(solver_factory * s); void set_check_sat_result(check_sat_result * r) { m_check_sat_result = r; } diff --git a/src/cmd_context/tactic_cmds.cpp b/src/cmd_context/tactic_cmds.cpp index a0805110b..b2b858b07 100644 --- a/src/cmd_context/tactic_cmds.cpp +++ b/src/cmd_context/tactic_cmds.cpp @@ -27,7 +27,6 @@ Notes: #include "ast/ast_smt2_pp.h" #include "tactic/tactic.h" #include "tactic/tactical.h" -#include "tactic/probe.h" #include "solver/check_sat_result.h" #include "cmd_context/cmd_context_to_goal.h" #include "cmd_context/echo_tactic.h" @@ -38,9 +37,6 @@ probe_info::probe_info(symbol const & n, char const * d, probe * p): m_probe(p) { } -probe_info::~probe_info() { -} - class declare_tactic_cmd : public cmd { symbol m_name; sexpr * m_decl; diff --git a/src/cmd_context/tactic_cmds.h b/src/cmd_context/tactic_cmds.h index 5096ae962..de5fda0a8 100644 --- a/src/cmd_context/tactic_cmds.h +++ b/src/cmd_context/tactic_cmds.h @@ -18,12 +18,12 @@ Notes: #pragma once #include "ast/ast.h" +#include "tactic/probe.h" #include "util/params.h" #include "util/cmd_context_types.h" #include "util/ref.h" class tactic; -class probe; typedef tactic* (*tactic_factory)(ast_manager&, const params_ref&); @@ -52,7 +52,6 @@ class probe_info { ref m_probe; public: probe_info(symbol const & n, char const * d, probe * p); - ~probe_info(); symbol get_name() const { return m_name; } char const * get_descr() const { return m_descr; } diff --git a/src/math/dd/dd_pdd.h b/src/math/dd/dd_pdd.h index fa545c06e..4fe208429 100644 --- a/src/math/dd/dd_pdd.h +++ b/src/math/dd/dd_pdd.h @@ -571,8 +571,7 @@ namespace dd { pdd_monomial const* operator->() const { return &m_mono; } pdd_iterator& operator++() { next(); return *this; } pdd_iterator operator++(int) { auto tmp = *this; next(); return tmp; } - bool operator==(pdd_iterator const& other) const { return m_nodes == other.m_nodes; } - bool operator!=(pdd_iterator const& other) const { return !operator==(other); } + bool operator!=(pdd_iterator const& other) const { return m_nodes != other.m_nodes; } }; class pdd_linear_iterator { @@ -591,7 +590,6 @@ namespace dd { pointer operator->() const { return &m_mono; } pdd_linear_iterator& operator++() { next(); return *this; } pdd_linear_iterator operator++(int) { auto tmp = *this; next(); return tmp; } - bool operator==(pdd_linear_iterator const& other) const { return m_next == other.m_next; } bool operator!=(pdd_linear_iterator const& other) const { return m_next != other.m_next; } }; diff --git a/src/math/grobner/grobner.h b/src/math/grobner/grobner.h index 6adffea7c..83c0d8a5e 100644 --- a/src/math/grobner/grobner.h +++ b/src/math/grobner/grobner.h @@ -48,7 +48,7 @@ public: friend class grobner; friend struct monomial_lt; - monomial() {} + monomial() = default; public: rational const & get_coeff() const { return m_coeff; } unsigned get_degree() const { return m_vars.size(); } @@ -63,7 +63,7 @@ public: ptr_vector m_monomials; //!< sorted monomials v_dependency * m_dep; //!< justification for the equality friend class grobner; - equation() {} + equation() = default; public: unsigned get_num_monomials() const { return m_monomials.size(); } monomial const * get_monomial(unsigned idx) const { return m_monomials[idx]; } diff --git a/src/math/hilbert/heap_trie.h b/src/math/hilbert/heap_trie.h index b492fb7ee..3feb68ba6 100644 --- a/src/math/hilbert/heap_trie.h +++ b/src/math/hilbert/heap_trie.h @@ -369,7 +369,6 @@ public: } iterator& operator++() { fwd(); return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } - bool operator==(iterator const& it) const {return m_count == it.m_count; } bool operator!=(iterator const& it) const {return m_count != it.m_count; } private: diff --git a/src/math/hilbert/hilbert_basis.cpp b/src/math/hilbert/hilbert_basis.cpp index 586027103..308adf54f 100644 --- a/src/math/hilbert/hilbert_basis.cpp +++ b/src/math/hilbert/hilbert_basis.cpp @@ -455,7 +455,6 @@ public: offset_t operator*() const { return p.m_passive[m_idx]; } iterator& operator++() { ++m_idx; fwd(); return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } - bool operator==(iterator const& it) const {return m_idx == it.m_idx; } bool operator!=(iterator const& it) const {return m_idx != it.m_idx; } }; @@ -614,7 +613,6 @@ public: offset_t sos() const { return (p.hb.vec(pas()).weight().is_pos()?p.m_neg_sos:p.m_pos_sos)[p.m_psos[m_idx]]; } iterator& operator++() { ++m_idx; fwd(); return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } - bool operator==(iterator const& it) const {return m_idx == it.m_idx; } bool operator!=(iterator const& it) const {return m_idx != it.m_idx; } }; diff --git a/src/math/hilbert/hilbert_basis.h b/src/math/hilbert/hilbert_basis.h index 8be44290b..0f089139e 100644 --- a/src/math/hilbert/hilbert_basis.h +++ b/src/math/hilbert/hilbert_basis.h @@ -115,7 +115,6 @@ class hilbert_basis { offset_t operator*() const { return hb.m_basis[m_idx]; } iterator& operator++() { ++m_idx; return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } - bool operator==(iterator const& it) const {return m_idx == it.m_idx; } bool operator!=(iterator const& it) const {return m_idx != it.m_idx; } }; diff --git a/src/math/interval/mod_interval.h b/src/math/interval/mod_interval.h index ed189fe7b..28b69b003 100644 --- a/src/math/interval/mod_interval.h +++ b/src/math/interval/mod_interval.h @@ -26,7 +26,7 @@ namespace bv { bool tight = true; interval_tpl(T const& l, T const& h, unsigned sz, bool tight = false): l(l), h(h), sz(sz), tight(tight) {} - interval_tpl() {} + interval_tpl() = default; bool invariant() const { return @@ -167,7 +167,7 @@ namespace bv { iinterval i; rinterval r; - interval() {} + interval() = default; interval(rational const& l, rational const& h, unsigned sz, bool tight = false) { if (sz <= 64) { diff --git a/src/math/lp/core_solver_pretty_printer.cpp b/src/math/lp/core_solver_pretty_printer.cpp index 18bef8303..65a9aef97 100644 --- a/src/math/lp/core_solver_pretty_printer.cpp +++ b/src/math/lp/core_solver_pretty_printer.cpp @@ -21,7 +21,5 @@ Revision History: #include "math/lp/core_solver_pretty_printer_def.h" template lp::core_solver_pretty_printer::core_solver_pretty_printer(const lp::lp_core_solver_base &, std::ostream & out); template void lp::core_solver_pretty_printer::print(); -template lp::core_solver_pretty_printer::~core_solver_pretty_printer(); template lp::core_solver_pretty_printer >::core_solver_pretty_printer(const lp::lp_core_solver_base > &, std::ostream & out); -template lp::core_solver_pretty_printer >::~core_solver_pretty_printer(); template void lp::core_solver_pretty_printer >::print(); diff --git a/src/math/lp/core_solver_pretty_printer.h b/src/math/lp/core_solver_pretty_printer.h index 5bf29d511..c9ab99760 100644 --- a/src/math/lp/core_solver_pretty_printer.h +++ b/src/math/lp/core_solver_pretty_printer.h @@ -66,7 +66,6 @@ public: void init_costs(); - ~core_solver_pretty_printer(); void init_rs_width(); T current_column_norm(); diff --git a/src/math/lp/core_solver_pretty_printer_def.h b/src/math/lp/core_solver_pretty_printer_def.h index cbe67ea36..6d35273af 100644 --- a/src/math/lp/core_solver_pretty_printer_def.h +++ b/src/math/lp/core_solver_pretty_printer_def.h @@ -67,8 +67,6 @@ template void core_solver_pretty_printer::init_co } -template core_solver_pretty_printer::~core_solver_pretty_printer() { -} template void core_solver_pretty_printer::init_rs_width() { m_rs_width = static_cast(T_to_string(m_core_solver.get_cost()).size()); for (unsigned i = 0; i < nrows(); i++) { diff --git a/src/math/lp/emonics.h b/src/math/lp/emonics.h index 55086515d..f6326c044 100644 --- a/src/math/lp/emonics.h +++ b/src/math/lp/emonics.h @@ -51,9 +51,8 @@ class emonics { unsigned m_index; }; struct head_tail { - head_tail(): m_head(nullptr), m_tail(nullptr) {} - cell* m_head; - cell* m_tail; + cell* m_head = nullptr; + cell* m_tail = nullptr; }; struct hash_canonical { emonics& em; @@ -205,7 +204,6 @@ public: monic & operator*() { return m.m_monics[m_cell->m_index]; } iterator& operator++() { m_touched = true; m_cell = m_cell->m_next; return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } - bool operator==(iterator const& other) const { return m_cell == other.m_cell && m_touched == other.m_touched; } bool operator!=(iterator const& other) const { return m_cell != other.m_cell || m_touched != other.m_touched; } }; @@ -239,7 +237,6 @@ public: } pf_iterator& operator++() { ++m_it; fast_forward(); return *this; } pf_iterator operator++(int) { pf_iterator tmp = *this; ++*this; return tmp; } - bool operator==(pf_iterator const& other) const { return m_it == other.m_it; } bool operator!=(pf_iterator const& other) const { return m_it != other.m_it; } }; diff --git a/src/math/lp/explanation.h b/src/math/lp/explanation.h index 960c5fb4a..850e59cd4 100644 --- a/src/math/lp/explanation.h +++ b/src/math/lp/explanation.h @@ -29,7 +29,7 @@ class explanation { vector> m_vector; ci_set m_set; public: - explanation() {} + explanation() = default; template explanation(const T& t) { @@ -106,11 +106,10 @@ public: iterator(bool run_on_vector, pair_vec::const_iterator vi, ci_set::iterator cii) : m_run_on_vector(run_on_vector), m_vi(vi), m_ci(cii) {} - bool operator==(const iterator &other) const { + bool operator!=(const iterator &other) const { SASSERT(m_run_on_vector == other.m_run_on_vector); - return m_run_on_vector? m_vi == other.m_vi : m_ci == other.m_ci; + return m_run_on_vector ? m_vi != other.m_vi : m_ci != other.m_ci; } - bool operator!=(const iterator &other) const { return !(*this == other); } }; iterator begin() const { diff --git a/src/math/lp/factorization.cpp b/src/math/lp/factorization.cpp index e1dcff626..89c16ec91 100644 --- a/src/math/lp/factorization.cpp +++ b/src/math/lp/factorization.cpp @@ -97,14 +97,12 @@ const_iterator_mon::const_iterator_mon(const bool_vector& mask, const factorizat m_ff(f) , m_full_factorization_returned(false) {} - -bool const_iterator_mon::operator==(const const_iterator_mon::self_type &other) const { - return - m_full_factorization_returned == other.m_full_factorization_returned && - m_mask == other.m_mask; -} -bool const_iterator_mon::operator!=(const const_iterator_mon::self_type &other) const { return !(*this == other); } +bool const_iterator_mon::operator!=(const const_iterator_mon::self_type &other) const { + return + m_full_factorization_returned != other.m_full_factorization_returned || + m_mask != other.m_mask; +} factorization const_iterator_mon::create_binary_factorization(factor j, factor k) const { factorization f(nullptr); diff --git a/src/math/lp/factorization.h b/src/math/lp/factorization.h index e1096a75f..128b269fa 100644 --- a/src/math/lp/factorization.h +++ b/src/math/lp/factorization.h @@ -24,7 +24,7 @@ class factor { factor_type m_type = factor_type::VAR; bool m_sign = false; public: - factor() { } + factor() = default; explicit factor(lpvar v, factor_type t) : m_var(v), m_type(t) {} unsigned var() const { return m_var; } factor_type type() const { return m_type; } @@ -88,8 +88,7 @@ struct const_iterator_mon { self_type operator++(int); const_iterator_mon(const bool_vector& mask, const factorization_factory *f); - - bool operator==(const self_type &other) const; + bool operator!=(const self_type &other) const; factorization create_binary_factorization(factor j, factor k) const; diff --git a/src/math/lp/general_matrix.h b/src/math/lp/general_matrix.h index fb1030e6b..e42f01ad7 100644 --- a/src/math/lp/general_matrix.h +++ b/src/math/lp/general_matrix.h @@ -180,7 +180,7 @@ public: m_column_permutation.transpose_from_left(j, k); } - general_matrix(){} + general_matrix() = default; general_matrix(unsigned n) : m_row_permutation(n), m_column_permutation(n), diff --git a/src/math/lp/gomory.cpp b/src/math/lp/gomory.cpp index 7b4347af5..6b7817769 100644 --- a/src/math/lp/gomory.cpp +++ b/src/math/lp/gomory.cpp @@ -527,7 +527,7 @@ public: has_small_cut = true; add_cut(cc.m_t, cc.m_k, cc.m_dep); if (lia.settings().get_cancel_flag()) - return lia_move::undef; + return lia_move::cancelled; } if (big_cuts.size()) { @@ -544,6 +544,9 @@ public: if (!_check_feasible()) return lia_move::conflict; + + if (lra.get_status() == lp_status::CANCELLED) + return lia_move::cancelled; if (!lia.has_inf_int()) return lia_move::sat; diff --git a/src/math/lp/hnf_cutter.cpp b/src/math/lp/hnf_cutter.cpp index b120b7aac..7f1af2aaa 100644 --- a/src/math/lp/hnf_cutter.cpp +++ b/src/math/lp/hnf_cutter.cpp @@ -19,8 +19,7 @@ namespace lp { lia(lia), lra(lia.lra), m_settings(lia.settings()), - m_abs_max(zero_of_type()), - m_var_register() {} + m_abs_max(zero_of_type()) {} bool hnf_cutter::is_full() const { return diff --git a/src/math/lp/implied_bound.h b/src/math/lp/implied_bound.h index 195ec0359..6d7fc54b9 100644 --- a/src/math/lp/implied_bound.h +++ b/src/math/lp/implied_bound.h @@ -44,7 +44,7 @@ class implied_bound { k = static_cast(k / 2); return k; } - implied_bound(){} + implied_bound() = default; implied_bound(const mpq & a, unsigned j, bool is_lower_bound, diff --git a/src/math/lp/indexed_value.h b/src/math/lp/indexed_value.h index 92d8f2adf..c0194670d 100644 --- a/src/math/lp/indexed_value.h +++ b/src/math/lp/indexed_value.h @@ -29,7 +29,7 @@ public: // m_other is the offset of the corresponding element in its vector : for a row element it points to the column element offset, // for a column element it points to the row element offset unsigned m_other; - indexed_value() {} + indexed_value() = default; indexed_value(T v, unsigned i, unsigned other) : m_value(v), m_index(i), m_other(other) { diff --git a/src/math/lp/indexed_vector.h b/src/math/lp/indexed_vector.h index 9f3119e9a..5740fdc21 100644 --- a/src/math/lp/indexed_vector.h +++ b/src/math/lp/indexed_vector.h @@ -76,7 +76,7 @@ public: } - indexed_vector() {} + indexed_vector() = default; void resize(unsigned data_size); unsigned data_size() const { diff --git a/src/math/lp/lar_constraints.h b/src/math/lp/lar_constraints.h index b9069625f..1105382e7 100644 --- a/src/math/lp/lar_constraints.h +++ b/src/math/lp/lar_constraints.h @@ -203,7 +203,6 @@ public: lar_base_constraint const* operator->() const { return &cs[m_index]; } iterator& operator++() { next(); return *this; } iterator operator++(int) { auto tmp = *this; next(); return tmp; } - bool operator==(iterator const& other) const { return m_index == other.m_index; } bool operator!=(iterator const& other) const { return m_index != other.m_index; } }; iterator begin() const { return iterator(cs, 0); } @@ -229,7 +228,6 @@ public: constraint_index const* operator->() const { return &m_index; } iterator& operator++() { next(); return *this; } iterator operator++(int) { auto tmp = *this; next(); return tmp; } - bool operator==(iterator const& other) const { return m_index == other.m_index; } bool operator!=(iterator const& other) const { return m_index != other.m_index; } }; iterator begin() const { return iterator(cs, 0); } diff --git a/src/math/lp/lar_solver.cpp b/src/math/lp/lar_solver.cpp index 9272e0298..3e3d98548 100644 --- a/src/math/lp/lar_solver.cpp +++ b/src/math/lp/lar_solver.cpp @@ -1930,9 +1930,10 @@ namespace lp { default: UNREACHABLE(); } - if (m_mpq_lar_core_solver.m_r_upper_bounds[j] == m_mpq_lar_core_solver.m_r_lower_bounds[j]) { + numeric_pair const& lo = m_mpq_lar_core_solver.m_r_lower_bounds[j]; + numeric_pair const& hi = m_mpq_lar_core_solver.m_r_upper_bounds[j]; + if (lo == hi) m_mpq_lar_core_solver.m_column_types[j] = column_type::fixed; - } } void lar_solver::update_bound_with_no_ub_lb(lpvar j, lconstraint_kind kind, const mpq& right_side, u_dependency* dep) { @@ -2081,6 +2082,24 @@ namespace lp { lpvar lar_solver::to_column(unsigned ext_j) const { return m_var_register.external_to_local(ext_j); } + + bool lar_solver::move_lpvar_to_value(lpvar j, mpq const& value) { + if (is_base(j)) + return false; + + impq ivalue(value); + auto& lcs = m_mpq_lar_core_solver; + auto& slv = m_mpq_lar_core_solver.m_r_solver; + + if (slv.column_has_upper_bound(j) && lcs.m_r_upper_bounds()[j] < ivalue) + return false; + if (slv.column_has_lower_bound(j) && lcs.m_r_lower_bounds()[j] > ivalue) + return false; + + set_value_for_nbasic_column(j, ivalue); + return true; + } + bool lar_solver::tighten_term_bounds_by_delta(lpvar j, const impq& delta) { SASSERT(column_has_term(j)); diff --git a/src/math/lp/lar_solver.h b/src/math/lp/lar_solver.h index f223b5cc5..c58fe7917 100644 --- a/src/math/lp/lar_solver.h +++ b/src/math/lp/lar_solver.h @@ -623,6 +623,7 @@ public: lp_status find_feasible_solution(); void move_non_basic_columns_to_bounds(); bool move_non_basic_column_to_bounds(unsigned j); + bool move_lpvar_to_value(lpvar j, mpq const& value); inline bool r_basis_has_inf_int() const { for (unsigned j : r_basis()) { if (column_is_int(j) && !column_value_is_int(j)) diff --git a/src/math/lp/lar_term.h b/src/math/lp/lar_term.h index 6547377d3..8f8dd2f4a 100644 --- a/src/math/lp/lar_term.h +++ b/src/math/lp/lar_term.h @@ -70,7 +70,7 @@ public: } } // constructors - lar_term() {} + lar_term() = default; lar_term(const vector>& coeffs) { for (auto const& p : coeffs) { add_monomial(p.first, p.second); @@ -170,8 +170,7 @@ public: const_iterator operator++() { const_iterator i = *this; m_it++; return i; } const_iterator operator++(int) { m_it++; return *this; } const_iterator(u_map::iterator it) : m_it(it) {} - bool operator==(const const_iterator &other) const { return m_it == other.m_it; } - bool operator!=(const const_iterator &other) const { return !(*this == other); } + bool operator!=(const const_iterator &other) const { return m_it != other.m_it; } }; bool is_normalized() const { diff --git a/src/math/lp/lia_move.h b/src/math/lp/lia_move.h index 12e3d8e35..75ff67dcd 100644 --- a/src/math/lp/lia_move.h +++ b/src/math/lp/lia_move.h @@ -26,7 +26,8 @@ namespace lp { conflict, continue_with_check, undef, - unsat + unsat, + cancelled }; inline std::string lia_move_to_string(lia_move m) { switch (m) { diff --git a/src/math/lp/lp_settings.h b/src/math/lp/lp_settings.h index d1a4be21c..0d47877c7 100644 --- a/src/math/lp/lp_settings.h +++ b/src/math/lp/lp_settings.h @@ -97,42 +97,41 @@ public: }; struct statistics { - unsigned m_make_feasible; - unsigned m_total_iterations; - unsigned m_iters_with_no_cost_growing; - unsigned m_num_factorizations; - unsigned m_num_of_implied_bounds; - unsigned m_need_to_solve_inf; - unsigned m_max_cols; - unsigned m_max_rows; - unsigned m_gcd_calls; - unsigned m_gcd_conflicts; - unsigned m_cube_calls; - unsigned m_cube_success; - unsigned m_patches; - unsigned m_patches_success; - unsigned m_hnf_cutter_calls; - unsigned m_hnf_cuts; - unsigned m_nla_calls; - unsigned m_gomory_cuts; - unsigned m_nla_add_bounds; - unsigned m_nla_propagate_bounds; - unsigned m_nla_propagate_eq; - unsigned m_nla_lemmas; - unsigned m_nra_calls; - unsigned m_nla_bounds_improvements; - unsigned m_horner_calls; - unsigned m_horner_conflicts; - unsigned m_cross_nested_forms; - unsigned m_grobner_calls; - unsigned m_grobner_conflicts; - unsigned m_offset_eqs; - unsigned m_fixed_eqs; - ::statistics m_st; - statistics() { reset(); } + unsigned m_make_feasible = 0; + unsigned m_total_iterations = 0; + unsigned m_iters_with_no_cost_growing = 0; + unsigned m_num_factorizations = 0; + unsigned m_num_of_implied_bounds = 0; + unsigned m_need_to_solve_inf = 0; + unsigned m_max_cols = 0; + unsigned m_max_rows = 0; + unsigned m_gcd_calls = 0; + unsigned m_gcd_conflicts = 0; + unsigned m_cube_calls = 0; + unsigned m_cube_success = 0; + unsigned m_patches = 0; + unsigned m_patches_success = 0; + unsigned m_hnf_cutter_calls = 0; + unsigned m_hnf_cuts = 0; + unsigned m_nla_calls = 0; + unsigned m_gomory_cuts = 0; + unsigned m_nla_add_bounds = 0; + unsigned m_nla_propagate_bounds = 0; + unsigned m_nla_propagate_eq = 0; + unsigned m_nla_lemmas = 0; + unsigned m_nra_calls = 0; + unsigned m_nla_bounds_improvements = 0; + unsigned m_horner_calls = 0; + unsigned m_horner_conflicts = 0; + unsigned m_cross_nested_forms = 0; + unsigned m_grobner_calls = 0; + unsigned m_grobner_conflicts = 0; + unsigned m_offset_eqs = 0; + unsigned m_fixed_eqs = 0; + ::statistics m_st = {}; + void reset() { - memset(this, 0, sizeof(*this)); - m_st.reset(); + *this = statistics{}; } void collect_statistics(::statistics& st) const { st.update("arith-factorizations", m_num_factorizations); diff --git a/src/math/lp/nex.h b/src/math/lp/nex.h index e4087a407..7217374d5 100644 --- a/src/math/lp/nex.h +++ b/src/math/lp/nex.h @@ -92,7 +92,7 @@ public: virtual const rational& coeff() const { return rational::one(); } #ifdef Z3DEBUG - virtual void sort() {}; + virtual void sort() {} #endif bool virtual is_linear() const = 0; }; diff --git a/src/math/lp/nla_core.cpp b/src/math/lp/nla_core.cpp index 449ecad4c..2d7e453ec 100644 --- a/src/math/lp/nla_core.cpp +++ b/src/math/lp/nla_core.cpp @@ -1678,7 +1678,7 @@ bool core::is_nl_var(lpvar j) const { unsigned core::get_var_weight(lpvar j) const { - unsigned k; + unsigned k = 0; switch (lra.get_column_type(j)) { case lp::column_type::fixed: diff --git a/src/math/lp/nla_divisions.cpp b/src/math/lp/nla_divisions.cpp index 6c3bb178c..72b6d73f0 100644 --- a/src/math/lp/nla_divisions.cpp +++ b/src/math/lp/nla_divisions.cpp @@ -19,7 +19,6 @@ Description: namespace nla { void divisions::add_idivision(lpvar q, lpvar x, lpvar y) { - const auto& lra = m_core.lra; if (x == null_lpvar || y == null_lpvar || q == null_lpvar) return; m_idivisions.push_back({q, x, y}); @@ -27,7 +26,6 @@ namespace nla { } void divisions::add_rdivision(lpvar q, lpvar x, lpvar y) { - auto& lra = m_core.lra; if (x == null_lpvar || y == null_lpvar || q == null_lpvar) return; m_rdivisions.push_back({ q, x, y }); diff --git a/src/math/lp/nla_tangent_lemmas.h b/src/math/lp/nla_tangent_lemmas.h index 1895b3fcb..daa45a41a 100644 --- a/src/math/lp/nla_tangent_lemmas.h +++ b/src/math/lp/nla_tangent_lemmas.h @@ -17,7 +17,7 @@ struct point { rational x; rational y; point(const rational& a, const rational& b): x(a), y(b) {} - point() {} + point() = default; inline point& operator*=(rational a) { x *= a; y *= a; diff --git a/src/math/lp/numeric_pair.h b/src/math/lp/numeric_pair.h index 93780f7be..dbebbf998 100644 --- a/src/math/lp/numeric_pair.h +++ b/src/math/lp/numeric_pair.h @@ -116,10 +116,7 @@ template struct numeric_pair { T x; T y; - // empty constructor - numeric_pair() {} - // another constructor - + numeric_pair() = default; numeric_pair(T xp, T yp) : x(xp), y(yp) {} template diff --git a/src/math/lp/permutation_matrix.h b/src/math/lp/permutation_matrix.h index a3fff4f7f..df0897dbe 100644 --- a/src/math/lp/permutation_matrix.h +++ b/src/math/lp/permutation_matrix.h @@ -52,7 +52,7 @@ class permutation_matrix }; public: - permutation_matrix() {} + permutation_matrix() = default; permutation_matrix(unsigned length); permutation_matrix(unsigned length, vector const & values); diff --git a/src/math/lp/stacked_vector.h b/src/math/lp/stacked_vector.h index ecd61eb10..791cddc85 100644 --- a/src/math/lp/stacked_vector.h +++ b/src/math/lp/stacked_vector.h @@ -51,13 +51,21 @@ public: operator const B&() const { return m_vec.m_vector[m_i]; } - + bool operator==(B const& other) const { return m_vec.m_vector[m_i] == other; } bool operator!=(B const& other) const { return m_vec.m_vector[m_i] != other; } + bool operator==(ref const& other) const { + return m_vec.m_vector[m_i] == other.m_vec.m_vector[other.m_i]; + } + bool operator!=(ref const& other) const { + return m_vec.m_vector[m_i] != other.m_vec.m_vector[other.m_i]; + } + + B& operator+=(B const &delta) { // not tracking the change here! return m_vec.m_vector[m_i] += delta; @@ -74,12 +82,16 @@ public: public: ref_const(const stacked_vector &m, unsigned key) :m_vec(m), m_i(key) { lp_assert(key < m.size()); - } - + } operator const B&() const { return m_vec.m_vector[m_i]; } - + bool operator==(ref_const const& other) const { + return m_vec.m_vector[m_i] == other.m_vec.m_vector[other.m_i]; + } + bool operator!=(ref_const const& other) const { + return m_vec.m_vector[m_i] != other.m_vec.m_vector[other.m_i]; + } }; private: @@ -98,9 +110,6 @@ private: } } public: - - stacked_vector() { } - ref operator[] (unsigned a) { return ref(*this, a); } diff --git a/src/math/lp/static_matrix.h b/src/math/lp/static_matrix.h index 9d6bb8599..5bbd000ca 100644 --- a/src/math/lp/static_matrix.h +++ b/src/math/lp/static_matrix.h @@ -79,7 +79,7 @@ public: ref(static_matrix & m, unsigned row, unsigned col):m_matrix(m), m_row(row), m_col(col) {} ref & operator=(T const & v) { m_matrix.set( m_row, m_col, v); return *this; } - ref operator=(ref & v) { m_matrix.set(m_row, m_col, v.m_matrix.get(v.m_row, v.m_col)); return *this; } + ref operator=(ref & v) { m_matrix.set(m_row, m_col, v.m_matrix.get_elem(v.m_row, v.m_col)); return *this; } operator T () const { return m_matrix.get_elem(m_row, m_col); } }; @@ -105,7 +105,7 @@ public: void init_row_columns(unsigned m, unsigned n); // constructor with no parameters - static_matrix() {} + static_matrix() = default; // constructor static_matrix(unsigned m, unsigned n): m_vector_of_row_offsets(n, -1) { diff --git a/src/math/lp/static_matrix_def.h b/src/math/lp/static_matrix_def.h index 0370ee899..c3b2fc168 100644 --- a/src/math/lp/static_matrix_def.h +++ b/src/math/lp/static_matrix_def.h @@ -92,7 +92,7 @@ static_matrix::static_matrix(static_matrix const &A, unsigned * /* basis * init_row_columns(m, m); for (; m-- > 0; ) for (auto & col : A.m_columns[m]) - set(col.var(), m, A.get_value_of_column_cell(col)); + set(col.var(), m, A.get_column_cell(col)); } template void static_matrix::clear() { diff --git a/src/math/lp/var_eqs.h b/src/math/lp/var_eqs.h index a639a9a5e..b2b3f24cf 100644 --- a/src/math/lp/var_eqs.h +++ b/src/math/lp/var_eqs.h @@ -81,7 +81,7 @@ class var_eqs { mutable stats m_stats; public: - var_eqs(): m_merge_handler(nullptr), m_uf(*this), m_stack() {} + var_eqs(): m_merge_handler(nullptr), m_uf(*this) {} /** \brief push a scope */ void push() { @@ -302,7 +302,6 @@ public: return signed_var(m_idx); } iterator& operator++() { m_idx = m_ve.m_uf.next(m_idx); m_touched = true; return *this; } - bool operator==(iterator const& other) const { return m_idx == other.m_idx && m_touched == other.m_touched; } bool operator!=(iterator const& other) const { return m_idx != other.m_idx || m_touched != other.m_touched; } }; diff --git a/src/math/lp/var_register.h b/src/math/lp/var_register.h index bd7e6efe8..84ac8236d 100644 --- a/src/math/lp/var_register.h +++ b/src/math/lp/var_register.h @@ -27,7 +27,7 @@ class ext_var_info { bool m_is_integer; std::string m_name; public: - ext_var_info() {} + ext_var_info() = default; ext_var_info(unsigned j): ext_var_info(j, true) {} ext_var_info(unsigned j , bool is_int) : m_external_j(j), m_is_integer(is_int) {} ext_var_info(unsigned j , bool is_int, std::string name) : m_external_j(j), m_is_integer(is_int), m_name(name) {} diff --git a/src/math/polynomial/algebraic_numbers.cpp b/src/math/polynomial/algebraic_numbers.cpp index b546df706..6cdd735a1 100644 --- a/src/math/polynomial/algebraic_numbers.cpp +++ b/src/math/polynomial/algebraic_numbers.cpp @@ -121,9 +121,6 @@ namespace algebraic_numbers { m_y = pm().mk_var(); } - ~imp() { - } - bool acell_inv(algebraic_cell const& c) { auto s = upm().eval_sign_at(c.m_p_sz, c.m_p, lower(&c)); return s == sign_zero || c.m_sign_lower == (s == sign_neg); diff --git a/src/math/polynomial/polynomial.cpp b/src/math/polynomial/polynomial.cpp index 74c5e05d7..76f717da0 100644 --- a/src/math/polynomial/polynomial.cpp +++ b/src/math/polynomial/polynomial.cpp @@ -91,7 +91,7 @@ namespace polynomial { */ class power : public std::pair { public: - power():std::pair() {} + power() = default; power(var v, unsigned d):std::pair(v, d) {} var get_var() const { return first; } unsigned degree() const { return second; } @@ -1895,7 +1895,7 @@ namespace polynomial { Invoke add(...), addmul(...) several times, and then invoke mk() to obtain the final polynomial. */ class som_buffer { - imp * m_owner; + imp * m_owner = nullptr; monomial2pos m_m2pos; numeral_vector m_tmp_as; monomial_vector m_tmp_ms; @@ -1939,8 +1939,6 @@ namespace polynomial { } public: - som_buffer():m_owner(nullptr) {} - void reset() { if (empty()) return; @@ -2236,12 +2234,10 @@ namespace polynomial { In this buffer, each monomial can be added at most once. */ class cheap_som_buffer { - imp * m_owner; + imp * m_owner = nullptr; numeral_vector m_tmp_as; monomial_vector m_tmp_ms; public: - cheap_som_buffer():m_owner(nullptr) {} - void set_owner(imp * o) { m_owner = o; } bool empty() const { return m_tmp_ms.empty(); } @@ -3072,11 +3068,9 @@ namespace polynomial { } class newton_interpolator_vector { - imp * m_imp; + imp * m_imp = nullptr; ptr_vector m_data; public: - newton_interpolator_vector():m_imp(nullptr) {} - ~newton_interpolator_vector() { flush(); } diff --git a/src/math/polynomial/upolynomial_factorization_int.h b/src/math/polynomial/upolynomial_factorization_int.h index a65e5ee62..f47610b65 100644 --- a/src/math/polynomial/upolynomial_factorization_int.h +++ b/src/math/polynomial/upolynomial_factorization_int.h @@ -64,7 +64,7 @@ namespace upolynomial { public: - factorization_degree_set() { } + factorization_degree_set() = default; factorization_degree_set(zp_factors const & factors) { diff --git a/src/math/realclosure/mpz_matrix.cpp b/src/math/realclosure/mpz_matrix.cpp index 3bbd387c6..701b3b26d 100644 --- a/src/math/realclosure/mpz_matrix.cpp +++ b/src/math/realclosure/mpz_matrix.cpp @@ -36,9 +36,6 @@ mpz_matrix_manager::mpz_matrix_manager(unsynch_mpz_manager & nm, small_object_al m_allocator(a) { } -mpz_matrix_manager::~mpz_matrix_manager() { -} - void mpz_matrix_manager::mk(unsigned m, unsigned n, mpz_matrix & A) { SASSERT(m > 0 && n > 0); del(A); diff --git a/src/math/realclosure/mpz_matrix.h b/src/math/realclosure/mpz_matrix.h index 91fe22681..9eb051ed2 100644 --- a/src/math/realclosure/mpz_matrix.h +++ b/src/math/realclosure/mpz_matrix.h @@ -63,7 +63,6 @@ class mpz_matrix_manager { bool solve_core(mpz_matrix const & A, mpz * b, bool int_solver); public: mpz_matrix_manager(unsynch_mpz_manager & nm, small_object_allocator & a); - ~mpz_matrix_manager(); unsynch_mpz_manager & nm() const { return m_nm; } void mk(unsigned m, unsigned n, mpz_matrix & A); void del(mpz_matrix & r); diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index ecea560a5..561d6a6d7 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -410,8 +410,6 @@ namespace realclosure { sbuffer m_szs; // size of each polynomial in the sequence public: scoped_polynomial_seq(imp & m):m_seq_coeffs(m) {} - ~scoped_polynomial_seq() { - } /** \brief Add a new polynomial to the sequence. diff --git a/src/math/simplex/bit_matrix.h b/src/math/simplex/bit_matrix.h index c827690ec..13ca2b7ba 100644 --- a/src/math/simplex/bit_matrix.h +++ b/src/math/simplex/bit_matrix.h @@ -71,7 +71,6 @@ public: unsigned const* operator->() const { return &m_column; } col_iterator& operator++() { next(); return *this; } col_iterator operator++(int) { auto tmp = *this; next(); return tmp; } - bool operator==(col_iterator const& other) const { return m_column == other.m_column; } bool operator!=(col_iterator const& other) const { return m_column != other.m_column; } }; @@ -88,7 +87,6 @@ public: row* operator->() { return &m_row; } row_iterator& operator++() { next(); return *this; } row_iterator operator++(int) { auto tmp = *this; next(); return tmp; } - bool operator==(row_iterator const& other) const { return m_index == other.m_index; } bool operator!=(row_iterator const& other) const { return m_index != other.m_index; } }; diff --git a/src/math/simplex/model_based_opt.h b/src/math/simplex/model_based_opt.h index 35516283d..891df598b 100644 --- a/src/math/simplex/model_based_opt.h +++ b/src/math/simplex/model_based_opt.h @@ -43,7 +43,7 @@ namespace opt { struct var { unsigned m_id { 0 }; rational m_coeff; - var() {} + var() = default; var(unsigned id, rational const& c): m_id(id), m_coeff(c) {} struct compare { bool operator()(var x, var y) { @@ -76,11 +76,11 @@ namespace opt { // A definition is a linear term of the form (vars + coeff) / div struct def { - def(): m_div(1) {} + def() = default; def(row const& r, unsigned x); vector m_vars; rational m_coeff; - rational m_div; + rational m_div{1}; def operator+(def const& other) const; def operator/(unsigned n) const { return *this / rational(n); } def operator/(rational const& n) const; diff --git a/src/math/simplex/sparse_matrix.h b/src/math/simplex/sparse_matrix.h index 9333e9ddb..0dfd1a2ad 100644 --- a/src/math/simplex/sparse_matrix.h +++ b/src/math/simplex/sparse_matrix.h @@ -198,7 +198,6 @@ namespace simplex { row_entry * operator->() const { return &(operator*()); } row_iterator & operator++() { ++m_curr; move_to_used(); return *this; } row_iterator operator++(int) { row_iterator tmp = *this; ++*this; return tmp; } - bool operator==(row_iterator const & it) const { return m_curr == it.m_curr; } bool operator!=(row_iterator const & it) const { return m_curr != it.m_curr; } }; @@ -308,7 +307,6 @@ namespace simplex { row operator*() { return row(m_curr); } all_row_iterator & operator++() { m_curr++; move_to_next(); return *this; } all_row_iterator operator++(int) { all_row_iterator tmp = *this; ++*this; return tmp; } - bool operator==(all_row_iterator const& it) const { return m_curr == it.m_curr; } bool operator!=(all_row_iterator const& it) const { return m_curr != it.m_curr; } }; diff --git a/src/model/model_evaluator.cpp b/src/model/model_evaluator.cpp index 2446609c6..6db52a98e 100644 --- a/src/model/model_evaluator.cpp +++ b/src/model/model_evaluator.cpp @@ -457,7 +457,7 @@ struct evaluator_cfg : public default_rewriter_cfg { if (interp) { var_subst vs(m, false); result = vs(fi->get_interp(), num, args); - result = m.mk_ite(m.mk_eq(m_au.mk_real(rational(0)), args[1]), result, m.mk_app(f, num, args)); + result = m.mk_ite(m.mk_eq(m_au.mk_numeral(rational(0), args[1]->get_sort()), args[1]), result, m.mk_app(f, num, args)); return BR_DONE; } } diff --git a/src/model/numeral_factory.cpp b/src/model/numeral_factory.cpp index ba19ec941..6f7aeeb2c 100644 --- a/src/model/numeral_factory.cpp +++ b/src/model/numeral_factory.cpp @@ -28,9 +28,6 @@ arith_factory::arith_factory(ast_manager & m): m_util(m) { } -arith_factory::~arith_factory() { -} - app * arith_factory::mk_num_value(rational const & val, bool is_int) { return numeral_factory::mk_value(val, is_int ? m_util.mk_int() : m_util.mk_real()); } @@ -40,9 +37,6 @@ bv_factory::bv_factory(ast_manager & m): m_util(m) { } -bv_factory::~bv_factory() { -} - app * bv_factory::mk_value_core(rational const & val, sort * s) { return m_util.mk_numeral(val, s); } diff --git a/src/model/numeral_factory.h b/src/model/numeral_factory.h index 174ea8757..ca917d927 100644 --- a/src/model/numeral_factory.h +++ b/src/model/numeral_factory.h @@ -34,7 +34,6 @@ class arith_factory : public numeral_factory { public: arith_factory(ast_manager & m); - ~arith_factory() override; app * mk_num_value(rational const & val, bool is_int); }; @@ -46,7 +45,6 @@ class bv_factory : public numeral_factory { public: bv_factory(ast_manager & m); - ~bv_factory() override; app * mk_num_value(rational const & val, unsigned bv_size); }; diff --git a/src/model/value_factory.cpp b/src/model/value_factory.cpp index 30fa82caf..c79919199 100644 --- a/src/model/value_factory.cpp +++ b/src/model/value_factory.cpp @@ -25,9 +25,6 @@ value_factory::value_factory(ast_manager & m, family_id fid): m_fid(fid) { } -value_factory::~value_factory() { -} - basic_factory::basic_factory(ast_manager & m, unsigned seed): value_factory(m, m.get_basic_family_id()), m_rand(seed) { } diff --git a/src/model/value_factory.h b/src/model/value_factory.h index 20c383efe..85515495b 100644 --- a/src/model/value_factory.h +++ b/src/model/value_factory.h @@ -31,7 +31,7 @@ protected: public: value_factory(ast_manager & m, family_id fid); - virtual ~value_factory(); + virtual ~value_factory() = default; /** \brief Return some value of the given sort. The result is always different from zero. diff --git a/src/muz/base/bind_variables.cpp b/src/muz/base/bind_variables.cpp index 5ac41e0bf..d96a49f67 100644 --- a/src/muz/base/bind_variables.cpp +++ b/src/muz/base/bind_variables.cpp @@ -25,9 +25,6 @@ bind_variables::bind_variables(ast_manager & m): m_vars(m), m_pinned(m) {} - -bind_variables::~bind_variables() { -} expr_ref bind_variables::operator()(expr* fml, bool is_forall) { if (m_vars.empty()) { diff --git a/src/muz/base/bind_variables.h b/src/muz/base/bind_variables.h index e231b7039..4c183b507 100644 --- a/src/muz/base/bind_variables.h +++ b/src/muz/base/bind_variables.h @@ -40,7 +40,6 @@ class bind_variables { expr_ref abstract(expr* fml, cache_t& cache, unsigned scope); public: bind_variables(ast_manager & m); - ~bind_variables(); expr_ref operator()(expr* fml, bool is_forall); diff --git a/src/muz/base/dl_context.cpp b/src/muz/base/dl_context.cpp index 230a452df..b1e74c1ef 100644 --- a/src/muz/base/dl_context.cpp +++ b/src/muz/base/dl_context.cpp @@ -313,7 +313,7 @@ namespace datalog { void context::register_finite_sort(sort * s, sort_kind k) { m_pinned.push_back(s); SASSERT(!m_sorts.contains(s)); - sort_domain * dom; + sort_domain * dom = nullptr; switch (k) { case SK_SYMBOL: dom = alloc(symbol_sort_domain, *this, s); diff --git a/src/muz/base/dl_util.cpp b/src/muz/base/dl_util.cpp index 03a8f1c99..7b01c2b3f 100644 --- a/src/muz/base/dl_util.cpp +++ b/src/muz/base/dl_util.cpp @@ -393,8 +393,6 @@ namespace datalog { class skip_model_converter : public model_converter { public: - skip_model_converter() {} - model_converter * translate(ast_translation & translator) override { return alloc(skip_model_converter); } diff --git a/src/muz/base/dl_util.h b/src/muz/base/dl_util.h index 401d8e816..ac1bed51e 100644 --- a/src/muz/base/dl_util.h +++ b/src/muz/base/dl_util.h @@ -347,7 +347,6 @@ namespace datalog { class rule_counter : public var_counter { public: - rule_counter(){} void count_rule_vars(const rule * r, int coef = 1); unsigned get_max_rule_var(const rule& r); }; diff --git a/src/muz/base/rule_properties.cpp b/src/muz/base/rule_properties.cpp index 239fa73b6..abd79c515 100644 --- a/src/muz/base/rule_properties.cpp +++ b/src/muz/base/rule_properties.cpp @@ -31,8 +31,6 @@ rule_properties::rule_properties(ast_manager & m, rule_manager& rm, context& ctx m_dt(m), m_dl(m), m_a(m), m_bv(m), m_ar(m), m_rec(m), m_generate_proof(false), m_collected(false), m_is_monotone(true) {} -rule_properties::~rule_properties() {} - void rule_properties::collect(rule_set const& rules) { reset(); m_collected = true; diff --git a/src/muz/base/rule_properties.h b/src/muz/base/rule_properties.h index a7ef9a0de..3159c28a6 100644 --- a/src/muz/base/rule_properties.h +++ b/src/muz/base/rule_properties.h @@ -58,7 +58,6 @@ namespace datalog { bool check_accessor(app* n); public: rule_properties(ast_manager & m, rule_manager& rm, context& ctx, i_expr_pred& is_predicate); - ~rule_properties(); void set_generate_proof(bool generate_proof) { m_generate_proof = generate_proof; } void collect(rule_set const& r); void check_quantifier_free(); diff --git a/src/muz/bmc/dl_bmc_engine.cpp b/src/muz/bmc/dl_bmc_engine.cpp index 913e35f36..e83569e0e 100644 --- a/src/muz/bmc/dl_bmc_engine.cpp +++ b/src/muz/bmc/dl_bmc_engine.cpp @@ -1443,8 +1443,6 @@ namespace datalog { m_rule_trace(ctx.get_rule_manager()) { } - bmc::~bmc() {} - lbool bmc::query(expr* query) { m_solver = nullptr; m_answer = nullptr; diff --git a/src/muz/bmc/dl_bmc_engine.h b/src/muz/bmc/dl_bmc_engine.h index 90c4ab862..05d5707a6 100644 --- a/src/muz/bmc/dl_bmc_engine.h +++ b/src/muz/bmc/dl_bmc_engine.h @@ -51,8 +51,6 @@ namespace datalog { public: bmc(context& ctx); - ~bmc() override; - lbool query(expr* query) override; void display_certificate(std::ostream& out) const override; diff --git a/src/muz/clp/clp_context.cpp b/src/muz/clp/clp_context.cpp index 89ae71e36..9d4baa4ae 100644 --- a/src/muz/clp/clp_context.cpp +++ b/src/muz/clp/clp_context.cpp @@ -59,8 +59,6 @@ namespace datalog { m_fparams.m_mbqi = false; } - ~imp() {} - lbool query(expr* query) { m_ctx.ensure_opened(); m_solver.reset(); diff --git a/src/muz/ddnf/ddnf.cpp b/src/muz/ddnf/ddnf.cpp index cf759c76e..eaf352475 100644 --- a/src/muz/ddnf/ddnf.cpp +++ b/src/muz/ddnf/ddnf.cpp @@ -78,8 +78,6 @@ namespace datalog { m_descendants(DEFAULT_HASHTABLE_INITIAL_CAPACITY, m_hash, m_eq) { } - ~ddnf_node() {} - unsigned inc_ref() { return ++m_refs; } @@ -429,8 +427,6 @@ namespace datalog { class ddnfs { u_map m_mgrs; public: - ddnfs() {} - ~ddnfs() { u_map::iterator it = m_mgrs.begin(), end = m_mgrs.end(); for (; it != end; ++it) { @@ -503,8 +499,6 @@ namespace datalog { m_inner_ctx.updt_params(params); } - ~imp() {} - lbool query(expr* query) { m_ctx.ensure_opened(); rule_set& old_rules = m_ctx.get_rules(); @@ -684,14 +678,9 @@ namespace datalog { } bool compile_rules1(rule_set const& rules, rule_set& new_rules) { - datalog::rule_set::iterator it = rules.begin(); - datalog::rule_set::iterator end = rules.end(); - unsigned idx = 0; - for (; it != end; ++idx, ++it) { - if (!compile_rule1(**it, rules, new_rules)) { + for (auto const & r : rules) + if (!compile_rule1(*r, rules, new_rules)) return false; - } - } return true; } diff --git a/src/muz/fp/datalog_parser.cpp b/src/muz/fp/datalog_parser.cpp index d748dca63..c6df500d8 100644 --- a/src/muz/fp/datalog_parser.cpp +++ b/src/muz/fp/datalog_parser.cpp @@ -228,20 +228,20 @@ public: class dlexer { - std::istream* m_input; - char_reader* m_reader; - char m_prev_char; - char m_curr_char; - int m_line; - int m_pos; - int m_tok_pos; + std::istream* m_input = nullptr; + char_reader* m_reader = nullptr; + int m_prev_char = 0; + int m_curr_char = 0; + int m_line = 1; + int m_pos = 0; + int m_tok_pos = 0; string_buffer<> m_buffer; reserved_symbols m_reserved_symbols; public: //when parsing domains, we want '.' character to be allowed in IDs, but elsewhere //we don't (because of the "y." in rules like "P(x,y):-x=y.") - bool m_parsing_domains; + bool m_parsing_domains = false; bool eos() const { return m_curr_char == EOF; @@ -267,17 +267,6 @@ public: next(); } - dlexer(): - m_input(nullptr), - m_reader(nullptr), - m_prev_char(0), - m_curr_char(0), - m_line(1), - m_pos(0), - m_tok_pos(0), - m_parsing_domains(false) { - } - void set_stream(std::istream* s, char_reader* r) { m_input = s; m_reader = r; @@ -902,7 +891,6 @@ protected: unsigned arg_idx = 0; tok = m_lexer->next_token(); while (tok != TK_EOS && tok != TK_ERROR) { - symbol alias; sort* s = nullptr; if(!f) { @@ -939,7 +927,6 @@ protected: } s = f->get_domain(arg_idx); - symbol var_symbol; tok = parse_arg(tok, s, args); } @@ -1067,7 +1054,7 @@ protected: bool read_line(std::istream& strm, std::string& line) { line.clear(); - char ch = strm.get(); + int ch = strm.get(); while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') { ch = strm.get(); } diff --git a/src/muz/fp/dl_cmds.cpp b/src/muz/fp/dl_cmds.cpp index f40400167..508b79ace 100644 --- a/src/muz/fp/dl_cmds.cpp +++ b/src/muz/fp/dl_cmds.cpp @@ -56,8 +56,7 @@ struct dl_context { m_cmd(ctx), m_collected_cmds(collected_cmds), m_ref_count(0), - m_decl_plugin(nullptr), - m_trail() {} + m_decl_plugin(nullptr) {} void inc_ref() { ++m_ref_count; diff --git a/src/muz/rel/check_relation.cpp b/src/muz/rel/check_relation.cpp index 24b109f35..454f6d8bc 100644 --- a/src/muz/rel/check_relation.cpp +++ b/src/muz/rel/check_relation.cpp @@ -150,8 +150,6 @@ namespace datalog { m(rm.get_context().get_manager()), m_base(nullptr) { } - check_relation_plugin::~check_relation_plugin() { - } check_relation& check_relation_plugin::get(relation_base& r) { return dynamic_cast(r); } diff --git a/src/muz/rel/check_relation.h b/src/muz/rel/check_relation.h index b0b4a8acc..773b45813 100644 --- a/src/muz/rel/check_relation.h +++ b/src/muz/rel/check_relation.h @@ -89,7 +89,6 @@ namespace datalog { unsigned_vector const& cols1, unsigned_vector const& cols2); public: check_relation_plugin(relation_manager& rm); - ~check_relation_plugin() override; void set_plugin(relation_plugin* p) { m_base = p; } bool can_handle_signature(const relation_signature & s) override; diff --git a/src/muz/rel/dl_base.h b/src/muz/rel/dl_base.h index 158df4906..d6394ddb1 100644 --- a/src/muz/rel/dl_base.h +++ b/src/muz/rel/dl_base.h @@ -93,7 +93,7 @@ namespace datalog { */ class signature_base : public signature_base_base { public: - bool operator==(const signature & o) const { + bool operator==(const signature_base & o) const { unsigned n=signature_base_base::size(); if (n!=o.size()) { return false; @@ -1113,7 +1113,7 @@ namespace datalog { virtual row_interface & operator*() = 0; virtual void operator++() = 0; - virtual bool operator==(const iterator_core & it) { + virtual bool operator==(const iterator_core & it) const { //we worry about the equality operator only because of checking //the equality with the end() iterator return is_finished() && it.is_finished(); @@ -1142,7 +1142,7 @@ namespace datalog { virtual table_element operator*() = 0; virtual void operator++() = 0; - virtual bool operator==(const row_iterator_core & it) { + virtual bool operator==(const row_iterator_core & it) const { //we worry about the equality operator only because of checking //the equality with the end() iterator return is_finished() && it.is_finished(); @@ -1169,10 +1169,8 @@ namespace datalog { { return &(*(*m_core)); } iterator & operator++() { ++(*m_core); return *this; } - bool operator==(const iterator & it) - { return (*m_core)==(*it.m_core); } - bool operator!=(const iterator & it) - { return !operator==(it); } + bool operator==(const iterator & it) const { return (*m_core)==(*it.m_core); } + bool operator!=(const iterator & it) const { return !operator==(it); } }; class row_iterator { @@ -1187,10 +1185,8 @@ namespace datalog { { return *(*m_core); } row_iterator & operator++() { ++(*m_core); return *this; } - bool operator==(const row_iterator & it) - { return (*m_core)==(*it.m_core); } - bool operator!=(const row_iterator & it) - { return !operator==(it); } + bool operator==(const row_iterator & it) const { return (*m_core)==(*it.m_core); } + bool operator!=(const row_iterator & it) const { return !operator==(it); } }; virtual iterator begin() const = 0; diff --git a/src/muz/rel/dl_external_relation.cpp b/src/muz/rel/dl_external_relation.cpp index a47b0719f..a2e42f640 100644 --- a/src/muz/rel/dl_external_relation.cpp +++ b/src/muz/rel/dl_external_relation.cpp @@ -34,9 +34,6 @@ namespace datalog { { } - external_relation::~external_relation() { - } - void external_relation::mk_accessor(decl_kind k, func_decl_ref& fn, const relation_fact& f, bool destructive, expr_ref& res) const { ast_manager& m = m_rel.get_manager(); family_id fid = get_plugin().get_family_id(); diff --git a/src/muz/rel/dl_external_relation.h b/src/muz/rel/dl_external_relation.h index 17e9a2364..c8887eeed 100644 --- a/src/muz/rel/dl_external_relation.h +++ b/src/muz/rel/dl_external_relation.h @@ -122,7 +122,6 @@ namespace datalog { void mk_accessor(decl_kind k, func_decl_ref& fn, const relation_fact& f, bool destructive, expr_ref& res) const; external_relation(external_relation_plugin & p, const relation_signature & s, expr* r); - ~external_relation() override; public: external_relation_plugin & get_plugin() const; diff --git a/src/muz/rel/dl_mk_explanations.cpp b/src/muz/rel/dl_mk_explanations.cpp index a4b704597..2d22e34a9 100644 --- a/src/muz/rel/dl_mk_explanations.cpp +++ b/src/muz/rel/dl_mk_explanations.cpp @@ -631,9 +631,6 @@ namespace datalog { ); } - mk_explanations::~mk_explanations() { - } - func_decl * mk_explanations::get_union_decl(context & ctx) { ast_manager & m = ctx.get_manager(); sort_ref s(ctx.get_decl_util().mk_rule_sort(), m); diff --git a/src/muz/rel/dl_mk_explanations.h b/src/muz/rel/dl_mk_explanations.h index 5491918de..33d5cc8ee 100644 --- a/src/muz/rel/dl_mk_explanations.h +++ b/src/muz/rel/dl_mk_explanations.h @@ -65,8 +65,6 @@ namespace datalog { */ mk_explanations(context & ctx); - ~mk_explanations() override; - /** \brief Return explanation predicate that corresponds to \c orig_decl. */ diff --git a/src/muz/rel/dl_mk_simple_joins.cpp b/src/muz/rel/dl_mk_simple_joins.cpp index 37fd3ef36..f60760fab 100644 --- a/src/muz/rel/dl_mk_simple_joins.cpp +++ b/src/muz/rel/dl_mk_simple_joins.cpp @@ -54,8 +54,6 @@ namespace datalog { var_idx_set m_all_nonlocal_vars; rule_vector m_rules; - pair_info() {} - pair_info & operator=(const pair_info &) = delete; bool can_be_joined() const { return m_consumers > 0; diff --git a/src/muz/rel/dl_product_relation.cpp b/src/muz/rel/dl_product_relation.cpp index 52c168f12..701bad3cc 100644 --- a/src/muz/rel/dl_product_relation.cpp +++ b/src/muz/rel/dl_product_relation.cpp @@ -1030,6 +1030,7 @@ namespace datalog { } new_rels.push_back(irel); } + (void)old_remain; SASSERT(old_remain==0); //the new specification must be a superset of the old one m_relations = new_rels; diff --git a/src/muz/rel/dl_relation_manager.cpp b/src/muz/rel/dl_relation_manager.cpp index 8de25c8f3..5e96dc487 100644 --- a/src/muz/rel/dl_relation_manager.cpp +++ b/src/muz/rel/dl_relation_manager.cpp @@ -1043,7 +1043,6 @@ namespace datalog { class relation_manager::null_signature_table_project_fn : public table_transformer_fn { const table_signature m_empty_sig; public: - null_signature_table_project_fn() : m_empty_sig() {} table_base * operator()(const table_base & t) override { relation_manager & m = t.get_plugin().get_manager(); table_base * res = m.mk_empty_table(m_empty_sig); diff --git a/src/muz/rel/dl_sieve_relation.h b/src/muz/rel/dl_sieve_relation.h index 72c246e99..0166bec98 100644 --- a/src/muz/rel/dl_sieve_relation.h +++ b/src/muz/rel/dl_sieve_relation.h @@ -36,7 +36,7 @@ namespace datalog { /** Create uninitialized rel_spec. */ - rel_spec() {} + rel_spec() = default; /** \c inner_kind==null_family_id means we will not specify a relation kind when requesting the relation object from the relation_manager. diff --git a/src/muz/rel/dl_table.cpp b/src/muz/rel/dl_table.cpp index e0ea17739..fec4e5c98 100644 --- a/src/muz/rel/dl_table.cpp +++ b/src/muz/rel/dl_table.cpp @@ -122,7 +122,7 @@ namespace datalog { m_end(t.m_data.end()), m_row_obj(*this) {} bool is_finished() const override { - return m_inner==m_end; + return !(m_inner != m_end); } row_interface & operator*() override { diff --git a/src/muz/rel/karr_relation.cpp b/src/muz/rel/karr_relation.cpp index d01056960..7a2ba5179 100644 --- a/src/muz/rel/karr_relation.cpp +++ b/src/muz/rel/karr_relation.cpp @@ -674,8 +674,6 @@ namespace datalog { class karr_relation_plugin::union_fn : public relation_union_fn { public: - union_fn() {} - void operator()(relation_base & _r, const relation_base & _src, relation_base * _delta) override { karr_relation& r = get(_r); diff --git a/src/muz/rel/udoc_relation.cpp b/src/muz/rel/udoc_relation.cpp index 2b28a6c82..8240f7f9e 100644 --- a/src/muz/rel/udoc_relation.cpp +++ b/src/muz/rel/udoc_relation.cpp @@ -491,8 +491,6 @@ namespace datalog { } class udoc_plugin::union_fn : public relation_union_fn { public: - union_fn() {} - void operator()(relation_base & _r, const relation_base & _src, relation_base * _delta) override { TRACE("doc", _r.display(tout << "dst:\n"); _src.display(tout << "src:\n");); udoc_relation& r = get(_r); @@ -1040,8 +1038,6 @@ namespace datalog { class udoc_plugin::join_project_and_fn : public relation_join_fn { public: - join_project_and_fn() {} - relation_base* operator()(relation_base const& t1, relation_base const& t2) override { udoc_relation *result = get(t1.clone()); result->get_udoc().intersect(result->get_dm(), get(t2).get_udoc()); diff --git a/src/muz/spacer/spacer_antiunify.cpp b/src/muz/spacer/spacer_antiunify.cpp index 11fe80f60..1c65b4e29 100644 --- a/src/muz/spacer/spacer_antiunify.cpp +++ b/src/muz/spacer/spacer_antiunify.cpp @@ -158,7 +158,7 @@ void anti_unifier::operator()(expr *e1, expr *e2, expr_ref &res, m_todo.pop_back(); } - expr *r; + expr *r = nullptr; VERIFY(m_cache.find(e1, e2, r)); res = r; diff --git a/src/muz/spacer/spacer_arith_kernel.cpp b/src/muz/spacer/spacer_arith_kernel.cpp index fdcb6b0d6..25aff0273 100644 --- a/src/muz/spacer/spacer_arith_kernel.cpp +++ b/src/muz/spacer/spacer_arith_kernel.cpp @@ -45,8 +45,6 @@ bool spacer_arith_kernel::compute_kernel() { namespace { class simplex_arith_kernel_plugin : public spacer_arith_kernel::plugin { public: - simplex_arith_kernel_plugin() {} - bool compute_kernel(const spacer_matrix &in, spacer_matrix &out, vector &basics) override { using qmatrix = simplex::sparse_matrix; diff --git a/src/muz/spacer/spacer_concretize.cpp b/src/muz/spacer/spacer_concretize.cpp index 809e9a971..9700af149 100644 --- a/src/muz/spacer/spacer_concretize.cpp +++ b/src/muz/spacer/spacer_concretize.cpp @@ -27,7 +27,7 @@ struct proc { void operator()(var *n) const {} void operator()(quantifier *q) const {} void operator()(app const *n) const { - expr *e1, *e2; + expr *e1 = nullptr, *e2 = nullptr; if (m_arith.is_mul(n, e1, e2)) { if (is_var(e1) && !is_var(e2)) m_marks.mark(e2); @@ -71,7 +71,7 @@ bool pob_concretizer::apply(const expr_ref_vector &cube, expr_ref_vector &out) { } bool pob_concretizer::is_split_var(expr *e, expr *&var, bool &pos) { - expr *e1, *e2; + expr *e1 = nullptr, *e2 = nullptr; rational n; if (m_var_marks.is_marked(e)) { @@ -89,7 +89,7 @@ bool pob_concretizer::is_split_var(expr *e, expr *&var, bool &pos) { } void pob_concretizer::split_lit_le_lt(expr *_lit, expr_ref_vector &out) { - expr *e1, *e2; + expr *e1 = nullptr, *e2 = nullptr; expr *lit = _lit; m.is_not(_lit, lit); @@ -133,7 +133,7 @@ void pob_concretizer::split_lit_le_lt(expr *_lit, expr_ref_vector &out) { } void pob_concretizer::split_lit_ge_gt(expr *_lit, expr_ref_vector &out) { - expr *e1, *e2; + expr *e1 = nullptr, *e2 = nullptr; expr *lit = _lit; m.is_not(_lit, lit); @@ -182,7 +182,7 @@ bool pob_concretizer::apply_lit(expr *_lit, expr_ref_vector &out) { // split literals of the form a1*x1 + ... + an*xn ~ c, where c is a // constant, ~ is <, <=, >, or >=, and the top level operator of LHS is + - expr *e1, *e2; + expr *e1 = nullptr, *e2 = nullptr; if ((m_arith.is_lt(lit, e1, e2) || m_arith.is_le(lit, e1, e2)) && m_arith.is_add(e1)) { SASSERT(m_arith.is_numeral(e2)); diff --git a/src/muz/spacer/spacer_context.h b/src/muz/spacer/spacer_context.h index 1283a525f..269142146 100644 --- a/src/muz/spacer/spacer_context.h +++ b/src/muz/spacer/spacer_context.h @@ -404,7 +404,7 @@ class pred_transformer { } pt_rule &mk_rule(const pt_rule &v); void set_tag(expr *tag, pt_rule &v) { - pt_rule *p; + pt_rule *p = nullptr; VERIFY(find_by_rule(v.rule(), p)); p->set_tag(tag); m_tags.insert(tag, p); @@ -569,7 +569,7 @@ class pred_transformer { expr *transition() const { return m_transition; } expr *init() const { return m_init; } expr *rule2tag(datalog::rule const *r) { - pt_rule *p; + pt_rule *p = nullptr; return m_pt_rules.find_by_rule(*r, p) ? p->tag() : nullptr; } unsigned get_num_levels() const { return m_frames.size(); } @@ -600,7 +600,7 @@ class pred_transformer { bool_vector &reach_pred_used, unsigned &num_reuse_reach); expr *get_transition(datalog::rule const &r) { - pt_rule *p; + pt_rule *p = nullptr; return m_pt_rules.find_by_rule(r, p) ? p->trans() : nullptr; } ptr_vector &get_aux_vars(datalog::rule const &r) { diff --git a/src/muz/spacer/spacer_expand_bnd_generalizer.h b/src/muz/spacer/spacer_expand_bnd_generalizer.h index 91ba3b417..6d4e68d17 100644 --- a/src/muz/spacer/spacer_expand_bnd_generalizer.h +++ b/src/muz/spacer/spacer_expand_bnd_generalizer.h @@ -43,7 +43,6 @@ class lemma_expand_bnd_generalizer : public lemma_generalizer { public: lemma_expand_bnd_generalizer(context &ctx); - ~lemma_expand_bnd_generalizer() override {} void operator()(lemma_ref &lemma) override; diff --git a/src/muz/spacer/spacer_global_generalizer.cpp b/src/muz/spacer/spacer_global_generalizer.cpp index 55bc4eec7..e4b16cfbb 100644 --- a/src/muz/spacer/spacer_global_generalizer.cpp +++ b/src/muz/spacer/spacer_global_generalizer.cpp @@ -223,7 +223,7 @@ void lemma_global_generalizer::subsumer::setup_cvx_closure( cc.reset(n_vars); - unsigned bv_width; + unsigned bv_width = 0; if (contains_bv(m, lc.get_lemmas()[0].get_sub(), bv_width)) { cc.set_bv(bv_width); } @@ -232,7 +232,7 @@ void lemma_global_generalizer::subsumer::setup_cvx_closure( cc.set_col_var(j, mk_rat_mul(m_col_lcm.get(j), m_col_names.get(j))); vector row; - unsigned i; + unsigned i = 0; for (const auto &lemma : lemmas) { row.reset(); row.reserve(n_vars); diff --git a/src/muz/spacer/spacer_global_generalizer.h b/src/muz/spacer/spacer_global_generalizer.h index 00b85ecd5..b7ee05757 100644 --- a/src/muz/spacer/spacer_global_generalizer.h +++ b/src/muz/spacer/spacer_global_generalizer.h @@ -161,7 +161,6 @@ class lemma_global_generalizer : public lemma_generalizer { public: lemma_global_generalizer(context &ctx); - ~lemma_global_generalizer() override {} void operator()(lemma_ref &lemma) override; diff --git a/src/muz/spacer/spacer_legacy_frames.cpp b/src/muz/spacer/spacer_legacy_frames.cpp index a21df5038..15b37b127 100644 --- a/src/muz/spacer/spacer_legacy_frames.cpp +++ b/src/muz/spacer/spacer_legacy_frames.cpp @@ -90,10 +90,10 @@ bool pred_transformer::legacy_frames::propagate_to_next_level(unsigned src_level for (unsigned i = 0; i < m_levels[src_level].size();) { expr_ref_vector &src = m_levels[src_level]; expr * curr = src[i].get(); - unsigned stored_lvl; + unsigned stored_lvl = 0; VERIFY(m_prop2level.find(curr, stored_lvl)); SASSERT(stored_lvl >= src_level); - unsigned solver_level; + unsigned solver_level = 0; if (stored_lvl > src_level) { TRACE("spacer", tout << "at level: " << stored_lvl << " " << mk_pp(curr, m) << "\n";); src[i] = src.back(); diff --git a/src/muz/spacer/spacer_legacy_mev.cpp b/src/muz/spacer/spacer_legacy_mev.cpp index a0c95fbd9..57f249274 100644 --- a/src/muz/spacer/spacer_legacy_mev.cpp +++ b/src/muz/spacer/spacer_legacy_mev.cpp @@ -568,8 +568,8 @@ void model_evaluator::eval_eq(app* e, expr* arg1, expr* arg2) void model_evaluator::eval_basic(app* e) { - expr* arg1, *arg2; - expr *argCond, *argThen, *argElse, *arg; + expr* arg1 = nullptr, *arg2 = nullptr; + expr *argCond = nullptr, *argThen = nullptr, *argElse = nullptr, *arg = nullptr; bool has_x = false; unsigned arity = e->get_num_args(); switch (e->get_decl_kind()) { diff --git a/src/muz/spacer/spacer_proof_utils.cpp b/src/muz/spacer/spacer_proof_utils.cpp index 9fbd4e01c..114dfc885 100644 --- a/src/muz/spacer/spacer_proof_utils.cpp +++ b/src/muz/spacer/spacer_proof_utils.cpp @@ -432,8 +432,8 @@ namespace spacer { ptr_buffer args; for (unsigned i = 0, sz = m.get_num_parents(p); i < sz; ++i) { - proof *pp, *tmp; - pp = m.get_parent(p, i); + proof *tmp = nullptr; + proof* pp = m.get_parent(p, i); VERIFY(m_cache.find(pp, tmp)); args.push_back(tmp); dirty |= (pp != tmp); @@ -455,8 +455,8 @@ namespace spacer { } } - proof* res; - VERIFY(m_cache.find(pr,res)); + proof* res = nullptr; + VERIFY(m_cache.find(pr, res)); DEBUG_CODE( proof_checker pc(m); expr_ref_vector side(m); diff --git a/src/muz/spacer/spacer_unsat_core_plugin.cpp b/src/muz/spacer/spacer_unsat_core_plugin.cpp index c0a9d7e6f..f0cfcbcd2 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.cpp +++ b/src/muz/spacer/spacer_unsat_core_plugin.cpp @@ -97,7 +97,6 @@ namespace spacer { // XXX this assertion should be true so there is no need to check for it SASSERT (!m_ctx.is_closed (step)); func_decl* d = step->get_decl(); - symbol sym; TRACE("spacer.farkas", tout << "looking at: " << mk_pp(step, m) << "\n";); if (!m_ctx.is_closed(step) && is_farkas_lemma(m, step)) { @@ -239,9 +238,8 @@ namespace spacer { SASSERT(m_ctx.is_b(step)); func_decl* d = step->get_decl(); - symbol sym; if (!m_ctx.is_closed(step) && // if step is not already interpolated - is_farkas_lemma(m, step)) { + is_farkas_lemma(m, step)) { SASSERT(d->get_num_parameters() == m.get_num_parents(step) + 2); SASSERT(m.has_fact(step)); diff --git a/src/muz/spacer/spacer_unsat_core_plugin.h b/src/muz/spacer/spacer_unsat_core_plugin.h index a7ea4c89b..b844cdd46 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.h +++ b/src/muz/spacer/spacer_unsat_core_plugin.h @@ -33,7 +33,7 @@ namespace spacer { unsat_core_plugin(unsat_core_learner& learner); virtual ~unsat_core_plugin() = default; virtual void compute_partial_core(proof* step) = 0; - virtual void finalize(){}; + virtual void finalize(){} unsat_core_learner& m_ctx; }; diff --git a/src/muz/tab/tab_context.cpp b/src/muz/tab/tab_context.cpp index f65661e9e..175c8aeb8 100644 --- a/src/muz/tab/tab_context.cpp +++ b/src/muz/tab/tab_context.cpp @@ -1354,8 +1354,6 @@ namespace datalog { m_fparams.m_mbqi = false; } - ~imp() {} - lbool query(expr* query) { m_ctx.ensure_opened(); m_index.reset(); diff --git a/src/muz/transforms/dl_mk_array_blast.cpp b/src/muz/transforms/dl_mk_array_blast.cpp index 30b57f2a4..824b298b4 100644 --- a/src/muz/transforms/dl_mk_array_blast.cpp +++ b/src/muz/transforms/dl_mk_array_blast.cpp @@ -38,9 +38,6 @@ namespace datalog { m_rewriter.updt_params(m_params); } - mk_array_blast::~mk_array_blast() { - } - bool mk_array_blast::is_store_def(expr* e, expr*& x, expr*& y) { if (m.is_eq(e, x, y)) { if (!a.is_store(y)) { diff --git a/src/muz/transforms/dl_mk_array_blast.h b/src/muz/transforms/dl_mk_array_blast.h index 352c8a248..12102af73 100644 --- a/src/muz/transforms/dl_mk_array_blast.h +++ b/src/muz/transforms/dl_mk_array_blast.h @@ -64,8 +64,6 @@ namespace datalog { \brief Create rule transformer that removes array stores and selects by ackermannization. */ mk_array_blast(context & ctx, unsigned priority); - - ~mk_array_blast() override; rule_set * operator()(rule_set const & source) override; diff --git a/src/muz/transforms/dl_mk_array_eq_rewrite.h b/src/muz/transforms/dl_mk_array_eq_rewrite.h index 7f6a29bf3..eabef4792 100644 --- a/src/muz/transforms/dl_mk_array_eq_rewrite.h +++ b/src/muz/transforms/dl_mk_array_eq_rewrite.h @@ -40,7 +40,6 @@ namespace datalog { public: mk_array_eq_rewrite(context & ctx, unsigned priority); rule_set * operator()(rule_set const & source) override; - ~mk_array_eq_rewrite() override{} }; diff --git a/src/muz/transforms/dl_mk_array_instantiation.h b/src/muz/transforms/dl_mk_array_instantiation.h index 0002f4ecd..71924288f 100644 --- a/src/muz/transforms/dl_mk_array_instantiation.h +++ b/src/muz/transforms/dl_mk_array_instantiation.h @@ -112,7 +112,6 @@ namespace datalog { public: mk_array_instantiation(context & ctx, unsigned priority); rule_set * operator()(rule_set const & source) override; - ~mk_array_instantiation() override{} }; diff --git a/src/muz/transforms/dl_mk_backwards.cpp b/src/muz/transforms/dl_mk_backwards.cpp index 5d124336b..5024d4631 100644 --- a/src/muz/transforms/dl_mk_backwards.cpp +++ b/src/muz/transforms/dl_mk_backwards.cpp @@ -27,8 +27,6 @@ namespace datalog { m(ctx.get_manager()), m_ctx(ctx) { } - - mk_backwards::~mk_backwards() { } rule_set * mk_backwards::operator()(rule_set const & source) { context& ctx = source.get_context(); diff --git a/src/muz/transforms/dl_mk_backwards.h b/src/muz/transforms/dl_mk_backwards.h index 78a9d2fd0..4d1522e02 100644 --- a/src/muz/transforms/dl_mk_backwards.h +++ b/src/muz/transforms/dl_mk_backwards.h @@ -27,7 +27,6 @@ namespace datalog { context& m_ctx; public: mk_backwards(context & ctx, unsigned priority = 33000); - ~mk_backwards() override; rule_set * operator()(rule_set const & source) override; }; diff --git a/src/muz/transforms/dl_mk_bit_blast.cpp b/src/muz/transforms/dl_mk_bit_blast.cpp index 439cb4540..0072f0078 100644 --- a/src/muz/transforms/dl_mk_bit_blast.cpp +++ b/src/muz/transforms/dl_mk_bit_blast.cpp @@ -146,8 +146,6 @@ namespace datalog { m_dst(nullptr) {} - ~expand_mkbv_cfg() {} - void set_src(rule_set const* src) { m_src = src; } void set_dst(rule_set* dst) { m_dst = dst; } func_decl_ref_vector const& old_funcs() const { return m_old_funcs; } diff --git a/src/muz/transforms/dl_mk_elim_term_ite.cpp b/src/muz/transforms/dl_mk_elim_term_ite.cpp index 753b82cea..98bd3c41a 100644 --- a/src/muz/transforms/dl_mk_elim_term_ite.cpp +++ b/src/muz/transforms/dl_mk_elim_term_ite.cpp @@ -80,8 +80,6 @@ namespace datalog { rm(ctx.get_rule_manager()), m_ground(m) {} - mk_elim_term_ite::~mk_elim_term_ite() {} - /** \brief map free variables in e to ground, fresh, constants m_ground is reset on every new rule so it is safe to assume diff --git a/src/muz/transforms/dl_mk_elim_term_ite.h b/src/muz/transforms/dl_mk_elim_term_ite.h index 98acd12f1..d42a7d773 100644 --- a/src/muz/transforms/dl_mk_elim_term_ite.h +++ b/src/muz/transforms/dl_mk_elim_term_ite.h @@ -35,7 +35,6 @@ namespace datalog { expr_ref ground(expr* e); public: mk_elim_term_ite(context &ctx, unsigned priority); - ~mk_elim_term_ite() override; rule_set * operator()(const rule_set &source) override; }; } diff --git a/src/muz/transforms/dl_mk_karr_invariants.cpp b/src/muz/transforms/dl_mk_karr_invariants.cpp index 18d67f549..955c3ca92 100644 --- a/src/muz/transforms/dl_mk_karr_invariants.cpp +++ b/src/muz/transforms/dl_mk_karr_invariants.cpp @@ -58,8 +58,6 @@ namespace datalog { m_inner_ctx.updt_params(params); } - mk_karr_invariants::~mk_karr_invariants() { } - void matrix::display_row( std::ostream& out, vector const& row, rational const& b, bool is_eq) { for (unsigned j = 0; j < row.size(); ++j) { diff --git a/src/muz/transforms/dl_mk_karr_invariants.h b/src/muz/transforms/dl_mk_karr_invariants.h index ac1015d14..9ba579a60 100644 --- a/src/muz/transforms/dl_mk_karr_invariants.h +++ b/src/muz/transforms/dl_mk_karr_invariants.h @@ -62,8 +62,6 @@ namespace datalog { rule_set* update_rules(rule_set const& src); public: mk_karr_invariants(context & ctx, unsigned priority); - - ~mk_karr_invariants() override; rule_set * operator()(rule_set const & source) override; diff --git a/src/muz/transforms/dl_mk_loop_counter.cpp b/src/muz/transforms/dl_mk_loop_counter.cpp index 91aaa8d8b..a20224eb2 100644 --- a/src/muz/transforms/dl_mk_loop_counter.cpp +++ b/src/muz/transforms/dl_mk_loop_counter.cpp @@ -30,8 +30,6 @@ namespace datalog { m_refs(m) { } - mk_loop_counter::~mk_loop_counter() { } - app_ref mk_loop_counter::add_arg(rule_set const& src, rule_set& dst, app* fn, unsigned idx) { expr_ref_vector args(m); func_decl* new_fn, *old_fn = fn->get_decl(); diff --git a/src/muz/transforms/dl_mk_loop_counter.h b/src/muz/transforms/dl_mk_loop_counter.h index 067945caf..b2758df67 100644 --- a/src/muz/transforms/dl_mk_loop_counter.h +++ b/src/muz/transforms/dl_mk_loop_counter.h @@ -35,7 +35,6 @@ namespace datalog { app_ref del_arg(app* fn); public: mk_loop_counter(context & ctx, unsigned priority = 33000); - ~mk_loop_counter() override; rule_set * operator()(rule_set const & source) override; diff --git a/src/muz/transforms/dl_mk_magic_sets.h b/src/muz/transforms/dl_mk_magic_sets.h index aa4c30274..3a8a92580 100644 --- a/src/muz/transforms/dl_mk_magic_sets.h +++ b/src/muz/transforms/dl_mk_magic_sets.h @@ -65,7 +65,7 @@ namespace datalog { func_decl * m_pred; adornment m_adornment; - adornment_desc() {} + adornment_desc() = default; adornment_desc(func_decl * pred) : m_pred(pred) {} adornment_desc(func_decl * pred, const adornment & a) : m_pred(pred), m_adornment(a) {} diff --git a/src/muz/transforms/dl_mk_magic_symbolic.cpp b/src/muz/transforms/dl_mk_magic_symbolic.cpp index 59529e630..afadfd6c3 100644 --- a/src/muz/transforms/dl_mk_magic_symbolic.cpp +++ b/src/muz/transforms/dl_mk_magic_symbolic.cpp @@ -63,8 +63,6 @@ namespace datalog { m(ctx.get_manager()), m_ctx(ctx) { } - - mk_magic_symbolic::~mk_magic_symbolic() { } rule_set * mk_magic_symbolic::operator()(rule_set const & source) { if (!m_ctx.magic()) { diff --git a/src/muz/transforms/dl_mk_magic_symbolic.h b/src/muz/transforms/dl_mk_magic_symbolic.h index 208f79f45..ac29194bc 100644 --- a/src/muz/transforms/dl_mk_magic_symbolic.h +++ b/src/muz/transforms/dl_mk_magic_symbolic.h @@ -29,7 +29,6 @@ namespace datalog { app_ref mk_query(app* q); public: mk_magic_symbolic(context & ctx, unsigned priority = 33037); - ~mk_magic_symbolic() override; rule_set * operator()(rule_set const & source) override; }; diff --git a/src/muz/transforms/dl_mk_quantifier_abstraction.cpp b/src/muz/transforms/dl_mk_quantifier_abstraction.cpp index b8a68a443..6b321bc75 100644 --- a/src/muz/transforms/dl_mk_quantifier_abstraction.cpp +++ b/src/muz/transforms/dl_mk_quantifier_abstraction.cpp @@ -149,9 +149,6 @@ namespace datalog { m_mc(nullptr) { } - mk_quantifier_abstraction::~mk_quantifier_abstraction() { - } - func_decl* mk_quantifier_abstraction::declare_pred(rule_set const& rules, rule_set& dst, func_decl* old_p) { if (rules.is_output_predicate(old_p)) { diff --git a/src/muz/transforms/dl_mk_quantifier_abstraction.h b/src/muz/transforms/dl_mk_quantifier_abstraction.h index 6cf546a50..33c70c08b 100644 --- a/src/muz/transforms/dl_mk_quantifier_abstraction.h +++ b/src/muz/transforms/dl_mk_quantifier_abstraction.h @@ -49,8 +49,6 @@ namespace datalog { public: mk_quantifier_abstraction(context & ctx, unsigned priority); - - ~mk_quantifier_abstraction() override; rule_set * operator()(rule_set const & source) override; }; diff --git a/src/muz/transforms/dl_mk_quantifier_instantiation.cpp b/src/muz/transforms/dl_mk_quantifier_instantiation.cpp index 61c395b4e..d1fb6400c 100644 --- a/src/muz/transforms/dl_mk_quantifier_instantiation.cpp +++ b/src/muz/transforms/dl_mk_quantifier_instantiation.cpp @@ -41,9 +41,6 @@ namespace datalog { m_cnst2var(m) { } - mk_quantifier_instantiation::~mk_quantifier_instantiation() { - } - void mk_quantifier_instantiation::extract_quantifiers(rule& r, expr_ref_vector& conjs, quantifier_ref_vector& qs) { conjs.reset(); qs.reset(); diff --git a/src/muz/transforms/dl_mk_quantifier_instantiation.h b/src/muz/transforms/dl_mk_quantifier_instantiation.h index 5c0c28cd4..716de11f0 100644 --- a/src/muz/transforms/dl_mk_quantifier_instantiation.h +++ b/src/muz/transforms/dl_mk_quantifier_instantiation.h @@ -60,8 +60,6 @@ namespace datalog { public: mk_quantifier_instantiation(context & ctx, unsigned priority); - ~mk_quantifier_instantiation() override; - rule_set * operator()(rule_set const & source) override; }; diff --git a/src/muz/transforms/dl_mk_scale.cpp b/src/muz/transforms/dl_mk_scale.cpp index 38305a04e..54cf22ea8 100644 --- a/src/muz/transforms/dl_mk_scale.cpp +++ b/src/muz/transforms/dl_mk_scale.cpp @@ -110,9 +110,6 @@ namespace datalog { m_eqs(m) { } - mk_scale::~mk_scale() { - } - rule_set * mk_scale::operator()(rule_set const & source) { if (!m_ctx.scale()) { return nullptr; diff --git a/src/muz/transforms/dl_mk_scale.h b/src/muz/transforms/dl_mk_scale.h index a8e42f17e..fcbf4c226 100644 --- a/src/muz/transforms/dl_mk_scale.h +++ b/src/muz/transforms/dl_mk_scale.h @@ -42,7 +42,6 @@ namespace datalog { app_ref mk_constraint(unsigned num_vars, app* q); public: mk_scale(context & ctx, unsigned priority = 33039); - ~mk_scale() override; rule_set * operator()(rule_set const & source) override; }; diff --git a/src/nlsat/CMakeLists.txt b/src/nlsat/CMakeLists.txt index cd073f0d5..077c420f9 100644 --- a/src/nlsat/CMakeLists.txt +++ b/src/nlsat/CMakeLists.txt @@ -7,7 +7,9 @@ z3_add_component(nlsat nlsat_simplify.cpp nlsat_solver.cpp nlsat_types.cpp - COMPONENT_DEPENDENCIES + nlsat_simple_checker.cpp + nlsat_variable_ordering_strategy.cpp + COMPONENT_DEPENDENCIES polynomial sat PYG_FILES diff --git a/src/nlsat/nlsat_explain.cpp b/src/nlsat/nlsat_explain.cpp index 618394ac1..cda44bdd4 100644 --- a/src/nlsat/nlsat_explain.cpp +++ b/src/nlsat/nlsat_explain.cpp @@ -45,6 +45,8 @@ namespace nlsat { bool m_minimize_cores; bool m_factor; bool m_signed_project; + bool m_cell_sample; + struct todo_set { polynomial::cache & m_cache; @@ -124,13 +126,13 @@ namespace nlsat { scoped_literal_vector m_core2; // temporary fields for storing the result - scoped_literal_vector * m_result; + scoped_literal_vector * m_result = nullptr; svector m_already_added_literal; evaluator & m_evaluator; imp(solver & s, assignment const & x2v, polynomial::cache & u, atom_vector const & atoms, atom_vector const & x2eq, - evaluator & ev): + evaluator & ev, bool is_sample): m_solver(s), m_assignment(x2v), m_atoms(atoms), @@ -144,19 +146,16 @@ namespace nlsat { m_factors(m_pm), m_factors_save(m_pm), m_roots_tmp(m_am), + m_cell_sample(is_sample), m_todo(u), m_core1(s), m_core2(s), - m_result(nullptr), m_evaluator(ev) { m_simplify_cores = false; m_full_dimensional = false; m_minimize_cores = false; m_signed_project = false; } - - ~imp() { - } std::ostream& display(std::ostream & out, polynomial_ref const & p) const { m_pm.display(out, p, m_solver.display_proc()); @@ -646,6 +645,45 @@ namespace nlsat { m_todo.insert(p); } } + + void add_sample_coeff(polynomial_ref_vector &ps, var x){ + polynomial_ref p(m_pm); + polynomial_ref lc(m_pm); + unsigned sz = ps.size(); + for (unsigned i = 0; i < sz; i++){ + p = ps.get(i); + unsigned k = degree(p, x); + SASSERT(k > 0); + TRACE("nlsat_explain", tout << "add_lc, x: "; display_var(tout, x); tout << "\nk: " << k << "\n"; display(tout, p); tout << "\n";); + for(; k > 0; k--){ + lc = m_pm.coeff(p, x, k); + add_factors(lc); + if (m_pm.nonzero_const_coeff(p, x, k)){ + TRACE("nlsat_explain", tout << "constant coefficient, skipping...\n";); + break; + } + } + SASSERT(sign(lc) != 0); + SASSERT(!is_const(lc)); + } + } + + void psc_resultant_sample(polynomial_ref_vector &ps, var x, polynomial_ref_vector & samples){ + polynomial_ref p(m_pm); + polynomial_ref q(m_pm); + SASSERT(samples.size() <= 2); + + for (unsigned i = 0; i < ps.size(); i++){ + p = ps.get(i); + for (unsigned j = 0; j < samples.size(); j++){ + q = samples.get(j); + if (!m_pm.eq(p, q)) { + psc(p, q, x); + } + } + } + } + /** \brief Add leading coefficients of the polynomials in ps. @@ -689,7 +727,6 @@ namespace nlsat { bool have_zero = false; for (unsigned i = 0; i < num_factors; i++) { f = m_factors.get(i); - // std::cout << "f=";display(std::cout, f) << "\n"; if (coeffs_are_zeroes_in_factor(f)) { have_zero = true; break; @@ -973,6 +1010,92 @@ namespace nlsat { add_simple_assumption(k, p, lsign); } + void cac_add_cell_lits(polynomial_ref_vector & ps, var y, polynomial_ref_vector & res) { + res.reset(); + SASSERT(m_assignment.is_assigned(y)); + bool lower_inf = true; + bool upper_inf = true; + scoped_anum_vector & roots = m_roots_tmp; + scoped_anum lower(m_am); + scoped_anum upper(m_am); + anum const & y_val = m_assignment.value(y); + TRACE("nlsat_explain", tout << "adding literals for "; display_var(tout, y); tout << " -> "; + m_am.display_decimal(tout, y_val); tout << "\n";); + polynomial_ref p_lower(m_pm); + unsigned i_lower = UINT_MAX; + polynomial_ref p_upper(m_pm); + unsigned i_upper = UINT_MAX; + polynomial_ref p(m_pm); + unsigned sz = ps.size(); + for (unsigned k = 0; k < sz; k++) { + p = ps.get(k); + if (max_var(p) != y) + continue; + roots.reset(); + // Variable y is assigned in m_assignment. We must temporarily unassign it. + // Otherwise, the isolate_roots procedure will assume p is a constant polynomial. + m_am.isolate_roots(p, undef_var_assignment(m_assignment, y), roots); + unsigned num_roots = roots.size(); + bool all_lt = true; + for (unsigned i = 0; i < num_roots; i++) { + int s = m_am.compare(y_val, roots[i]); + TRACE("nlsat_explain", + m_am.display_decimal(tout << "comparing root: ", roots[i]); tout << "\n"; + m_am.display_decimal(tout << "with y_val:", y_val); + tout << "\nsign " << s << "\n"; + tout << "poly: " << p << "\n"; + ); + if (s == 0) { + // y_val == roots[i] + // add literal + // ! (y = root_i(p)) + add_root_literal(atom::ROOT_EQ, y, i+1, p); + res.push_back(p); + return; + } + else if (s < 0) { + // y_val < roots[i] + if (i > 0) { + // y_val > roots[j] + int j = i - 1; + if (lower_inf || m_am.lt(lower, roots[j])) { + lower_inf = false; + m_am.set(lower, roots[j]); + p_lower = p; + i_lower = j + 1; + } + } + if (upper_inf || m_am.lt(roots[i], upper)) { + upper_inf = false; + m_am.set(upper, roots[i]); + p_upper = p; + i_upper = i + 1; + } + all_lt = false; + break; + } + } + if (all_lt && num_roots > 0) { + int j = num_roots - 1; + if (lower_inf || m_am.lt(lower, roots[j])) { + lower_inf = false; + m_am.set(lower, roots[j]); + p_lower = p; + i_lower = j + 1; + } + } + } + + if (!lower_inf) { + res.push_back(p_lower); + add_root_literal(m_full_dimensional ? atom::ROOT_GE : atom::ROOT_GT, y, i_lower, p_lower); + } + if (!upper_inf) { + res.push_back(p_upper); + add_root_literal(m_full_dimensional ? atom::ROOT_LE : atom::ROOT_LT, y, i_upper, p_upper); + } + } + /** Add one or two literals that specify in which cell of variable y the current interpretation is. One literal is added for the cases: @@ -1016,6 +1139,7 @@ namespace nlsat { // Otherwise, the isolate_roots procedure will assume p is a constant polynomial. m_am.isolate_roots(p, undef_var_assignment(m_assignment, y), roots); unsigned num_roots = roots.size(); + bool all_lt = true; for (unsigned i = 0; i < num_roots; i++) { int s = m_am.compare(y_val, roots[i]); TRACE("nlsat_explain", @@ -1033,25 +1157,33 @@ namespace nlsat { } else if (s < 0) { // y_val < roots[i] - - // check if roots[i] is a better upper bound + if (i > 0) { + // y_val > roots[j] + int j = i - 1; + if (lower_inf || m_am.lt(lower, roots[j])) { + lower_inf = false; + m_am.set(lower, roots[j]); + p_lower = p; + i_lower = j + 1; + } + } if (upper_inf || m_am.lt(roots[i], upper)) { upper_inf = false; m_am.set(upper, roots[i]); p_upper = p; - i_upper = i+1; + i_upper = i + 1; } + all_lt = false; + break; } - else if (s > 0) { - // roots[i] < y_val - - // check if roots[i] is a better lower bound - if (lower_inf || m_am.lt(lower, roots[i])) { - lower_inf = false; - m_am.set(lower, roots[i]); - p_lower = p; - i_lower = i+1; - } + } + if (all_lt && num_roots > 0) { + int j = num_roots - 1; + if (lower_inf || m_am.lt(lower, roots[j])) { + lower_inf = false; + m_am.set(lower, roots[j]); + p_lower = p; + i_lower = j + 1; } } } @@ -1064,6 +1196,7 @@ namespace nlsat { } } + /** \brief Return true if all polynomials in ps are univariate in x. */ @@ -1082,7 +1215,8 @@ namespace nlsat { /** \brief Apply model-based projection operation defined in our paper. */ - void project(polynomial_ref_vector & ps, var max_x) { + + void project_original(polynomial_ref_vector & ps, var max_x) { if (ps.empty()) return; m_todo.reset(); @@ -1094,12 +1228,12 @@ namespace nlsat { if (x < max_x) add_cell_lits(ps, x); while (true) { - TRACE("nlsat_explain", tout << "project loop, processing var "; display_var(tout, x); tout << "\npolynomials\n"; - display(tout, ps); tout << "\n";); if (all_univ(ps, x) && m_todo.empty()) { m_todo.reset(); break; } + TRACE("nlsat_explain", tout << "project loop, processing var "; display_var(tout, x); tout << "\npolynomials\n"; + display(tout, ps); tout << "\n";); add_lc(ps, x); psc_discriminant(ps, x); psc_resultant(ps, x); @@ -1110,6 +1244,68 @@ namespace nlsat { } } + /** + * Sample Projection + * Reference: + * Haokun Li and Bican Xia. + * "Solving Satisfiability of Polynomial Formulas By Sample - Cell Projection" + * https://arxiv.org/abs/2003.00409 + */ + void project_cdcac(polynomial_ref_vector & ps, var max_x) { + if (ps.empty()) + return; + bool first = true; + m_todo.reset(); + for (poly* p : ps) { + m_todo.insert(p); + } + var x = m_todo.remove_max_polys(ps); + // Remark: after vanishing coefficients are eliminated, ps may not contain max_x anymore + + polynomial_ref_vector samples(m_pm); + + + if (x < max_x){ + cac_add_cell_lits(ps, x, samples); + } + + while (true) { + if (all_univ(ps, x) && m_todo.empty()) { + m_todo.reset(); + break; + } + TRACE("nlsat_explain", tout << "project loop, processing var "; display_var(tout, x); tout << "\npolynomials\n"; + display(tout, ps); tout << "\n";); + + if (first) { + add_lc(ps, x); + psc_discriminant(ps, x); + psc_resultant(ps, x); + first = false; + } + else { + add_lc(ps, x); + // add_sample_coeff(ps, x); + psc_discriminant(ps, x); + psc_resultant_sample(ps, x, samples); + } + + if (m_todo.empty()) + break; + x = m_todo.remove_max_polys(ps); + cac_add_cell_lits(ps, x, samples); + } + } + + void project(polynomial_ref_vector & ps, var max_x) { + if (m_cell_sample) { + project_cdcac(ps, max_x); + } + else { + project_original(ps, max_x); + } + } + bool check_already_added() const { for (bool b : m_already_added_literal) { (void)b; @@ -1474,7 +1670,7 @@ namespace nlsat { var max_x = max_var(m_ps); TRACE("nlsat_explain", tout << "polynomials in the conflict:\n"; display(tout, m_ps); tout << "\n";); elim_vanishing(m_ps); - TRACE("nlsat_explain", tout << "elim vanishing x" << max_x << "\n"; display(tout, m_ps); tout << "\n";); + TRACE("nlsat_explain", tout << "elim vanishing\n"; display(tout, m_ps); tout << "\n";); project(m_ps, max_x); TRACE("nlsat_explain", tout << "after projection\n"; display(tout, m_ps); tout << "\n";); } @@ -1936,8 +2132,8 @@ namespace nlsat { }; explain::explain(solver & s, assignment const & x2v, polynomial::cache & u, - atom_vector const& atoms, atom_vector const& x2eq, evaluator & ev) { - m_imp = alloc(imp, s, x2v, u, atoms, x2eq, ev); + atom_vector const& atoms, atom_vector const& x2eq, evaluator & ev, bool use_cell_sample) { + m_imp = alloc(imp, s, x2v, u, atoms, x2eq, ev, use_cell_sample); } explain::~explain() { diff --git a/src/nlsat/nlsat_explain.h b/src/nlsat/nlsat_explain.h index 20322a680..f44a9ae92 100644 --- a/src/nlsat/nlsat_explain.h +++ b/src/nlsat/nlsat_explain.h @@ -8,7 +8,8 @@ Module Name: Abstract: Functor that implements the "explain" procedure defined in Dejan and Leo's paper. - + Uses paper Haokun Li and Bican Xia, "Solving Satisfiability of Polynomial Formulas By Sample - Cell Projection",https://arxiv.org/abs/2003.00409, + and code from https://github.com/hybridSMT/hybridSMT.git Author: Leonardo de Moura (leonardo) 2012-01-13. @@ -34,7 +35,8 @@ namespace nlsat { imp * m_imp; public: explain(solver & s, assignment const & x2v, polynomial::cache & u, - atom_vector const& atoms, atom_vector const& x2eq, evaluator & ev); + atom_vector const& atoms, atom_vector const& x2eq, evaluator & ev, bool use_cell_sample_proj); + ~explain(); void reset(); diff --git a/src/nlsat/nlsat_interval_set.cpp b/src/nlsat/nlsat_interval_set.cpp index f928fd5b6..872266f5f 100644 --- a/src/nlsat/nlsat_interval_set.cpp +++ b/src/nlsat/nlsat_interval_set.cpp @@ -112,9 +112,6 @@ namespace nlsat { m_am(m), m_allocator(a) { } - - interval_set_manager::~interval_set_manager() { - } void interval_set_manager::del(interval_set * s) { if (s == nullptr) @@ -684,34 +681,51 @@ namespace nlsat { return new_set; } - void interval_set_manager::peek_in_complement(interval_set const * s, bool is_int, anum & w, bool randomize) { + int compare_interval_with_zero(const interval &now, const scoped_anum &zero, anum_manager & m) { + if (!now.m_upper_inf) { + int sgn = m.compare(now.m_upper, zero); + if (sgn < 0) + return -1; + if (sgn == 0 && now.m_upper_open) + return -1; + } + if (!now.m_lower_inf) { + int sgn = m.compare(now.m_lower, zero); + if (sgn > 0) + return 1; + if (sgn == 0 && now.m_lower_open) + return 1; + } + return 0; + } + + + void interval_set_manager::pick_in_complement(interval_set const * s, bool is_int, anum & w, bool randomize) { SASSERT(!is_full(s)); if (s == nullptr) { - if (randomize) { - int num = m_rand() % 2 == 0 ? 1 : -1; -#define MAX_RANDOM_DEN_K 4 - int den_k = (m_rand() % MAX_RANDOM_DEN_K); - int den = is_int ? 1 : (1 << den_k); - scoped_mpq _w(m_am.qm()); - m_am.qm().set(_w, num, den); - m_am.set(w, _w); - } - else { - m_am.set(w, 0); - } + m_am.set(w, 0); return; } - unsigned n = 0; - unsigned num = num_intervals(s); - if (!s->m_intervals[0].m_lower_inf) { - // lower is not -oo - n++; - m_am.int_lt(s->m_intervals[0].m_lower, w); - if (!randomize) - return; + // try to assign w to zero first to simplify the polynomials + scoped_anum zero(m_am); + m_am.set(zero, 0); + bool available = true; + for (unsigned i = 0; i < num; ++i) { + int sgn = compare_interval_with_zero(s->m_intervals[i], zero, m_am); + if (sgn == 0) { + available = false; + break; + } + if (sgn > 0) + break; } + if (available) { + m_am.set(w, 0); + return ; + } + // cannot assign w to zero if (!s->m_intervals[num-1].m_upper_inf) { // upper is not oo n++; @@ -720,6 +734,16 @@ namespace nlsat { if (!randomize) return; } + + if (!s->m_intervals[0].m_lower_inf) { + // lower is not -oo + n++; + m_am.int_lt(s->m_intervals[0].m_lower, w); + if (!randomize) + return; + } + + // Try to find a gap that is not an unit. for (unsigned i = 1; i < num; i++) { @@ -770,5 +794,4 @@ namespace nlsat { out << "*"; return out; } - }; diff --git a/src/nlsat/nlsat_interval_set.h b/src/nlsat/nlsat_interval_set.h index f1055118f..297318912 100644 --- a/src/nlsat/nlsat_interval_set.h +++ b/src/nlsat/nlsat_interval_set.h @@ -21,7 +21,7 @@ Revision History: #include "nlsat/nlsat_types.h" namespace nlsat { - + class interval_set; class interval_set_manager { @@ -29,10 +29,10 @@ namespace nlsat { small_object_allocator & m_allocator; svector m_already_visited; random_gen m_rand; + void del(interval_set * s); public: interval_set_manager(anum_manager & m, small_object_allocator & a); - ~interval_set_manager(); void set_seed(unsigned s) { m_rand.set_seed(s); } @@ -107,7 +107,7 @@ namespace nlsat { \pre !is_full(s) */ - void peek_in_complement(interval_set const * s, bool is_int, anum & w, bool randomize); + void pick_in_complement(interval_set const * s, bool is_int, anum & w, bool randomize); }; typedef obj_ref interval_set_ref; diff --git a/src/nlsat/nlsat_params.pyg b/src/nlsat/nlsat_params.pyg index cac33fe87..01229a527 100644 --- a/src/nlsat/nlsat_params.pyg +++ b/src/nlsat/nlsat_params.pyg @@ -3,6 +3,9 @@ def_module_params('nlsat', description='nonlinear solver', export=True, params=(max_memory_param(), + ('simple_check', BOOL, False, "precheck polynomials using variables sign"), + ('variable_ordering_strategy', UINT, 0, "Variable Ordering Strategy, 0 for none, 1 for BROWN, 2 for TRIANGULAR, 3 for ONLYPOLY"), + ('cell_sample', BOOL, True, "cell sample projection"), ('lazy', UINT, 0, "how lazy the solver is."), ('reorder', BOOL, True, "reorder variables."), ('log_lemmas', BOOL, False, "display lemmas as self-contained SMT formulas"), @@ -14,6 +17,5 @@ def_module_params('nlsat', ('shuffle_vars', BOOL, False, "use a random variable order."), ('inline_vars', BOOL, False, "inline variables that can be isolated from equations (not supported in incremental mode)"), ('seed', UINT, 0, "random seed."), - ('factor', BOOL, True, "factor polynomials produced during conflict resolution.") + ('factor', BOOL, True, "factor polynomials produced during conflict resolution.") )) - diff --git a/src/nlsat/nlsat_simple_checker.cpp b/src/nlsat/nlsat_simple_checker.cpp new file mode 100644 index 000000000..f61bc97ad --- /dev/null +++ b/src/nlsat/nlsat_simple_checker.cpp @@ -0,0 +1,1563 @@ +#include "nlsat/nlsat_simple_checker.h" + +namespace nlsat { + struct simple_checker::imp { + // solver / + pmanager ± + anum_manager &am; + const clause_vector &clauses; + literal_vector &learned_unit; + const atom_vector &atoms; + const unsigned arith_var_num; + // unsigned all_var_num; + enum sign_kind { EQ = 0, LT, GT, NONE, LE, GE, NEQ}; + void display(std::ostream & out, const sign_kind &sk) { + if (sk == EQ) + out << "=="; + else if (sk == LT) + out << "<"; + else if (sk == GT) + out << ">"; + else if (sk == NONE) + out << "<=>"; + else if (sk == LE) + out << "<="; + else if (sk == GE) + out << ">="; + else if (sk == NEQ) + out << "!="; + else + UNREACHABLE(); + } + struct Endpoint { + anum_manager &m_am; + unsigned m_open:1; + unsigned m_inf:1; + unsigned m_is_lower:1; + scoped_anum m_val; + Endpoint(anum_manager &_am) : + m_am(_am), + m_open(1), + m_inf(1), + m_is_lower(1), + m_val(_am) { + } + Endpoint(anum_manager &_am, unsigned _open, unsigned _inf, unsigned _islower) : + m_am(_am), + m_open(_open), + m_inf(_inf), + m_is_lower(_islower), + m_val(_am) { + } + Endpoint(anum_manager &_am, unsigned _open, unsigned _inf, unsigned _islower, const scoped_anum &_val) : + m_am(_am), + m_open(_open), + m_inf(_inf), + m_is_lower(_islower), + m_val(_am) { + m_am.set(m_val, _val); + } + bool operator== (const Endpoint &rhs) const { + if (m_inf && rhs.m_inf && m_is_lower == rhs.m_is_lower) + return true; + if (!m_inf && !rhs.m_inf && m_open == rhs.m_open && m_val == rhs.m_val) { + if (!m_open) + return true; + if (m_is_lower == rhs.m_is_lower) + return true; + } + return false; + } + bool operator< (const Endpoint &rhs) const { + if (m_inf) { + if (m_is_lower) { + if (rhs.m_inf && rhs.m_is_lower) + return false; + else + return true; + } + else { + return false; + } + } + else { + if (rhs.m_inf) { + if (rhs.m_is_lower) + return false; + else + return true; + } + else { + if (m_val == rhs.m_val) { + if (!m_open && !rhs.m_open) { // {[, [} + // {[, [} {[, ]} {], [} {], ]} + return false; + } + else if (!m_open) { // {[, (} + // [ < (, [ > ), ] < (, ] > ) + if (rhs.m_is_lower) + return true; + else + return false; + } + else if (!rhs.m_open) { // {(, [} + if (m_is_lower) // x + EPS + return false; + else // x - EPS + return true; + } + else { // {(, (} + // ( == (, ( > ), ) < (, ) == ) + if (!m_is_lower && rhs.m_is_lower) + return true; + else + return false; + } + } + else { + return m_val < rhs.m_val; + } + } + } + } + void copy(const Endpoint &ep) { + m_inf = ep.m_inf; + m_open = ep.m_open; + m_is_lower = ep.m_is_lower; + if (!m_inf) + m_am.set(m_val, ep.m_val); + } + void set_num(const scoped_anum &num, unsigned is_lower) { + m_open = 0; + m_inf = 0; + m_is_lower = is_lower; + m_am.set(m_val, num); + } + void set_num(int num, unsigned is_lower) { + m_open = 0; + m_inf = 0; + m_is_lower = is_lower; + m_am.set(m_val, num); + } + bool is_neg() const { + if (m_inf) { + if (m_is_lower) + return true; + else + return false; + } + else { + if (m_am.is_zero(m_val)) { + if (m_open) { + if (m_is_lower) + return false; + else + return true; + } + else { + return false; + } + } + else { + return m_am.is_neg(m_val); + } + } + } + bool is_zero(unsigned is_open = 0) const { + return !m_inf && m_open == is_open && m_am.is_zero(m_val); + } + }; + struct Domain_Interval { + anum_manager &m_am; + Endpoint m_lower; + Endpoint m_upper; + Domain_Interval(anum_manager &_am) : + m_am(_am), + m_lower(_am, 1, 1, 1), + m_upper(_am, 1, 1, 0) { + // (-oo, +oo) + } + Domain_Interval(anum_manager &_am, + unsigned _lower_open, unsigned _lower_inf, + unsigned _upper_open, unsigned _upper_inf) : + m_am(_am), + m_lower(_am, _lower_open, _lower_inf, 1), + m_upper(_am, _upper_open, _upper_inf, 0) { + } + void copy(const Domain_Interval &di) { + m_lower.copy(di.m_lower); + m_upper.copy(di.m_upper); + } + void set_num(const scoped_anum &num) { + m_lower.set_num(num, 1); + m_upper.set_num(num, 0); + } + void set_num(int num) { + m_lower.set_num(num, 1); + m_upper.set_num(num, 0); + } + }; + + void display(std::ostream & out, anum_manager & am, Domain_Interval const & curr) { + if (curr.m_lower.m_inf) { + out << "(-oo, "; + } + else { + if (curr.m_lower.m_open) + out << "("; + else + out << "["; + am.display_decimal(out, curr.m_lower.m_val); + out << ", "; + } + if (curr.m_upper.m_inf) { + out << "oo)"; + } + else { + am.display_decimal(out, curr.m_upper.m_val); + if (curr.m_upper.m_open) + out << ")"; + else + out << "]"; + } + } + + struct Var_Domain { + Domain_Interval ori_val; // original, ext sign + Domain_Interval mag_val; // magnitude + Var_Domain(anum_manager &am) : + ori_val(am), + mag_val(am) { + mag_val.m_lower.set_num(0, 1); + } + void copy(const Var_Domain &vd) { + ori_val.copy(vd.ori_val); + mag_val.copy(vd.mag_val); + } + }; + vector vars_domain; + struct Clause_Visit_Tag { + bool visited; + bool_vector literal_visited; + Clause_Visit_Tag() : visited(false) {} + }; + vector clauses_visited; + bool improved; + enum special_ineq_kind {UNK = 0, AXBC, AXBSC, NK}; // None Kind + vector> literal_special_kind; + imp(pmanager &_pm, anum_manager &_am, const clause_vector &_clauses, literal_vector &_learned_unit, const atom_vector &_atoms, const unsigned &_arith_var_num) : + // sol(_sol), + pm(_pm), + am(_am), + clauses(_clauses), + learned_unit(_learned_unit), + atoms(_atoms), + arith_var_num(_arith_var_num) { + // all_var_num = atoms.size(); + for (unsigned i = 0; i < arith_var_num; ++i) { + vars_domain.push_back(Var_Domain(am)); + } + clauses_visited.resize(clauses.size()); + literal_special_kind.resize(clauses.size()); + } + sign_kind to_sign_kind(atom::kind kd) { + if (kd == atom::EQ) + return EQ; + if (kd == atom::LT) + return LT; + if (kd == atom::GT) + return GT; + UNREACHABLE(); + return EQ; + } + bool update_interval_intersection(Domain_Interval &ia, const Domain_Interval &ib) { + TRACE("simple_checker", + tout << "ia: "; + display(tout, am, ia); + tout << "\nib: "; + display(tout, am, ib); + tout << "\n"; + tout << "ia.lower < ib.lower: " << (ia.m_lower < ib.m_lower) << '\n'; + tout << "ia.m_upper < ib.m_upper: " << (ia.m_upper < ib.m_upper) << '\n'; + ); + if (ia.m_lower < ib.m_lower) { + ia.m_lower.copy(ib.m_lower); + improved = true; + } + + if (ib.m_upper < ia.m_upper) { + ia.m_upper.copy(ib.m_upper); + improved = true; + } + if (ia.m_upper < ia.m_lower) + return false; + + + + TRACE("simple_checker", + tout << "after update: "; + display(tout, am, ia); + tout << "\n"; + ); + return true; + } + + bool update_var_ori_domain_interval(Var_Domain &vd, const Domain_Interval &di) { + return update_interval_intersection(vd.ori_val, di); + } + bool update_var_mag_domain_interval_by_ori(Var_Domain &vd, const Domain_Interval &di) { + TRACE("simple_checker", + tout << "vd mag val: "; + display(tout, am, vd.mag_val); + tout << "\n"; + tout << "di: "; + display(tout, am, di); + tout << "\n"; + ); + Domain_Interval mag_di(am, 0, 0, 1, 1); + + if (di.m_lower.m_inf) { + mag_di.m_upper.m_inf = 1; + mag_di.m_upper.m_open = 1; + if (am.is_neg(di.m_upper.m_val)) { + // am.neg(di.m_upper); + am.set(mag_di.m_lower.m_val, di.m_upper.m_val*-1); + mag_di.m_lower.m_open = di.m_upper.m_open; + } + else if (am.is_zero(di.m_upper.m_val)) { + mag_di.m_lower.m_open = di.m_upper.m_open; + } + else { + return true; + } + } + else if (di.m_upper.m_inf) { + mag_di.m_upper.m_inf = 1; + mag_di.m_upper.m_open = 1; + if (am.is_neg(di.m_lower.m_val)) { + return true; + } + else if (am.is_zero(di.m_lower.m_val)) { + mag_di.m_lower.m_open = di.m_lower.m_open; + } + else { + am.set(mag_di.m_lower.m_val, di.m_lower.m_val); + mag_di.m_lower.m_open = di.m_lower.m_open; + } + } + else { + mag_di.m_lower.m_inf = 0; + mag_di.m_upper.m_inf = 0; + if (!am.is_neg(di.m_lower.m_val)) { + mag_di.m_lower.m_open = di.m_lower.m_open; + mag_di.m_upper.m_open = di.m_upper.m_open; + am.set(mag_di.m_lower.m_val, di.m_lower.m_val); + am.set(mag_di.m_upper.m_val, di.m_upper.m_val); + } + else if (!am.is_pos(di.m_upper.m_val)) { + mag_di.m_lower.m_open = di.m_upper.m_open; + mag_di.m_upper.m_open = di.m_lower.m_open; + + am.set(mag_di.m_lower.m_val, di.m_upper.m_val*-1); + am.set(mag_di.m_upper.m_val, di.m_lower.m_val*-1); + } + else { + scoped_anum nl(am); + am.set(nl, di.m_lower.m_val); + am.neg(nl); + am.set(mag_di.m_lower.m_val, 0); + mag_di.m_lower.m_open = 0; + if (nl < di.m_upper.m_val) { + mag_di.m_upper.m_open = di.m_upper.m_open; + am.set(mag_di.m_upper.m_val, di.m_upper.m_val); + } + else if (nl == di.m_upper.m_val) { + mag_di.m_upper.m_open = (di.m_lower.m_open | di.m_upper.m_open); + am.set(mag_di.m_upper.m_val, di.m_upper.m_val); + } + else { + mag_di.m_upper.m_open = di.m_lower.m_open; + am.set(mag_di.m_upper.m_val, nl); + } + } + } + TRACE("simple_checker", + tout << "mag di: "; + display(tout, am, mag_di); + tout << "\n"; + ); + return update_interval_intersection(vd.mag_val, mag_di); + } + void calc_formula(scoped_anum &num, const scoped_anum &a, unsigned b, const scoped_anum &c) { + scoped_anum frac(am); + am.div(c, a, frac); + am.neg(frac); + if (b > 1) + am.root(frac, b, num); + else + am.set(num, frac); + } + bool process_odd_degree_formula(Var_Domain &vd, sign_kind nsk, const scoped_anum &a, unsigned b, const scoped_anum &c) { + Domain_Interval now_di(am); + scoped_anum num(am); + calc_formula(num, a, b, c); + TRACE("simple_checker", + tout << "nsk: "; + display(tout, nsk); + tout << '\n'; + tout << "num: " << num << '\n'; + ); + if (nsk == EQ) { + now_di.set_num(num); + // am.set(now_di.m_lower.m_val, num); + // am.set(now_di.m_upper.m_val, num); + // now_di.m_lower.m_inf = 0; + // now_di.m_upper.m_inf = 0; + // now_di.m_lower.m_open = 0; + // now_di.m_upper.m_open = 0; + } + else if (nsk == LT) { + am.set(now_di.m_upper.m_val, num); + now_di.m_upper.m_inf = 0; + now_di.m_upper.m_open = 1; + } + else if (nsk == GT) { + am.set(now_di.m_lower.m_val, num); + now_di.m_lower.m_inf = 0; + now_di.m_lower.m_open = 1; + } + else if (nsk == LE) { + am.set(now_di.m_upper.m_val, num); + now_di.m_upper.m_inf = 0; + now_di.m_upper.m_open = 0; + } + else if (nsk == GE) { + am.set(now_di.m_lower.m_val, num); + now_di.m_lower.m_inf = 0; + now_di.m_lower.m_open = 0; + } + else { + UNREACHABLE(); + } + TRACE("simple_checker", + tout << "now_di: "; + display(tout, am, now_di); + tout << "\n"; + ); + if (!update_var_ori_domain_interval(vd, now_di)) + return false; + if (!update_var_mag_domain_interval_by_ori(vd, vd.ori_val)) + return false; + return true; + } + + bool process_even_degree_formula(Var_Domain &vd, sign_kind nsk, const scoped_anum &a, unsigned b, const scoped_anum &c) { + scoped_anum num(am), frac(am); + am.div(c, a, frac); + am.neg(frac); + + if (frac < 0) { + if (nsk == EQ || nsk == LT || nsk == LE) { + return false; + } + else if (nsk == GT || nsk == GE) { + return true; + } + else { + UNREACHABLE(); + } + } + else if (frac == 0) { + if (nsk == EQ || nsk == LE) { + Domain_Interval di(am); + di.set_num(0); + if (!update_interval_intersection(vd.ori_val, di)) + return false; + if (!update_interval_intersection(vd.mag_val, di)) + return false; + } + else if (nsk == LT) { + return false; + } + else if (nsk == GT) { + Domain_Interval di(am); + di.m_lower.set_num(0, 1); + if (!update_interval_intersection(vd.mag_val, di)) + return false; + } + else if (nsk == GE) { + return true; + } + else { + UNREACHABLE(); + } + } + else { + scoped_anum num(am); + am.root(frac, b, num); + if (nsk == EQ) { + Domain_Interval di(am); + di.set_num(num); + // di.m_lower_open = 0; + // di.m_upper_open = 0; + // di.m_lower_inf = 0; + // di.m_upper_inf = 0; + // am.set(di.m_lower, num); + // am.set(di.m_upper, num); + if (!update_interval_intersection(vd.mag_val, di)) + return false; + } + else if (nsk == LT) { + Domain_Interval di(am, 0, 0, 1, 0); + // [0, num) + am.set(di.m_lower.m_val, 0); + am.set(di.m_upper.m_val, num); + if (!update_interval_intersection(vd.mag_val, di)) + return false; + + // (-num, num) + di.m_lower.m_open = 1; + // am.set(di.m_upper, num); + am.neg(num); + am.set(di.m_lower.m_val, num); + if (!update_interval_intersection(vd.ori_val, di)) + return false; + } + else if (nsk == GT) { + // (num, inf) + Domain_Interval di(am, 1, 0, 1, 1); + // di.m_lower_open = 1; + // di.m_upper_open = 1; + // di.m_lower_inf = 0; + // di.m_upper_inf = 1; + am.set(di.m_lower.m_val, num); + if (!update_interval_intersection(vd.mag_val, di)) + return false; + } + else if (nsk == LE) { + Domain_Interval di(am, 0, 0, 0, 0); + // [0, num] + // di.m_lower_open = 0; + // di.m_upper_open = 0; + // di.m_lower_inf = 0; + // di.m_upper_inf = 0; + am.set(di.m_lower.m_val, 0); + am.set(di.m_upper.m_val, num); + if (!update_interval_intersection(vd.mag_val, di)) + return false; + // [-num, num] + // am.set(di.m_upper, num); + am.neg(num); + am.set(di.m_lower.m_val, num); + if (!update_interval_intersection(vd.ori_val, di)) + return false; + } + else if (nsk == GE) { + // [num, inf) + Domain_Interval di(am, 0, 0, 1, 1); + // di.m_lower_open = 0; + // di.m_upper_open = 1; + // di.m_lower_inf = 0; + // di.m_upper_inf = 1; + am.set(di.m_lower.m_val, num); + if (!update_interval_intersection(vd.mag_val, di)) + return false; + } + else { + UNREACHABLE(); + } + } + return true; + } + + bool update_var_domain(sign_kind nsk, const scoped_anum &a, var x, unsigned b, const scoped_anum &c) { + Var_Domain &vd = vars_domain[x]; + if (am.is_neg(a)) { + if (nsk == LT) + nsk = GT; + else if (nsk == GT) + nsk = LT; + else if (nsk == LE) + nsk = GE; + else if (nsk == GE) + nsk = LE; + } + if (nsk == NEQ) { + if (am.is_zero(c)) { + Domain_Interval di(am, 1, 0, 1, 1); + am.set(di.m_lower.m_val, 0); + return update_interval_intersection(vd.mag_val, di); + } + else { + return true; + } + } + if ((b & 1) == 1) + return process_odd_degree_formula(vd, nsk, a, b, c); + else + return process_even_degree_formula(vd, nsk, a, b, c); + } + + bool check_is_axbc(const poly *p, scoped_anum &a, var &x, unsigned &b, scoped_anum& c) { + // is a*(x^b) + c*1 form + if (pm.size(p) == 1 && pm.is_var(pm.get_monomial(p, 0), x)) { + am.set(a, 1); + b = 1; + am.set(c, 0); + return true; + } + if (pm.size(p) != 2) + return false; + if (!pm.is_unit(pm.get_monomial(p, 1))) + return false; + monomial *m = pm.get_monomial(p, 0); + if (pm.size(m) != 1) + return false; + x = pm.get_var(m, 0); + b = pm.degree(m, 0); + + am.set(a, pm.coeff(p, 0)); + am.set(c, pm.coeff(p, 1)); + return true; + } + + bool collect_domain_axbc_form(unsigned cid, unsigned lid) { + // is_var_num, a*(x^b) + c form + literal lit = (*clauses[cid])[lid]; + bool s = lit.sign(); + ineq_atom *ia = to_ineq_atom(atoms[lit.var()]); + if (ia->size() > 1) { + // clauses_visited[cid].visited = true; + return true; + } + poly *p = ia->p(0); + if (literal_special_kind[cid][lid] != UNK && + literal_special_kind[cid][lid] != AXBC) + return true; + var x; + scoped_anum a(am), c(am); + unsigned b; + + if (!check_is_axbc(p, a, x, b, c)) { + // vec_id.push_back(cid); + return true; + } + clauses_visited[cid].visited = true; + literal_special_kind[cid][lid] = AXBC; + sign_kind nsk = to_sign_kind(ia->get_kind()); + if (s) { + if (nsk == EQ) + nsk = NEQ; + else if (nsk == LT) + nsk = GE; + else if (nsk == GT) + nsk = LE; + } + TRACE("simple_checker", + tout << a << "x[" << x << "]^" << b << " + " << c << " "; + display(tout, nsk); + tout << " 0 \n"; + ); + if (!update_var_domain(nsk, a, x, b, c)) + return false; + TRACE("simple_checker", + tout << "original: "; + display(tout, am, vars_domain[x].ori_val); + tout << "\nmagnitude: "; + display(tout, am, vars_domain[x].mag_val); + tout << "\n"; + ); + return true; + } + bool check_is_axbsc(const poly *p, vector &as, vector &xs, vector &bs, scoped_anum& c, unsigned &cnt) { + // [a*(x^b)] + ... + [a*(x^b)] + c form + unsigned psz = pm.size(p); + am.set(c, 0); + for (unsigned i = 0; i < psz; ++i) { + monomial *m = pm.get_monomial(p, i); + if (pm.size(m) > 1) + return false; + } + cnt = 0; + for (unsigned i = 0; i < psz; ++i) { + monomial *m = pm.get_monomial(p, i); + if (pm.size(m) == 0) { + am.set(c, pm.coeff(p, i)); + } + else { + // as.push_back(scoped_anum(am)); + am.set(as[cnt++], pm.coeff(p, i)); + xs.push_back(pm.get_var(m, 0)); + bs.push_back(pm.degree(m, 0)); + } + } + return true; + } + + sign_kind get_axb_sign(const scoped_anum &a, var x, unsigned b) { + Var_Domain &vd = vars_domain[x]; + if (vd.ori_val.m_lower.is_zero() && + vd.ori_val.m_upper.is_zero()) + return EQ; + if ((b & 1) == 0) { + if (am.is_pos(a)) { // a > 0 + if (vd.mag_val.m_lower.is_zero(0)) + return GE; + else + return GT; + } + else { + if (vd.mag_val.m_lower.is_zero(0)) + return LE; + else + return LT; + } + } else { + sign_kind ret = NONE; + if (!vd.ori_val.m_lower.m_inf && !vd.ori_val.m_upper.m_inf) { + if (am.is_zero(vd.ori_val.m_lower.m_val)) { + if (vd.ori_val.m_lower.m_open) + ret = GT; + else + ret = GE; + } + else if (am.is_pos(vd.ori_val.m_lower.m_val)) { + ret = GT; + } + if (am.is_zero(vd.ori_val.m_upper.m_val)) { + if (vd.ori_val.m_upper.m_open) + ret = LT; + else + ret = LE; + } + else if (am.is_neg(vd.ori_val.m_upper.m_val)) { + ret = LT; + } + } + else if (!vd.ori_val.m_lower.m_inf) { + if (am.is_pos(vd.ori_val.m_lower.m_val)) { + ret = GT; + } + else if (am.is_zero(vd.ori_val.m_lower.m_val)) { + if (vd.ori_val.m_lower.m_open) + ret = GT; + else + ret = GE; + } + } + else if (!vd.ori_val.m_upper.m_inf) { + if (am.is_neg(vd.ori_val.m_upper.m_val)) { + ret = LT; + } + else if (am.is_zero(vd.ori_val.m_upper.m_val)) { + if (vd.ori_val.m_upper.m_open) + ret = LT; + else + ret = LE; + } + } + if (a < 0) { + if (ret == LT) + ret = GT; + else if (ret == LE) + ret = GE; + else if (ret == GT) + ret = LT; + else if (ret == GE) + ret = LE; + } + return ret; + } + } + + bool check_is_sign_ineq_consistent(sign_kind &nsk, vector &as, vector &xs, vector &bs, scoped_anum& c, bool &is_conflict) { + sign_kind sta = get_axb_sign(as[0], xs[0], bs[0]); + if (sta == NONE) + return false; + unsigned sz = as.size(); + for (unsigned i = 1; i < sz; ++i) { + sign_kind now = get_axb_sign(as[i], xs[i], bs[i]); + TRACE("simple_checker", + tout << "sta: "; + display(tout, sta); + tout << "\n"; + tout << "now: "; + display(tout, now); + tout << "\n"; + ); + if (now == NONE) + return false; + if (sta == EQ) { + sta = now; + } + else if (sta == LT || sta == LE) { + if (now != LT && now != LE) + return false; + if (sta != now) + sta = LT; + } + else { + if (now != GT && now != GE) + return false; + if (sta != now) + sta = GT; + } + TRACE("simple_checker", + tout << "after merge\n"; + tout << "sta: "; + display(tout, sta); + tout << "\n"; + ); + } + TRACE("simple_checker", + tout << "sta: "; + display(tout, sta); + tout << "\n"; + tout << "nsk: "; + display(tout, nsk); + tout << "\n"; + tout << "c: "; + am.display(tout, c); + tout << "\n"; + ); +/* +if (am.is_neg(c)) { // ( == 0) + (c < 0) -> < 0 + +} +else if (am.is_zero(c)) { // ( == 0) + (c == 0) -> == 0 + +} +else { // ( == 0) + (c > 0) -> > 0 + +} +*/ + if (sta == EQ) { + if (am.is_neg(c)) { // ( == 0) + (c < 0) -> < 0 + if (nsk == EQ || nsk == GE || nsk == GT) { + is_conflict = true; + return true; + } + else { + return false; + } + } + else if (am.is_zero(c)) { // ( == 0) + (c == 0) -> == 0 + if (nsk == GT || nsk == LT) { + is_conflict = true; + return true; + } + else { + return false; + } + } + else { // ( == 0) + (c > 0) -> > 0 + if (nsk == EQ || nsk == LE || nsk == LT) { + is_conflict = true; + return true; + } + else { + return false; + } + } + } + else if (sta == LT) { + if (am.is_neg(c)) { // ( < 0) + (c < 0) -> < 0 + if (nsk == EQ || nsk == GE || nsk == GT) { + is_conflict = true; + return true; + } + else { + return false; + } + } + else if (am.is_zero(c)) { // ( < 0) + (c == 0) -> < 0 + if (nsk == EQ || nsk == GE || nsk == GT) { + is_conflict = true; + return true; + } + else { + return false; + } + } + else { // [(t0 <= 0 + .. + tn <= 0) + (c > 0) >/>= 0] -> t > -c + if (nsk == LE || nsk == LT) + return false; + if (sz > 1 && nsk == EQ) + nsk = GE; + return true; + } + } + else if (sta == LE) { + if (am.is_neg(c)) { // ( <= 0) + (c < 0) -> < 0 + if (nsk == EQ || nsk == GE || nsk == GT) { + is_conflict = true; + return true; + } + else { + return false; + } + } + else if (am.is_zero(c)) { // ( <= 0) + (c == 0) -> <= 0 + if (nsk == GT) { + is_conflict = true; + return true; + } + else { + return false; + } + } + else { // [(t0 <= 0 + .. + tn <= 0) + (c > 0) >/>= 0] -> t > -c + if (nsk == LE || nsk == LT) + return false; + if (sz > 1 && nsk == EQ) + nsk = GE; + return true; + } + } + else if (sta == GT) { + if (am.is_neg(c)) { // [(t0 > 0 + .. + tn > 0) + (c < 0) t < -c + if (nsk == GE || nsk == GT) + return false; + if (sz > 1 && nsk == EQ) + nsk = LE; + return true; + } + else if (am.is_zero(c)) { // ( > 0) + (c == 0) -> > 0 + if (nsk == EQ || nsk == LE || nsk == LT) { + is_conflict = true; + return true; + } + else { + return false; + } + } + else { // (t > 0) + (c > 0) -> > 0 + if (nsk == EQ || nsk == LE || nsk == LT) { + is_conflict = true; + return true; + } + else { + return false; + } + } + } + else if (sta == GE) { + if (am.is_neg(c)) { // [(t0 >= 0 + .. + tn >= 0) + (c < 0) t < -c + if (nsk == GE || nsk == GT) + return false; + if (sz > 1 && nsk == EQ) + nsk = LE; + return true; + } + else if (am.is_zero(c)) { // ( >= 0) + (c == 0) -> >= 0 + if (nsk == LT) { + is_conflict = true; + return true; + } + else { + return false; + } + } + else { // (t >= 0) + (c > 0) -> > 0 + if (nsk == EQ || nsk == LE || nsk == LT) { + is_conflict = true; + return true; + } + else { + return false; + } + } + } + return false; + } + bool collect_domain_sign_ineq_consistent_form(sign_kind nsk, vector &as, vector &xs, vector &bs, scoped_anum& c) { + for (unsigned i = 0, sz = as.size(); i < sz; ++i) { + if (!update_var_domain(nsk, as[i], xs[i], bs[i], c)) + return false; + } + return true; + } + bool process_axbsc_form(sign_kind nsk, unsigned cid, vector &as, vector &xs, vector &bs, scoped_anum& c) { + bool is_conflict(false); + TRACE("simple_checker", + for (unsigned i = 0, sz = as.size(); i < sz; ++i) { + if (i > 0) + tout << "+ "; + tout << as[i] << "x[" << xs[i] << "]^" << bs[i] << " "; + } + tout << "+ " << c << " "; + display(tout, nsk); + tout << " 0\n"; + ); + if (!check_is_sign_ineq_consistent(nsk, as, xs, bs, c, is_conflict)) + return true; + TRACE("simple_checker", + tout << "is conflict: " << is_conflict << "\n" + ); + if (is_conflict) + return false; + clauses_visited[cid].visited = true; + if (!collect_domain_sign_ineq_consistent_form(nsk, as, xs, bs, c)) + return false; + return true; + } + bool collect_domain_axbsc_form(unsigned cid, unsigned lid) { + // [a*(x^k)] + ... + [a*(x^b)] + k form + literal lit = (*clauses[cid])[lid]; + bool s = lit.sign(); + ineq_atom *iat = to_ineq_atom(atoms[lit.var()]); + if (iat->size() > 1) + return true; + if (literal_special_kind[cid][lid] != UNK && + literal_special_kind[cid][lid] != AXBSC) + return true; + + poly *p = iat->p(0); + vector as; + for (unsigned i = 0, sz = pm.size(p); i < sz; ++i) { + as.push_back(scoped_anum(am)); + } + vector xs; + vector bs; + scoped_anum c(am); + unsigned cnt; + if (!check_is_axbsc(p, as, xs, bs, c, cnt)) { + literal_special_kind[cid][lid] = NK; + return true; + } + literal_special_kind[cid][lid] = AXBSC; + TRACE("simple_checker", + tout << "as size: " << as.size() << '\n'; + ); + while (as.size() > cnt) + as.pop_back(); + + sign_kind nsk = to_sign_kind(iat->get_kind()); + if (s) { + if (nsk == EQ) + return true; + else if (nsk == LT) + nsk = GE; + else if (nsk == GT) + nsk = LE; + } + TRACE("simple_checker", + tout << "ineq atom: " << '\n'; + for (unsigned i = 0, sz = iat->size(); i < sz; ++i) { + pm.display(tout, iat->p(i)); + tout << " is even: " << iat->is_even(i) << "\n"; + } + display(tout, nsk); + tout << " 0\n"; + tout << "\n"; + tout << "as size: " << as.size() << '\n'; + for (unsigned i = 0, sz = as.size(); i < sz; ++i) { + if (i > 0) + tout << "+ "; + tout << as[i] << "x[" << xs[i] << "]^" << bs[i] << " "; + } + tout << "+ " << c << " "; + display(tout, nsk); + tout << " 0\n"; + ); + if (!process_axbsc_form(nsk, cid, as, xs, bs, c)) + return false; + return true; + } + + bool collect_var_domain() { + // vector vec_id; + for (unsigned i = 0, sz = clauses.size(); i < sz; ++i) { + if (clauses_visited[i].visited) + continue; + if (clauses[i]->size() > 1) + continue; + literal lit = (*clauses[i])[0]; + atom *tmp_atom = atoms[lit.var()]; + if (tmp_atom == nullptr) { + clauses_visited[i].visited = true; + continue; + } + if (!tmp_atom->is_ineq_atom()) { + clauses_visited[i].visited = true; + continue; + } + ineq_atom *tmp_ineq_atom = to_ineq_atom(tmp_atom); + if (tmp_ineq_atom->size() > 1) + continue; + if (!collect_domain_axbc_form(i, 0)) + return false; + } + TRACE("simple_checker", + for (unsigned i = 0; i < arith_var_num; ++i) { + tout << "====== arith[" << i << "] ======\n"; + tout << "original value: "; + display(tout, am, vars_domain[i].ori_val); + tout << "\nmagitude value: "; + display(tout, am, vars_domain[i].mag_val); + tout << "\n"; + tout << "====== arith[" << i << "] ======\n"; + } + ); + for (unsigned i = 0, sz = clauses.size(); i < sz; ++i) { + // unsigned id = vec_id[i]; + if (!collect_domain_axbsc_form(i, 0)) + return false; + } + return true; + } + void endpoint_multiply(const Endpoint &a, const Endpoint &b, Endpoint &c) { + if (a.is_zero() || b.is_zero()) { + c.set_num(0, 0); + return ; + } + bool a_neg = a.is_neg(), b_neg = b.is_neg(); + if (a.m_inf || b.m_inf) { + c.m_inf = 1; + c.m_open = 1; + if (a_neg == b_neg) + c.m_is_lower = 0; + else + c.m_is_lower = 1; + } + else { + c.m_inf = 0; + c.m_open = (a.m_open | b.m_open); + am.set(c.m_val, a.m_val*b.m_val); + } + } + void get_max_min_endpoint(const ptr_vector &pev, Endpoint *&pmi, Endpoint *&pmx) { + pmi = pmx = pev[0]; + for (unsigned i = 1, sz = pev.size(); i < sz; ++i) { + if (*pmx < *pev[i]) + pmx = pev[i]; + if (*pev[i] < *pmi) + pmi = pev[i]; + } + } + void merge_mul_domain(Domain_Interval &pre, const Domain_Interval &now) { + TRACE("simple_checker", + tout << "dom: "; + display(tout, am, pre); + tout << "\n"; + tout << "di: "; + display(tout, am, now); + tout << "\n"; + ); + Endpoint plnl(am), plnu(am), punl(am), punu(am); + endpoint_multiply(pre.m_lower, now.m_lower, plnl); + endpoint_multiply(pre.m_lower, now.m_upper, plnu); + endpoint_multiply(pre.m_upper, now.m_lower, punl); + endpoint_multiply(pre.m_upper, now.m_upper, punu); + ptr_vector pev; + pev.push_back(&plnl); + pev.push_back(&plnu); + pev.push_back(&punl); + pev.push_back(&punu); + Endpoint *pmi, *pmx; + get_max_min_endpoint(pev, pmi, pmx); + pre.m_lower.copy(*pmi); + pre.m_lower.m_is_lower = 1; + pre.m_upper.copy(*pmx); + pre.m_upper.m_is_lower = 0; + } + + void get_monomial_domain(monomial *m, const scoped_anum &a, Domain_Interval &dom) { + TRACE("simple_checker", + tout << "monomial: "; + pm.display(tout, m); + tout << '\n'; + tout << "coefficient: " << a << "\n"; + tout << "# "; + for (unsigned i = 0, sz = pm.size(m); i < sz; ++i) { + var v = pm.get_var(m, i); + tout << " (" << i << ", " << pm.degree_of(m, v) << ")"; + } + tout << "\n"; + ); + + // [a, a] + dom.set_num(a); + for (unsigned i = 0, sz = pm.size(m); i < sz; ++i) { + var v = pm.get_var(m, i); + unsigned deg = pm.degree_of(m, v); + const Domain_Interval &di = ((deg & 1) == 0 ? vars_domain[v].mag_val : vars_domain[v].ori_val); + TRACE("simple_checker", + tout << "dom: "; + display(tout, am, dom); + tout << "\n"; + tout << "var: " << v; + tout << ", di: "; + display(tout, am, di); + tout << "\n"; + ); + for (unsigned j = 0; j < deg; ++j) { + merge_mul_domain(dom, di); + } + TRACE("simple_checker", + tout << "after merge mul: "; + display(tout, am, dom); + tout << "\n"; + ); + // mul 0 + // if (dom.m_lower_inf && dom.m_upper_inf) + // return ; + } + } + void endpoint_add(Endpoint &a, const Endpoint &b) { + a.m_inf = (a.m_inf | b.m_inf); + if (a.m_inf == 0) { + am.set(a.m_val, a.m_val + b.m_val); + a.m_open = (a.m_open | b.m_open); + } + } + + void merge_add_domain(Domain_Interval &pre, const Domain_Interval &now) { + endpoint_add(pre.m_lower, now.m_lower); + endpoint_add(pre.m_upper, now.m_upper); + } + + sign_kind get_poly_sign(const poly *p) { + scoped_anum a(am); + am.set(a, pm.coeff(p, 0)); + Domain_Interval pre(am); + get_monomial_domain(pm.get_monomial(p, 0), a, pre); + TRACE("simple_checker", + tout << "poly: "; + pm.display(tout, p); + tout << "\n"; + ); + TRACE("simple_checker", + tout << "pre: "; + display(tout, am, pre); + tout << "\n"; + ); + for (unsigned i = 1, sz = pm.size(p); i < sz; ++i) { + am.set(a, pm.coeff(p, i)); + Domain_Interval now(am); + get_monomial_domain(pm.get_monomial(p, i), a, now); + TRACE("simple_checker", + tout << "pre: "; + display(tout, am, pre); + tout << "\n"; + tout << "now: "; + display(tout, am, now); + tout << "\n"; + ); + if (now.m_lower.m_inf && now.m_upper.m_inf) + return NONE; + merge_add_domain(pre, now); + TRACE("simple_checker", + tout << "after merge: "; + display(tout, am, pre); + tout << "\n"; + ); + if (pre.m_lower.m_inf && pre.m_upper.m_inf) + return NONE; + } + if (pre.m_lower.m_inf) { + if (am.is_neg(pre.m_upper.m_val)) { + // (-inf, -} + return LT; + } + else if (am.is_zero(pre.m_upper.m_val)) { + // (-inf, 0} + if (pre.m_upper.m_open) + return LT; + else + return LE; + } + else { + // (-inf, +} + return NONE; + } + } + else if (pre.m_upper.m_inf) { + if (am.is_neg(pre.m_lower.m_val)) { + // {-, +inf) + return NONE; + } + else if (am.is_zero(pre.m_lower.m_val)) { + // {0, +inf) + if (pre.m_lower.m_open) + return GT; + else + return GE; + } + else { + // {+, +inf) + return GT; + } + } + else { + // [0, 0] + if (am.is_zero(pre.m_lower.m_val) && am.is_zero(pre.m_upper.m_val)) + return EQ; + else if (am.is_zero(pre.m_lower.m_val)) { + // {0, +} + if (pre.m_lower.m_open) + return GT; + else + return GE; + } + else if (am.is_zero(pre.m_upper.m_val)) { + // {-, 0} + if (pre.m_upper.m_open) + return LT; + else + return LE; + } + else { + if (am.is_pos(pre.m_lower.m_val)) + return GT; + else if (am.is_neg(pre.m_upper.m_val)) + return LT; + else + return NONE; + } + } + return NONE; + } + + sign_kind get_poly_sign_degree(const poly *p, bool is_even) { + sign_kind ret = get_poly_sign(p); + if (is_even) { + if (ret == GE || ret == LE || ret == NONE) + ret = GE; + else if (ret != EQ) + ret = GT; + } + TRACE("simple_checker", + tout << "ret sign: "; + display(tout, ret); + tout << "\n"; + tout << "is even: " << is_even << "\n"; + ); + return ret; + } + void merge_mul_sign(sign_kind &pre, sign_kind now) { + if (pre == EQ) + return ; + if (now == EQ) { + pre = EQ; + return ; + } + if (pre == NONE) + return ; + + if (now == NONE) { + pre = NONE; + } + // else if (now == EQ) { + // pre = EQ; + // } + else if (now == LT) { + if (pre == GE) + pre = LE; + else if (pre == GT) + pre = LT; + else if (pre == LE) + pre = GE; + else if (pre == LT) + pre = GT; + } + else if (now == GT) { + // if (pre == LE) + // pre = LE; + // else if (pre == LT) + // pre = LT; + // else if (pre == GT) + // pre = GT; + // else if (pre == GE) + // pre = GE; + } + else if (now == LE) { + if (pre == GE) + pre = LE; + else if (pre == GT) + pre = LE; + else if (pre == LE) + pre = GE; + else if (pre == LT) + pre = GE; + } + else if (now == GE) { + // if (pre == LE) + // pre = LE; + if (pre == LT) + pre = LE; + else if (pre == GT) + pre = GE; + // else if (pre == GE) + // pre = GE; + } + } + bool check_ineq_atom_satisfiable(const ineq_atom *iat, bool s) { + TRACE("simple_checker", + tout << "s: " << s << "\n"; + tout << "kd: " << iat->get_kind() << "\n"; + ); + sign_kind nsk = to_sign_kind(iat->get_kind()); + if (s) { + if (nsk == EQ) + return true; + else if (nsk == GT) + nsk = LE; + else + nsk = GE; + } + TRACE("simple_checker", + tout << "ineq atom: " << '\n'; + for (unsigned i = 0, sz = iat->size(); i < sz; ++i) { + pm.display(tout, iat->p(i)); + tout << " is even: " << iat->is_even(i) << "\n"; + } + display(tout, nsk); + tout << " 0\n"; + ); + // return true; + + sign_kind pre = get_poly_sign_degree(iat->p(0), iat->is_even(0)); + + for (unsigned i = 1, sz = iat->size(); i < sz; ++i) { + sign_kind now = get_poly_sign_degree(iat->p(i), iat->is_even(i)); + merge_mul_sign(pre, now); + if (pre == NONE) + return true; + if ((nsk == EQ || nsk == GE || nsk == LE) && + (pre == EQ || pre == GE || pre == LE)) + return true; + } + TRACE("simple_checker", + tout << "pre: "; + display(tout, pre); + tout << ", nsk: "; + display(tout, nsk); + tout << "\n"; + ); + if (pre == NONE) + return true; + if (pre == EQ && (nsk == LT || nsk == GT)) + return false; + if (pre == GE && nsk == LT) + return false; + if (pre == GT && (nsk == LT || nsk == LE || nsk == EQ)) + return false; + if (pre == LE && nsk == GT) + return false; + if (pre == LT && (nsk == GT || nsk == GE || nsk == EQ)) + return false; + return true; + } + bool check_literal_satisfiable(unsigned cid, unsigned lit_id) { + literal lit = (*clauses[cid])[lit_id]; + const var &v = lit.var(); + atom *at = atoms[v]; + if (at == nullptr) { + clauses_visited[cid].visited = true; + return true; + } + if (!at->is_ineq_atom()) { + clauses_visited[cid].visited = true; + return true; + } + // TRACE("sign", + // tout << "literal: " << lit << '\n'; + // ); + bool s = lit.sign(); + return check_ineq_atom_satisfiable(to_ineq_atom(at), s); + } + bool check_clause_satisfiable(unsigned cid) { + const clause *cla = clauses[cid]; + TRACE("simple_checker", + tout << "clause size: " << cla->size() << '\n'; + ); + unsigned sz = cla->size(); + if (clauses_visited[cid].literal_visited.size() == 0) { + clauses_visited[cid].literal_visited.resize(sz, false); + literal_special_kind[cid].resize(sz, UNK); + } + unsigned sat_lit_id = sz; + for (unsigned i = 0; i < sz; ++i) { + if (clauses_visited[cid].literal_visited[i]) + continue; + if (check_literal_satisfiable(cid, i)) { + if (clauses_visited[cid].visited) + return true; + if (sat_lit_id == sz) + sat_lit_id = i; + else + return true; + } else { + clauses_visited[cid].literal_visited[i] = true; + literal lit = (*clauses[cid])[i]; + lit.neg(); + learned_unit.push_back(lit); + TRACE("simple_checker_learned", + tout << "making new clauses!\n"; + tout << "sign: " << lit.sign() << '\n'; + if (atoms[lit.var()] != nullptr && atoms[lit.var()]->is_ineq_atom()) { + ineq_atom *iat = to_ineq_atom(atoms[lit.var()]); + tout << "ineq atom: " << '\n'; + sign_kind nsk = to_sign_kind(iat->get_kind()); + for (unsigned i = 0, sz = iat->size(); i < sz; ++i) { + pm.display(tout, iat->p(i)); + tout << " is even: " << iat->is_even(i) << "\n"; + } + display(tout, nsk); + tout << " 0\n"; + } + ); + } + } + if (sat_lit_id != sz) { + if (!collect_domain_axbc_form(cid, sat_lit_id)) + return false; + if (!collect_domain_axbsc_form(cid, sat_lit_id)) + return false; + return true; + } + return false; + } + bool check() { + for (unsigned i = 0, sz = clauses.size(); i < sz; ++i) { + if (clauses_visited[i].visited) + continue; + if (!check_clause_satisfiable(i)) { + return false; + } + } + return true; + } + bool operator()() { + + improved = true; + while (improved) { + improved = false; + if (!check()) + return false; + TRACE("simple_checker", + for (unsigned i = 0; i < arith_var_num; ++i) { + tout << "====== arith[" << i << "] ======\n"; + tout << "original value: "; + display(tout, am, vars_domain[i].ori_val); + tout << "\nmagitude value: "; + display(tout, am, vars_domain[i].mag_val); + tout << "\n"; + tout << "====== arith[" << i << "] ======\n"; + } + ); + } + return true; + } + }; + simple_checker::simple_checker(pmanager &_pm, anum_manager &_am, const clause_vector &_clauses, literal_vector &_learned_unit, const atom_vector &_atoms, const unsigned &_arith_var_num) { + m_imp = alloc(imp, _pm, _am, _clauses, _learned_unit, _atoms, _arith_var_num); + } + simple_checker::~simple_checker() { + dealloc(m_imp); + } + bool simple_checker::operator()() { + return m_imp->operator()(); + } +} diff --git a/src/nlsat/nlsat_simple_checker.h b/src/nlsat/nlsat_simple_checker.h new file mode 100644 index 000000000..c13e2669c --- /dev/null +++ b/src/nlsat/nlsat_simple_checker.h @@ -0,0 +1,33 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + nlsat_simple_checker.cpp + +Abstract: + + Attempts to find a conflict by using simple polynomial forms. +Author: + + Mengyu Zhao (Linxi) and Shaowei Cai + +Revision History: + +--*/ + +#pragma once +#include "math/polynomial/algebraic_numbers.h" +#include "nlsat/nlsat_clause.h" + + +namespace nlsat { + class simple_checker { + struct imp; + imp * m_imp; + public: + simple_checker(pmanager &_pm, anum_manager &_am, const clause_vector &_clauses, literal_vector &_learned_unit, const atom_vector &_atoms, const unsigned &_arith_var_num); + ~simple_checker(); + bool operator()(); + }; +} \ No newline at end of file diff --git a/src/nlsat/nlsat_simplify.cpp b/src/nlsat/nlsat_simplify.cpp index 8148d721f..d483a0391 100644 --- a/src/nlsat/nlsat_simplify.cpp +++ b/src/nlsat/nlsat_simplify.cpp @@ -93,7 +93,6 @@ namespace nlsat { } void update_clauses(u_map const& b2l) { - bool is_sat = true; literal_vector lits; unsigned n = m_clauses.size(); @@ -141,6 +140,8 @@ namespace nlsat { auto& a = *to_ineq_atom(a1); if (a.size() != 2) continue; + if (a.is_root_atom()) + continue; auto* p = a.p(0); auto* q = a.p(1); @@ -229,6 +230,10 @@ namespace nlsat { } break; } + default: + SASSERT(a.is_root_atom()); + UNREACHABLE(); + break; } IF_VERBOSE(3, s.display(verbose_stream(), c) << " ->\n"; diff --git a/src/nlsat/nlsat_solver.cpp b/src/nlsat/nlsat_solver.cpp index bb169a05e..53d7d9fe7 100644 --- a/src/nlsat/nlsat_solver.cpp +++ b/src/nlsat/nlsat_solver.cpp @@ -1,4027 +1,4134 @@ -/*++ -Copyright (c) 2012 Microsoft Corporation - -Module Name: - - nlsat_solver.cpp - -Abstract: - - Nonlinear arithmetic satisfiability procedure. The procedure is - complete for nonlinear real arithmetic, but it also has limited - support for integers. - -Author: - - Leonardo de Moura (leonardo) 2012-01-02. - -Revision History: - ---*/ -#include "util/z3_exception.h" -#include "util/chashtable.h" -#include "util/id_gen.h" -#include "util/map.h" -#include "util/dependency.h" -#include "util/permutation.h" -#include "math/polynomial/algebraic_numbers.h" -#include "math/polynomial/polynomial_cache.h" -#include "nlsat/nlsat_solver.h" -#include "nlsat/nlsat_clause.h" -#include "nlsat/nlsat_assignment.h" -#include "nlsat/nlsat_justification.h" -#include "nlsat/nlsat_evaluator.h" -#include "nlsat/nlsat_explain.h" -#include "nlsat/nlsat_params.hpp" -#include "nlsat/nlsat_simplify.h" - -#define NLSAT_EXTRA_VERBOSE - -#ifdef NLSAT_EXTRA_VERBOSE -#define NLSAT_VERBOSE(CODE) IF_VERBOSE(10, CODE) -#else -#define NLSAT_VERBOSE(CODE) ((void)0) -#endif - -namespace nlsat { - - - typedef chashtable ineq_atom_table; - typedef chashtable root_atom_table; - - // for apply_permutation procedure - void swap(clause * & c1, clause * & c2) noexcept { - std::swap(c1, c2); - } - - struct solver::ctx { - params_ref m_params; - reslimit& m_rlimit; - small_object_allocator m_allocator; - unsynch_mpq_manager m_qm; - pmanager m_pm; - anum_manager m_am; - bool m_incremental; - ctx(reslimit& rlim, params_ref const & p, bool incremental): - m_params(p), - m_rlimit(rlim), - m_allocator("nlsat"), - m_pm(rlim, m_qm, &m_allocator), - m_am(rlim, m_qm, p, &m_allocator), - m_incremental(incremental) - {} - }; - - struct solver::imp { - - - struct dconfig { - typedef imp value_manager; - typedef small_object_allocator allocator; - typedef void* value; - static const bool ref_count = false; - }; - - typedef dependency_manager assumption_manager; - typedef assumption_manager::dependency* _assumption_set; - - typedef obj_ref assumption_set_ref; - - - typedef polynomial::cache cache; - typedef ptr_vector interval_set_vector; - - - - ctx& m_ctx; - solver& m_solver; - reslimit& m_rlimit; - small_object_allocator& m_allocator; - bool m_incremental; - unsynch_mpq_manager& m_qm; - pmanager& m_pm; - cache m_cache; - anum_manager& m_am; - mutable assumption_manager m_asm; - assignment m_assignment, m_lo, m_hi; // partial interpretation - evaluator m_evaluator; - interval_set_manager & m_ism; - ineq_atom_table m_ineq_atoms; - root_atom_table m_root_atoms; - - - vector m_bounds; - - id_gen m_cid_gen; - clause_vector m_clauses; // set of clauses - clause_vector m_learned; // set of learned clauses - clause_vector m_valids; - - unsigned m_num_bool_vars; - atom_vector m_atoms; // bool_var -> atom - svector m_bvalues; // boolean assignment - unsigned_vector m_levels; // bool_var -> level - svector m_justifications; - vector m_bwatches; // bool_var (that are not attached to atoms) -> clauses where it is maximal - bool_vector m_dead; // mark dead boolean variables - id_gen m_bid_gen; - - simplify m_simplify; - - bool_vector m_is_int; // m_is_int[x] is true if variable is integer - vector m_watches; // var -> clauses where variable is maximal - interval_set_vector m_infeasible; // var -> to a set of interval where the variable cannot be assigned to. - atom_vector m_var2eq; // var -> to asserted equality - var_vector m_perm; // var -> var permutation of the variables - var_vector m_inv_perm; - // m_perm: internal -> external - // m_inv_perm: external -> internal - struct perm_display_var_proc : public display_var_proc { - var_vector & m_perm; - display_var_proc m_default_display_var; - display_var_proc const * m_proc; // display external var ids - perm_display_var_proc(var_vector & perm): - m_perm(perm), - m_proc(nullptr) { - } - std::ostream& operator()(std::ostream & out, var x) const override { - if (m_proc == nullptr) - m_default_display_var(out, x); - else - (*m_proc)(out, m_perm[x]); - return out; - } - }; - perm_display_var_proc m_display_var; - - display_assumption_proc const* m_display_assumption; - struct display_literal_assumption : public display_assumption_proc { - imp& i; - literal_vector const& lits; - display_literal_assumption(imp& i, literal_vector const& lits): i(i), lits(lits) {} - std::ostream& operator()(std::ostream& out, assumption a) const override { - if (lits.begin() <= a && a < lits.end()) { - out << *((literal const*)a); - } - else if (i.m_display_assumption) { - (*i.m_display_assumption)(out, a); - } - return out; - } - - }; - struct scoped_display_assumptions { - imp& i; - display_assumption_proc const* m_save; - scoped_display_assumptions(imp& i, display_assumption_proc const& p): i(i), m_save(i.m_display_assumption) { - i.m_display_assumption = &p; - } - ~scoped_display_assumptions() { - i.m_display_assumption = m_save; - } - }; - - explain m_explain; - - bool_var m_bk; // current Boolean variable we are processing - var m_xk; // current arith variable we are processing - - unsigned m_scope_lvl; - - struct bvar_assignment {}; - struct stage {}; - struct trail { - enum kind { BVAR_ASSIGNMENT, INFEASIBLE_UPDT, NEW_LEVEL, NEW_STAGE, UPDT_EQ }; - kind m_kind; - union { - bool_var m_b; - interval_set * m_old_set; - atom * m_old_eq; - }; - trail(bool_var b, bvar_assignment):m_kind(BVAR_ASSIGNMENT), m_b(b) {} - trail(interval_set * old_set):m_kind(INFEASIBLE_UPDT), m_old_set(old_set) {} - trail(bool s, stage):m_kind(s ? NEW_STAGE : NEW_LEVEL) {} - trail(atom * a):m_kind(UPDT_EQ), m_old_eq(a) {} - }; - svector m_trail; - - anum m_zero; - - // configuration - unsigned long long m_max_memory; - unsigned m_lazy; // how lazy the solver is: 0 - satisfy all learned clauses, 1 - process only unit and empty learned clauses, 2 - use only conflict clauses for resolving conflicts - bool m_simplify_cores; - bool m_reorder; - bool m_randomize; - bool m_random_order; - unsigned m_random_seed; - bool m_inline_vars; - bool m_log_lemmas; - bool m_check_lemmas; - unsigned m_max_conflicts; - unsigned m_lemma_count; - - struct stats { - unsigned m_simplifications; - unsigned m_restarts; - unsigned m_conflicts; - unsigned m_propagations; - unsigned m_decisions; - unsigned m_stages; - unsigned m_irrational_assignments; // number of irrational witnesses - void reset() { memset(this, 0, sizeof(*this)); } - stats() { reset(); } - }; - // statistics - stats m_stats; - - imp(solver& s, ctx& c): - m_ctx(c), - m_solver(s), - m_rlimit(c.m_rlimit), - m_allocator(c.m_allocator), - m_incremental(c.m_incremental), - m_qm(c.m_qm), - m_pm(c.m_pm), - m_cache(m_pm), - m_am(c.m_am), - m_asm(*this, m_allocator), - m_assignment(m_am), m_lo(m_am), m_hi(m_am), - m_evaluator(s, m_assignment, m_pm, m_allocator), - m_ism(m_evaluator.ism()), - m_num_bool_vars(0), - m_simplify(s, m_atoms, m_clauses, m_learned, m_pm), - m_display_var(m_perm), - m_display_assumption(nullptr), - m_explain(s, m_assignment, m_cache, m_atoms, m_var2eq, m_evaluator), - m_scope_lvl(0), - m_lemma(s), - m_lazy_clause(s), - m_lemma_assumptions(m_asm) { - updt_params(c.m_params); - reset_statistics(); - mk_true_bvar(); - m_lemma_count = 0; - } - - ~imp() { - clear(); - } - - void mk_true_bvar() { - bool_var b = mk_bool_var(); - SASSERT(b == true_bool_var); - literal true_lit(b, false); - mk_clause(1, &true_lit, false, nullptr); - } - - void updt_params(params_ref const & _p) { - nlsat_params p(_p); - m_max_memory = p.max_memory(); - m_lazy = p.lazy(); - m_simplify_cores = p.simplify_conflicts(); - bool min_cores = p.minimize_conflicts(); - m_reorder = p.reorder(); - m_randomize = p.randomize(); - m_max_conflicts = p.max_conflicts(); - m_random_order = p.shuffle_vars(); - m_random_seed = p.seed(); - m_inline_vars = p.inline_vars(); - m_log_lemmas = p.log_lemmas(); - m_check_lemmas = p.check_lemmas(); - m_ism.set_seed(m_random_seed); - m_explain.set_simplify_cores(m_simplify_cores); - m_explain.set_minimize_cores(min_cores); - m_explain.set_factor(p.factor()); - m_am.updt_params(p.p); - } - - void reset() { - m_explain.reset(); - m_lemma.reset(); - m_lazy_clause.reset(); - undo_until_size(0); - del_clauses(); - del_unref_atoms(); - m_cache.reset(); - m_assignment.reset(); - m_lo.reset(); - m_hi.reset(); - } - - void clear() { - m_explain.reset(); - m_lemma.reset(); - m_lazy_clause.reset(); - undo_until_size(0); - del_clauses(); - del_unref_atoms(); - } - - void checkpoint() { - if (!m_rlimit.inc()) throw solver_exception(m_rlimit.get_cancel_msg()); - if (memory::get_allocation_size() > m_max_memory) throw solver_exception(Z3_MAX_MEMORY_MSG); - } - - // ----------------------- - // - // Basic - // - // ----------------------- - - unsigned num_bool_vars() const { - return m_num_bool_vars; - } - - unsigned num_vars() const { - return m_is_int.size(); - } - - bool is_int(var x) const { - return m_is_int[x]; - } - - void inc_ref(assumption) {} - - void dec_ref(assumption) {} - - void inc_ref(_assumption_set a) { - if (a != nullptr) m_asm.inc_ref(a); - } - - void dec_ref(_assumption_set a) { - if (a != nullptr) m_asm.dec_ref(a); - } - - void inc_ref(bool_var b) { - if (b == null_bool_var) - return; - atom * a = m_atoms[b]; - if (a == nullptr) - return; - TRACE("ref", display(tout << "inc: " << b << " " << a->ref_count() << " ", *a) << "\n";); - a->inc_ref(); - } - - void inc_ref(literal l) { - inc_ref(l.var()); - } - - void dec_ref(bool_var b) { - if (b == null_bool_var) - return; - atom * a = m_atoms[b]; - if (a == nullptr) - return; - SASSERT(a->ref_count() > 0); - a->dec_ref(); - TRACE("ref", display(tout << "dec: " << b << " " << a->ref_count() << " ", *a) << "\n";); - if (a->ref_count() == 0) - del(a); - } - - void dec_ref(literal l) { - dec_ref(l.var()); - } - - bool is_arith_atom(bool_var b) const { return m_atoms[b] != nullptr; } - - bool is_arith_literal(literal l) const { return is_arith_atom(l.var()); } - - var max_var(poly const * p) const { - return m_pm.max_var(p); - } - - var max_var(bool_var b) const { - if (!is_arith_atom(b)) - return null_var; - else - return m_atoms[b]->max_var(); - } - - var max_var(literal l) const { - return max_var(l.var()); - } - - /** - \brief Return the maximum variable occurring in cls. - */ - var max_var(unsigned sz, literal const * cls) const { - var x = null_var; - for (unsigned i = 0; i < sz; i++) { - literal l = cls[i]; - if (is_arith_literal(l)) { - var y = max_var(l); - if (x == null_var || y > x) - x = y; - } - } - return x; - } - - var max_var(clause const & cls) const { - return max_var(cls.size(), cls.data()); - } - - /** - \brief Return the maximum Boolean variable occurring in cls. - */ - bool_var max_bvar(clause const & cls) const { - bool_var b = null_bool_var; - for (literal l : cls) { - if (b == null_bool_var || l.var() > b) - b = l.var(); - } - return b; - } - - /** - \brief Return the degree of the maximal variable of the given atom - */ - unsigned degree(atom const * a) const { - if (a->is_ineq_atom()) { - unsigned max = 0; - unsigned sz = to_ineq_atom(a)->size(); - var x = a->max_var(); - for (unsigned i = 0; i < sz; i++) { - unsigned d = m_pm.degree(to_ineq_atom(a)->p(i), x); - if (d > max) - max = d; - } - return max; - } - else { - return m_pm.degree(to_root_atom(a)->p(), a->max_var()); - } - } - - /** - \brief Return the degree of the maximal variable in c - */ - unsigned degree(clause const & c) const { - var x = max_var(c); - if (x == null_var) - return 0; - unsigned max = 0; - for (literal l : c) { - atom const * a = m_atoms[l.var()]; - if (a == nullptr) - continue; - unsigned d = degree(a); - if (d > max) - max = d; - } - return max; - } - - // ----------------------- - // - // Variable, Atoms, Clauses & Assumption creation - // - // ----------------------- - - bool_var mk_bool_var_core() { - bool_var b = m_bid_gen.mk(); - m_num_bool_vars++; - m_atoms .setx(b, nullptr, nullptr); - m_bvalues .setx(b, l_undef, l_undef); - m_levels .setx(b, UINT_MAX, UINT_MAX); - m_justifications.setx(b, null_justification, null_justification); - m_bwatches .setx(b, clause_vector(), clause_vector()); - m_dead .setx(b, false, true); - return b; - } - - bool_var mk_bool_var() { - return mk_bool_var_core(); - } - - var mk_var(bool is_int) { - var x = m_pm.mk_var(); - register_var(x, is_int); - return x; - } - void register_var(var x, bool is_int) { - SASSERT(x == num_vars()); - m_is_int. push_back(is_int); - m_watches. push_back(clause_vector()); - m_infeasible.push_back(nullptr); - m_var2eq. push_back(nullptr); - m_perm. push_back(x); - m_inv_perm. push_back(x); - SASSERT(m_is_int.size() == m_watches.size()); - SASSERT(m_is_int.size() == m_infeasible.size()); - SASSERT(m_is_int.size() == m_var2eq.size()); - SASSERT(m_is_int.size() == m_perm.size()); - SASSERT(m_is_int.size() == m_inv_perm.size()); - } - - bool_vector m_found_vars; - void vars(literal l, var_vector& vs) { - vs.reset(); - atom * a = m_atoms[l.var()]; - if (a == nullptr) { - - } - else if (a->is_ineq_atom()) { - unsigned sz = to_ineq_atom(a)->size(); - var_vector new_vs; - for (unsigned j = 0; j < sz; j++) { - m_found_vars.reset(); - m_pm.vars(to_ineq_atom(a)->p(j), new_vs); - for (unsigned i = 0; i < new_vs.size(); ++i) { - if (!m_found_vars.get(new_vs[i], false)) { - m_found_vars.setx(new_vs[i], true, false); - vs.push_back(new_vs[i]); - } - } - } - } - else { - m_pm.vars(to_root_atom(a)->p(), vs); - //vs.erase(max_var(to_root_atom(a)->p())); - vs.push_back(to_root_atom(a)->x()); - } - } - - void deallocate(ineq_atom * a) { - unsigned obj_sz = ineq_atom::get_obj_size(a->size()); - a->~ineq_atom(); - m_allocator.deallocate(obj_sz, a); - } - - void deallocate(root_atom * a) { - a->~root_atom(); - m_allocator.deallocate(sizeof(root_atom), a); - } - - void del(bool_var b) { - SASSERT(m_bwatches[b].empty()); - //SASSERT(m_bvalues[b] == l_undef); - m_num_bool_vars--; - m_dead[b] = true; - m_atoms[b] = nullptr; - m_bvalues[b] = l_undef; - m_bid_gen.recycle(b); - } - - void del(ineq_atom * a) { - CTRACE("nlsat_solver", a->ref_count() > 0, display(tout, *a) << "\n";); - // this triggers in too many benign cases: - // SASSERT(a->ref_count() == 0); - m_ineq_atoms.erase(a); - del(a->bvar()); - unsigned sz = a->size(); - for (unsigned i = 0; i < sz; i++) - m_pm.dec_ref(a->p(i)); - deallocate(a); - } - - void del(root_atom * a) { - SASSERT(a->ref_count() == 0); - m_root_atoms.erase(a); - del(a->bvar()); - m_pm.dec_ref(a->p()); - deallocate(a); - } - - void del(atom * a) { - if (a == nullptr) - return; - TRACE("nlsat_verbose", display(tout << "del: b" << a->m_bool_var << " " << a->ref_count() << " ", *a) << "\n";); - if (a->is_ineq_atom()) - del(to_ineq_atom(a)); - else - del(to_root_atom(a)); - } - - // Delete atoms with ref_count == 0 - void del_unref_atoms() { - for (auto* a : m_atoms) { - del(a); - } - } - - - ineq_atom* mk_ineq_atom(atom::kind k, unsigned sz, poly * const * ps, bool const * is_even, bool& is_new, bool simplify) { - SASSERT(sz >= 1); - SASSERT(k == atom::LT || k == atom::GT || k == atom::EQ); - int sign = 1; - polynomial_ref p(m_pm); - ptr_buffer uniq_ps; - var max = null_var; - for (unsigned i = 0; i < sz; i++) { - p = m_pm.flip_sign_if_lm_neg(ps[i]); - if (p.get() != ps[i] && !is_even[i]) { - sign = -sign; - } - var curr_max = max_var(p.get()); - if (curr_max > max || max == null_var) - max = curr_max; - if (sz == 1 && simplify) { - if (sign < 0) - k = atom::flip(k); - sign = 1; - polynomial::manager::ineq_type t; - switch (k) { - case atom::EQ: t = polynomial::manager::ineq_type::EQ; break; - case atom::LT: t = polynomial::manager::ineq_type::LT; break; - case atom::GT: t = polynomial::manager::ineq_type::GT; break; - default: UNREACHABLE(); break; - } - polynomial::var_vector vars; - m_pm.vars(p, vars); - bool all_int = all_of(vars, [&](var x) { return is_int(x); }); - if (!all_int) - t = polynomial::manager::ineq_type::EQ; - m_pm.gcd_simplify(p, t); - } - uniq_ps.push_back(m_cache.mk_unique(p)); - TRACE("nlsat_table_bug", tout << "p: " << p << ", uniq: " << uniq_ps.back() << "\n";); - //verbose_stream() << "p: " << p.get() << ", uniq: " << uniq_ps.back() << "\n"; - } - void * mem = m_allocator.allocate(ineq_atom::get_obj_size(sz)); - if (sign < 0) - k = atom::flip(k); - ineq_atom * tmp_atom = new (mem) ineq_atom(k, sz, uniq_ps.data(), is_even, max); - ineq_atom * atom = m_ineq_atoms.insert_if_not_there(tmp_atom); - CTRACE("nlsat_table_bug", tmp_atom != atom, ineq_atom::hash_proc h; - tout << "mk_ineq_atom hash: " << h(tmp_atom) << "\n"; display(tout, *tmp_atom, m_display_var) << "\n";); - CTRACE("nlsat_table_bug", atom->max_var() != max, display(tout << "nonmax: ", *atom, m_display_var) << "\n";); - SASSERT(atom->max_var() == max); - is_new = (atom == tmp_atom); - if (is_new) { - for (unsigned i = 0; i < sz; i++) { - m_pm.inc_ref(atom->p(i)); - } - } - else { - deallocate(tmp_atom); - } - return atom; - } - - bool_var mk_ineq_atom(atom::kind k, unsigned sz, poly * const * ps, bool const * is_even, bool simplify = false) { - bool is_new = false; - ineq_atom* atom = mk_ineq_atom(k, sz, ps, is_even, is_new, simplify); - if (!is_new) { - return atom->bvar(); - } - else { - bool_var b = mk_bool_var_core(); - m_atoms[b] = atom; - atom->m_bool_var = b; - TRACE("nlsat_verbose", display(tout << "create: b" << atom->m_bool_var << " ", *atom) << "\n";); - return b; - } - } - - literal mk_ineq_literal(atom::kind k, unsigned sz, poly * const * ps, bool const * is_even, bool simplify = false) { - SASSERT(k == atom::LT || k == atom::GT || k == atom::EQ); - bool is_const = true; - polynomial::manager::scoped_numeral cnst(m_pm.m()); - m_pm.m().set(cnst, 1); - for (unsigned i = 0; i < sz; ++i) { - if (m_pm.is_const(ps[i])) { - if (m_pm.is_zero(ps[i])) { - m_pm.m().set(cnst, 0); - is_const = true; - break; - } - auto const& c = m_pm.coeff(ps[i], 0); - m_pm.m().mul(cnst, c, cnst); - if (is_even[i] && m_pm.m().is_neg(c)) { - m_pm.m().neg(cnst); - } - } - else { - is_const = false; - } - } - if (is_const) { - if (m_pm.m().is_pos(cnst) && k == atom::GT) return true_literal; - if (m_pm.m().is_neg(cnst) && k == atom::LT) return true_literal; - if (m_pm.m().is_zero(cnst) && k == atom::EQ) return true_literal; - return false_literal; - } - return literal(mk_ineq_atom(k, sz, ps, is_even, simplify), false); - } - - bool_var mk_root_atom(atom::kind k, var x, unsigned i, poly * p) { - polynomial_ref p1(m_pm), uniq_p(m_pm); - p1 = m_pm.flip_sign_if_lm_neg(p); // flipping the sign of the polynomial will not change its roots. - uniq_p = m_cache.mk_unique(p1); - TRACE("nlsat_solver", tout << x << " " << p1 << " " << uniq_p << "\n";); - SASSERT(i > 0); - SASSERT(x >= max_var(p)); - SASSERT(k == atom::ROOT_LT || k == atom::ROOT_GT || k == atom::ROOT_EQ || k == atom::ROOT_LE || k == atom::ROOT_GE); - - void * mem = m_allocator.allocate(sizeof(root_atom)); - root_atom * new_atom = new (mem) root_atom(k, x, i, uniq_p); - root_atom * old_atom = m_root_atoms.insert_if_not_there(new_atom); - SASSERT(old_atom->max_var() == x); - if (old_atom != new_atom) { - deallocate(new_atom); - return old_atom->bvar(); - } - bool_var b = mk_bool_var_core(); - m_atoms[b] = new_atom; - new_atom->m_bool_var = b; - m_pm.inc_ref(new_atom->p()); - return b; - } - - void attach_clause(clause & cls) { - var x = max_var(cls); - if (x != null_var) { - m_watches[x].push_back(&cls); - } - else { - bool_var b = max_bvar(cls); - m_bwatches[b].push_back(&cls); - } - } - - void deattach_clause(clause & cls) { - var x = max_var(cls); - if (x != null_var) { - m_watches[x].erase(&cls); - } - else { - bool_var b = max_bvar(cls); - m_bwatches[b].erase(&cls); - } - } - - void deallocate(clause * cls) { - size_t obj_sz = clause::get_obj_size(cls->size()); - cls->~clause(); - m_allocator.deallocate(obj_sz, cls); - } - - void del_clause(clause * cls) { - deattach_clause(*cls); - m_cid_gen.recycle(cls->id()); - unsigned sz = cls->size(); - for (unsigned i = 0; i < sz; i++) - dec_ref((*cls)[i]); - _assumption_set a = static_cast<_assumption_set>(cls->assumptions()); - dec_ref(a); - deallocate(cls); - } - - void del_clause(clause * cls, clause_vector& clauses) { - clauses.erase(cls); - del_clause(cls); - } - - void del_clauses(ptr_vector & cs) { - for (clause* cp : cs) - del_clause(cp); - cs.reset(); - } - - void del_clauses() { - del_clauses(m_clauses); - del_clauses(m_learned); - del_clauses(m_valids); - } - - // We use a simple heuristic to sort literals - // - bool literals < arith literals - // - sort literals based on max_var - // - sort literal with the same max_var using degree - // break ties using the fact that ineqs are usually cheaper to process than eqs. - struct lit_lt { - imp & m; - lit_lt(imp & _m):m(_m) {} - - bool operator()(literal l1, literal l2) const { - atom * a1 = m.m_atoms[l1.var()]; - atom * a2 = m.m_atoms[l2.var()]; - if (a1 == nullptr && a2 == nullptr) - return l1.index() < l2.index(); - if (a1 == nullptr) - return true; - if (a2 == nullptr) - return false; - var x1 = a1->max_var(); - var x2 = a2->max_var(); - if (x1 < x2) - return true; - if (x1 > x2) - return false; - SASSERT(x1 == x2); - unsigned d1 = m.degree(a1); - unsigned d2 = m.degree(a2); - if (d1 < d2) - return true; - if (d1 > d2) - return false; - if (!a1->is_eq() && a2->is_eq()) - return true; - if (a1->is_eq() && !a2->is_eq()) - return false; - return l1.index() < l2.index(); - } - }; - - class scoped_bool_vars { - imp& s; - svector vec; - public: - scoped_bool_vars(imp& s):s(s) {} - ~scoped_bool_vars() { - for (bool_var v : vec) { - s.dec_ref(v); - } - } - void push_back(bool_var v) { - s.inc_ref(v); - vec.push_back(v); - } - bool_var const* begin() const { return vec.begin(); } - bool_var const* end() const { return vec.end(); } - bool_var operator[](bool_var v) const { return vec[v]; } - }; - - void check_lemma(unsigned n, literal const* cls, bool is_valid, assumption_set a) { - TRACE("nlsat", display(tout << "check lemma: ", n, cls) << "\n"; - display(tout);); - IF_VERBOSE(2, display(verbose_stream() << "check lemma " << (is_valid?"valid: ":"consequence: "), n, cls) << "\n"); - for (clause* c : m_learned) IF_VERBOSE(1, display(verbose_stream() << "lemma: ", *c) << "\n"); - scoped_suspend_rlimit _limit(m_rlimit); - ctx c(m_rlimit, m_ctx.m_params, m_ctx.m_incremental); - solver solver2(c); - imp& checker = *(solver2.m_imp); - checker.m_check_lemmas = false; - checker.m_log_lemmas = false; - checker.m_inline_vars = false; - - auto pconvert = [&](poly* p) { - return convert(m_pm, p, checker.m_pm); - }; - - // need to translate Boolean variables and literals - scoped_bool_vars tr(checker); - for (var x = 0; x < m_is_int.size(); ++x) { - checker.register_var(x, is_int(x)); - } - bool_var bv = 0; - tr.push_back(bv); - for (bool_var b = 1; b < m_atoms.size(); ++b) { - atom* a = m_atoms[b]; - if (a == nullptr) { - bv = checker.mk_bool_var(); - } - else if (a->is_ineq_atom()) { - ineq_atom& ia = *to_ineq_atom(a); - unsigned sz = ia.size(); - polynomial_ref_vector ps(checker.m_pm); - bool_vector is_even; - for (unsigned i = 0; i < sz; ++i) { - ps.push_back(pconvert(ia.p(i))); - is_even.push_back(ia.is_even(i)); - } - bv = checker.mk_ineq_atom(ia.get_kind(), sz, ps.data(), is_even.data()); - } - else if (a->is_root_atom()) { - root_atom& r = *to_root_atom(a); - if (r.x() >= max_var(r.p())) { - // permutation may be reverted after check completes, - // but then root atoms are not used in lemmas. - bv = checker.mk_root_atom(r.get_kind(), r.x(), r.i(), pconvert(r.p())); - } - } - else { - UNREACHABLE(); - } - tr.push_back(bv); - } - if (!is_valid) { - for (clause* c : m_clauses) { - if (!a && c->assumptions()) { - continue; - } - literal_vector lits; - for (literal lit : *c) { - lits.push_back(literal(tr[lit.var()], lit.sign())); - } - checker.mk_external_clause(lits.size(), lits.data(), nullptr); - } - } - for (unsigned i = 0; i < n; ++i) { - literal lit = cls[i]; - literal nlit(tr[lit.var()], !lit.sign()); - checker.mk_external_clause(1, &nlit, nullptr); - } - lbool r = checker.check(); - if (r == l_true) { - for (bool_var b : tr) { - literal lit(b, false); - IF_VERBOSE(0, checker.display(verbose_stream(), lit) << " := " << checker.value(lit) << "\n"); - TRACE("nlsat", checker.display(tout, lit) << " := " << checker.value(lit) << "\n";); - } - for (clause* c : m_learned) { - bool found = false; - for (literal lit: *c) { - literal tlit(tr[lit.var()], lit.sign()); - found |= checker.value(tlit) == l_true; - } - if (!found) { - IF_VERBOSE(0, display(verbose_stream() << "violdated clause: ", *c) << "\n"); - TRACE("nlsat", display(tout << "violdated clause: ", *c) << "\n";); - } - } - for (clause* c : m_valids) { - bool found = false; - for (literal lit: *c) { - literal tlit(tr[lit.var()], lit.sign()); - found |= checker.value(tlit) == l_true; - } - if (!found) { - IF_VERBOSE(0, display(verbose_stream() << "violdated tautology clause: ", *c) << "\n"); - TRACE("nlsat", display(tout << "violdated tautology clause: ", *c) << "\n";); - } - } - throw default_exception("lemma did not check"); - UNREACHABLE(); - } - } - - void log_lemma(std::ostream& out, clause const& cls) { - log_lemma(out, cls.size(), cls.data(), false); - } - - void log_lemma(std::ostream& out, unsigned n, literal const* cls, bool is_valid) { - ++m_lemma_count; - out << "(set-logic NRA)\n"; - if (is_valid) { - display_smt2_bool_decls(out); - display_smt2_arith_decls(out); - } - else - display_smt2(out); - for (unsigned i = 0; i < n; ++i) - display_smt2(out << "(assert ", ~cls[i]) << ")\n"; - display(out << "(echo \"#" << m_lemma_count << " ", n, cls) << "\")\n"; - out << "(check-sat)\n(reset)\n"; - - TRACE("nlsat", display(tout << "(echo \"#" << m_lemma_count << " ", n, cls) << "\")\n"); - } - - clause * mk_clause_core(unsigned num_lits, literal const * lits, bool learned, _assumption_set a) { - SASSERT(num_lits > 0); - unsigned cid = m_cid_gen.mk(); - void * mem = m_allocator.allocate(clause::get_obj_size(num_lits)); - clause * cls = new (mem) clause(cid, num_lits, lits, learned, a); - for (unsigned i = 0; i < num_lits; i++) - inc_ref(lits[i]); - inc_ref(a); - return cls; - } - - clause * mk_clause(unsigned num_lits, literal const * lits, bool learned, _assumption_set a) { - if (num_lits == 0) { - num_lits = 1; - lits = &false_literal; - } - SASSERT(num_lits > 0); - clause * cls = mk_clause_core(num_lits, lits, learned, a); - TRACE("nlsat_sort", display(tout << "mk_clause:\n", *cls) << "\n";); - std::sort(cls->begin(), cls->end(), lit_lt(*this)); - TRACE("nlsat", display(tout << " after sort:\n", *cls) << "\n";); - if (learned && m_log_lemmas) { - log_lemma(verbose_stream(), *cls); - } - if (learned && m_check_lemmas && false) { - check_lemma(cls->size(), cls->data(), false, cls->assumptions()); - } - if (learned) - m_learned.push_back(cls); - else - m_clauses.push_back(cls); - attach_clause(*cls); - return cls; - } - - void mk_external_clause(unsigned num_lits, literal const * lits, assumption a) { - _assumption_set as = nullptr; - if (a != nullptr) - as = m_asm.mk_leaf(a); - if (num_lits == 0) { - num_lits = 1; - lits = &false_literal; - } - mk_clause(num_lits, lits, false, as); - } - - // ----------------------- - // - // Search - // - // ----------------------- - - void save_assign_trail(bool_var b) { - m_trail.push_back(trail(b, bvar_assignment())); - } - - void save_set_updt_trail(interval_set * old_set) { - m_trail.push_back(trail(old_set)); - } - - void save_updt_eq_trail(atom * old_eq) { - m_trail.push_back(trail(old_eq)); - } - - void save_new_stage_trail() { - m_trail.push_back(trail(true, stage())); - } - - void save_new_level_trail() { - m_trail.push_back(trail(false, stage())); - } - - void undo_bvar_assignment(bool_var b) { - m_bvalues[b] = l_undef; - m_levels[b] = UINT_MAX; - del_jst(m_allocator, m_justifications[b]); - m_justifications[b] = null_justification; - if (m_atoms[b] == nullptr && b < m_bk) - m_bk = b; - } - - void undo_set_updt(interval_set * old_set) { - if (m_xk == null_var) - return; - var x = m_xk; - if (x < m_infeasible.size()) { - m_ism.dec_ref(m_infeasible[x]); - m_infeasible[x] = old_set; - } - } - - void undo_new_stage() { - if (m_xk == 0) { - m_xk = null_var; - } - else if (m_xk != null_var) { - m_xk--; - m_assignment.reset(m_xk); - } - } - - void undo_new_level() { - SASSERT(m_scope_lvl > 0); - m_scope_lvl--; - m_evaluator.pop(1); - } - - void undo_updt_eq(atom * a) { - if (m_var2eq.size() > m_xk) - m_var2eq[m_xk] = a; - } - - template - void undo_until(Predicate const & pred) { - while (pred() && !m_trail.empty()) { - trail & t = m_trail.back(); - switch (t.m_kind) { - case trail::BVAR_ASSIGNMENT: - undo_bvar_assignment(t.m_b); - break; - case trail::INFEASIBLE_UPDT: - undo_set_updt(t.m_old_set); - break; - case trail::NEW_STAGE: - undo_new_stage(); - break; - case trail::NEW_LEVEL: - undo_new_level(); - break; - case trail::UPDT_EQ: - undo_updt_eq(t.m_old_eq); - break; - default: - break; - } - m_trail.pop_back(); - } - } - - struct size_pred { - svector & m_trail; - unsigned m_old_size; - size_pred(svector & trail, unsigned old_size):m_trail(trail), m_old_size(old_size) {} - bool operator()() const { return m_trail.size() > m_old_size; } - }; - - // Keep undoing until trail has the given size - void undo_until_size(unsigned old_size) { - SASSERT(m_trail.size() >= old_size); - undo_until(size_pred(m_trail, old_size)); - } - - struct stage_pred { - var const & m_xk; - var m_target; - stage_pred(var const & xk, var target):m_xk(xk), m_target(target) {} - bool operator()() const { return m_xk != m_target; } - }; - - // Keep undoing until stage is new_xk - void undo_until_stage(var new_xk) { - undo_until(stage_pred(m_xk, new_xk)); - } - - struct level_pred { - unsigned const & m_scope_lvl; - unsigned m_new_lvl; - level_pred(unsigned const & scope_lvl, unsigned new_lvl):m_scope_lvl(scope_lvl), m_new_lvl(new_lvl) {} - bool operator()() const { return m_scope_lvl > m_new_lvl; } - }; - - // Keep undoing until level is new_lvl - void undo_until_level(unsigned new_lvl) { - undo_until(level_pred(m_scope_lvl, new_lvl)); - } - - struct unassigned_pred { - bool_var m_b; - svector const & m_bvalues; - unassigned_pred(svector const & bvalues, bool_var b): - m_b(b), - m_bvalues(bvalues) {} - bool operator()() const { return m_bvalues[m_b] != l_undef; } - }; - - // Keep undoing until b is unassigned - void undo_until_unassigned(bool_var b) { - undo_until(unassigned_pred(m_bvalues, b)); - SASSERT(m_bvalues[b] == l_undef); - } - - struct true_pred { - bool operator()() const { return true; } - }; - - void undo_until_empty() { - undo_until(true_pred()); - } - - /** - \brief Create a new scope level - */ - void new_level() { - m_evaluator.push(); - m_scope_lvl++; - save_new_level_trail(); - } - - /** - \brief Return the value of the given literal that was assigned by the search - engine. - */ - lbool assigned_value(literal l) const { - bool_var b = l.var(); - if (l.sign()) - return ~m_bvalues[b]; - else - return m_bvalues[b]; - } - - /** - \brief Assign literal using the given justification - */ - void assign(literal l, justification j) { - TRACE("nlsat_assign", - display(tout << "assigning literal: ", l); - display(tout << " <- ", j);); - - SASSERT(assigned_value(l) == l_undef); - SASSERT(j != null_justification); - SASSERT(!j.is_null()); - if (j.is_decision()) - m_stats.m_decisions++; - else - m_stats.m_propagations++; - bool_var b = l.var(); - m_bvalues[b] = to_lbool(!l.sign()); - m_levels[b] = m_scope_lvl; - m_justifications[b] = j; - save_assign_trail(b); - updt_eq(b, j); - TRACE("nlsat_assign", tout << "b" << b << " -> " << m_bvalues[b] << "\n";); - } - - /** - \brief Create a "case-split" - */ - void decide(literal l) { - new_level(); - assign(l, decided_justification); - } - - /** - \brief Return the value of a literal as defined in Dejan and Leo's paper. - */ - lbool value(literal l) { - lbool val = assigned_value(l); - if (val != l_undef) { - TRACE("nlsat_verbose", display(tout << " assigned value " << val << " for ", l) << "\n";); - return val; - } - bool_var b = l.var(); - atom * a = m_atoms[b]; - if (a == nullptr) { - TRACE("nlsat_verbose", display(tout << " no atom for ", l) << "\n";); - return l_undef; - } - var max = a->max_var(); - if (!m_assignment.is_assigned(max)) { - TRACE("nlsat_verbose", display(tout << " maximal variable not assigned ", l) << "\n";); - return l_undef; - } - val = to_lbool(m_evaluator.eval(a, l.sign())); - TRACE("nlsat_verbose", display(tout << " evaluated value " << val << " for ", l) << "\n";); - TRACE("value_bug", tout << "value of: "; display(tout, l); tout << " := " << val << "\n"; - tout << "xk: " << m_xk << ", a->max_var(): " << a->max_var() << "\n"; - display_assignment(tout);); - return val; - } - - /** - \brief Return true if the given clause is already satisfied in the current partial interpretation. - */ - bool is_satisfied(clause const & cls) const { - for (literal l : cls) { - if (const_cast(this)->value(l) == l_true) { - TRACE("value_bug:", tout << l << " := true\n";); - return true; - } - } - return false; - } - - /** - \brief Return true if the given clause is false in the current partial interpretation. - */ - bool is_inconsistent(unsigned sz, literal const * cls) { - for (unsigned i = 0; i < sz; i++) { - if (value(cls[i]) != l_false) { - TRACE("is_inconsistent", tout << "literal is not false:\n"; display(tout, cls[i]); tout << "\n";); - return false; - } - } - return true; - } - - /** - \brief Process a clauses that contains only Boolean literals. - */ - bool process_boolean_clause(clause const & cls) { - SASSERT(m_xk == null_var); - unsigned num_undef = 0; - unsigned first_undef = UINT_MAX; - unsigned sz = cls.size(); - for (unsigned i = 0; i < sz; i++) { - literal l = cls[i]; - SASSERT(m_atoms[l.var()] == nullptr); - SASSERT(value(l) != l_true); - if (value(l) == l_false) - continue; - SASSERT(value(l) == l_undef); - num_undef++; - if (first_undef == UINT_MAX) - first_undef = i; - } - if (num_undef == 0) - return false; - SASSERT(first_undef != UINT_MAX); - if (num_undef == 1) - assign(cls[first_undef], mk_clause_jst(&cls)); // unit clause - else - decide(cls[first_undef]); - return true; - } - - /** - \brief assign l to true, because l + (justification of) s is infeasible in RCF in the current interpretation. - */ - literal_vector core; - ptr_vector clauses; - void R_propagate(literal l, interval_set const * s, bool include_l = true) { - m_ism.get_justifications(s, core, clauses); - if (include_l) - core.push_back(~l); - auto j = mk_lazy_jst(m_allocator, core.size(), core.data(), clauses.size(), clauses.data()); - TRACE("nlsat_resolve", display(tout, j); display_eval(tout << "evaluated:", j)); - assign(l, j); - SASSERT(value(l) == l_true); - } - - /** - \brief m_infeasible[m_xk] <- m_infeasible[m_xk] Union s - */ - void updt_infeasible(interval_set const * s) { - SASSERT(m_xk != null_var); - interval_set * xk_set = m_infeasible[m_xk]; - save_set_updt_trail(xk_set); - interval_set_ref new_set(m_ism); - TRACE("nlsat_inf_set", tout << "updating infeasible set\n"; m_ism.display(tout, xk_set) << "\n"; m_ism.display(tout, s) << "\n";); - new_set = m_ism.mk_union(s, xk_set); - TRACE("nlsat_inf_set", tout << "new infeasible set:\n"; m_ism.display(tout, new_set) << "\n";); - SASSERT(!m_ism.is_full(new_set)); - m_ism.inc_ref(new_set); - m_infeasible[m_xk] = new_set; - } - - /** - \brief Update m_var2eq mapping. - */ - void updt_eq(bool_var b, justification j) { - if (!m_simplify_cores) - return; - if (m_bvalues[b] != l_true) - return; - atom * a = m_atoms[b]; - if (a == nullptr || a->get_kind() != atom::EQ || to_ineq_atom(a)->size() > 1 || to_ineq_atom(a)->is_even(0)) - return; - switch (j.get_kind()) { - case justification::CLAUSE: - if (j.get_clause()->assumptions() != nullptr) return; - break; - case justification::LAZY: - if (j.get_lazy()->num_clauses() > 0) return; - if (j.get_lazy()->num_lits() > 0) return; - break; - default: - break; - } - var x = m_xk; - SASSERT(a->max_var() == x); - SASSERT(x != null_var); - if (m_var2eq[x] != 0 && degree(m_var2eq[x]) <= degree(a)) - return; // we only update m_var2eq if the new equality has smaller degree - TRACE("nlsat_simplify_core", tout << "Saving equality for "; m_display_var(tout, x) << " (x" << x << ") "; - tout << "scope-lvl: " << scope_lvl() << "\n"; display(tout, literal(b, false)) << "\n"; - display(tout, j); - ); - save_updt_eq_trail(m_var2eq[x]); - m_var2eq[x] = a; - } - - /** - \brief Process a clause that contains nonlinear arithmetic literals - - If satisfy_learned is true, then learned clauses are satisfied even if m_lazy > 0 - */ - bool process_arith_clause(clause const & cls, bool satisfy_learned) { - if (!satisfy_learned && m_lazy >= 2 && cls.is_learned()) { - TRACE("nlsat", tout << "skip learned\n";); - return true; // ignore lemmas in super lazy mode - } - SASSERT(m_xk == max_var(cls)); - unsigned num_undef = 0; // number of undefined literals - unsigned first_undef = UINT_MAX; // position of the first undefined literal - interval_set_ref first_undef_set(m_ism); // infeasible region of the first undefined literal - interval_set * xk_set = m_infeasible[m_xk]; // current set of infeasible interval for current variable - SASSERT(!m_ism.is_full(xk_set)); - for (unsigned idx = 0; idx < cls.size(); ++idx) { - literal l = cls[idx]; - checkpoint(); - if (value(l) == l_false) - continue; - if (value(l) == l_true) - return true; // could happen if clause is a tautology - CTRACE("nlsat", max_var(l) != m_xk || value(l) != l_undef, display(tout); - tout << "xk: " << m_xk << ", max_var(l): " << max_var(l) << ", l: "; display(tout, l) << "\n"; - display(tout, cls) << "\n";); - SASSERT(value(l) == l_undef); - SASSERT(max_var(l) == m_xk); - bool_var b = l.var(); - atom * a = m_atoms[b]; - SASSERT(a != nullptr); - interval_set_ref curr_set(m_ism); - curr_set = m_evaluator.infeasible_intervals(a, l.sign(), &cls); - TRACE("nlsat_inf_set", tout << "infeasible set for literal: "; display(tout, l); tout << "\n"; m_ism.display(tout, curr_set); tout << "\n"; - display(tout, cls) << "\n";); - if (m_ism.is_empty(curr_set)) { - TRACE("nlsat_inf_set", tout << "infeasible set is empty, found literal\n";); - R_propagate(l, nullptr); - SASSERT(is_satisfied(cls)); - return true; - } - if (m_ism.is_full(curr_set)) { - TRACE("nlsat_inf_set", tout << "infeasible set is R, skip literal\n";); - R_propagate(~l, nullptr); - continue; - } - if (m_ism.subset(curr_set, xk_set)) { - TRACE("nlsat_inf_set", tout << "infeasible set is a subset of current set, found literal\n";); - R_propagate(l, xk_set); - return true; - } - interval_set_ref tmp(m_ism); - tmp = m_ism.mk_union(curr_set, xk_set); - if (m_ism.is_full(tmp)) { - TRACE("nlsat_inf_set", tout << "infeasible set + current set = R, skip literal\n"; - display(tout, cls) << "\n"; - m_ism.display(tout, tmp); tout << "\n"; - ); - R_propagate(~l, tmp, false); - continue; - } - num_undef++; - if (first_undef == UINT_MAX) { - first_undef = idx; - first_undef_set = curr_set; - } - } - TRACE("nlsat_inf_set", tout << "num_undef: " << num_undef << "\n";); - if (num_undef == 0) - return false; - SASSERT(first_undef != UINT_MAX); - if (num_undef == 1) { - // unit clause - assign(cls[first_undef], mk_clause_jst(&cls)); - updt_infeasible(first_undef_set); - } - else if ( satisfy_learned || - !cls.is_learned() /* must always satisfy input clauses */ || - m_lazy == 0 /* if not in lazy mode, we also satiffy lemmas */) { - decide(cls[first_undef]); - updt_infeasible(first_undef_set); - } - else { - TRACE("nlsat_lazy", tout << "skipping clause, satisfy_learned: " << satisfy_learned << ", cls.is_learned(): " << cls.is_learned() - << ", lazy: " << m_lazy << "\n";); - } - return true; - } - - /** - \brief Try to satisfy the given clause. Return true if succeeded. - - If satisfy_learned is true, then (arithmetic) learned clauses are satisfied even if m_lazy > 0 - */ - bool process_clause(clause const & cls, bool satisfy_learned) { - if (is_satisfied(cls)) - return true; - if (m_xk == null_var) - return process_boolean_clause(cls); - else - return process_arith_clause(cls, satisfy_learned); - } - - /** - \brief Try to satisfy the given "set" of clauses. - Return 0, if the set was satisfied, or the violating clause otherwise - */ - clause * process_clauses(clause_vector const & cs) { - for (clause* c : cs) { - if (!process_clause(*c, false)) - return c; - } - return nullptr; // succeeded - } - - /** - \brief Make sure m_bk is the first unassigned pure Boolean variable. - Set m_bk == null_bool_var if there is no unassigned pure Boolean variable. - */ - void peek_next_bool_var() { - while (m_bk < m_atoms.size()) { - if (!m_dead[m_bk] && m_atoms[m_bk] == nullptr && m_bvalues[m_bk] == l_undef) { - return; - } - m_bk++; - } - m_bk = null_bool_var; - } - - /** - \brief Create a new stage. See Dejan and Leo's paper. - */ - void new_stage() { - m_stats.m_stages++; - save_new_stage_trail(); - if (m_xk == null_var) - m_xk = 0; - else - m_xk++; - } - - /** - \brief Assign m_xk - */ - void select_witness() { - scoped_anum w(m_am); - SASSERT(!m_ism.is_full(m_infeasible[m_xk])); - m_ism.peek_in_complement(m_infeasible[m_xk], is_int(m_xk), w, m_randomize); - TRACE("nlsat", - tout << "infeasible intervals: "; m_ism.display(tout, m_infeasible[m_xk]); tout << "\n"; - tout << "assigning "; m_display_var(tout, m_xk) << "(x" << m_xk << ") -> " << w << "\n";); - TRACE("nlsat_root", tout << "value as root object: "; m_am.display_root(tout, w); tout << "\n";); - if (!m_am.is_rational(w)) - m_stats.m_irrational_assignments++; - m_assignment.set_core(m_xk, w); - } - - - - bool is_satisfied() { - if (m_bk == null_bool_var && m_xk >= num_vars()) { - TRACE("nlsat", tout << "found model\n"; display_assignment(tout);); - fix_patch(); - SASSERT(check_satisfied(m_clauses)); - return true; // all variables were assigned, and all clauses were satisfied. - } - else { - return false; - } - } - - - /** - \brief main procedure - */ - lbool search() { - TRACE("nlsat", tout << "starting search...\n"; display(tout); tout << "\nvar order:\n"; display_vars(tout);); - TRACE("nlsat_proof", tout << "ASSERTED\n"; display(tout);); - TRACE("nlsat_proof_sk", tout << "ASSERTED\n"; display_abst(tout);); - TRACE("nlsat_mathematica", display_mathematica(tout);); - TRACE("nlsat", display_smt2(tout);); - m_bk = 0; - m_xk = null_var; - - while (true) { - if (should_reorder()) - do_reorder(); - -#if 0 - if (should_gc()) - do_gc(); -#endif - - if (should_simplify()) - do_simplify(); - - CASSERT("nlsat", check_satisfied()); - if (m_xk == null_var) { - peek_next_bool_var(); - if (m_bk == null_bool_var) - new_stage(); // move to arith vars - } - else { - new_stage(); // peek next arith var - } - TRACE("nlsat_bug", tout << "xk: x" << m_xk << " bk: b" << m_bk << "\n";); - if (is_satisfied()) { - return l_true; - } - while (true) { - TRACE("nlsat_verbose", tout << "processing variable "; - if (m_xk != null_var) { - m_display_var(tout, m_xk); tout << " " << m_watches[m_xk].size(); - } - else { - tout << m_bwatches[m_bk].size() << " boolean b" << m_bk; - } - tout << "\n";); - checkpoint(); - clause * conflict_clause; - if (m_xk == null_var) - conflict_clause = process_clauses(m_bwatches[m_bk]); - else - conflict_clause = process_clauses(m_watches[m_xk]); - if (conflict_clause == nullptr) - break; - if (!resolve(*conflict_clause)) - return l_false; - if (m_stats.m_conflicts >= m_max_conflicts) - return l_undef; - log(); - } - - if (m_xk == null_var) { - if (m_bvalues[m_bk] == l_undef) { - decide(literal(m_bk, true)); - m_bk++; - } - } - else { - select_witness(); - } - } - } - - void gc() { - if (m_learned.size() <= 4*m_clauses.size()) - return; - reset_watches(); - reinit_cache(); - unsigned j = 0; - for (unsigned i = 0; i < m_learned.size(); ++i) { - auto cls = m_learned[i]; - if (i - j < m_clauses.size() && cls->size() > 1 && !cls->is_active()) - del_clause(cls); - else { - m_learned[j++] = cls; - cls->set_active(false); - } - } - m_learned.shrink(j); - reattach_arith_clauses(m_clauses); - reattach_arith_clauses(m_learned); - } - - - bool should_gc() { - return m_learned.size() > 10 * m_clauses.size(); - } - - void do_gc() { - undo_to_base(); - gc(); - } - - void undo_to_base() { - init_search(); - m_bk = 0; - m_xk = null_var; - } - - unsigned m_restart_threshold = 10000; - bool should_reorder() { - return m_stats.m_conflicts > 0 && m_stats.m_conflicts % m_restart_threshold == 0; - } - - void do_reorder() { - undo_to_base(); - m_stats.m_restarts++; - m_stats.m_conflicts++; - if (m_reordered) - restore_order(); - apply_reorder(); - } - - bool m_did_simplify = false; - bool should_simplify() { - return - !m_did_simplify && m_inline_vars && - !m_incremental && m_stats.m_conflicts > 100; - } - - void do_simplify() { - undo_to_base(); - m_did_simplify = true; - m_simplify(); - } - - unsigned m_next_conflict = 100; - void log() { - if (m_stats.m_conflicts != 1 && m_stats.m_conflicts < m_next_conflict) - return; - m_next_conflict += 100; - IF_VERBOSE(2, verbose_stream() << "(nlsat :conflicts " << m_stats.m_conflicts - << " :decisions " << m_stats.m_decisions - << " :propagations " << m_stats.m_propagations - << " :clauses " << m_clauses.size() - << " :learned " << m_learned.size() << ")\n"); - } - - - lbool search_check() { - lbool r = l_undef; - m_stats.m_conflicts = 0; - m_stats.m_restarts = 0; - m_next_conflict = 0; - while (true) { - r = search(); - if (r != l_true) - break; - ++m_stats.m_restarts; - vector> bounds; - - for (var x = 0; x < num_vars(); x++) { - if (is_int(x) && m_assignment.is_assigned(x) && !m_am.is_int(m_assignment.value(x))) { - scoped_anum v(m_am), vlo(m_am); - v = m_assignment.value(x); - rational lo; - m_am.int_lt(v, vlo); - if (!m_am.is_int(vlo)) - continue; - m_am.to_rational(vlo, lo); - // derive tight bounds. - while (true) { - lo++; - if (!m_am.gt(v, lo.to_mpq())) { - lo--; - break; - } - } - bounds.push_back(std::make_pair(x, lo)); - } - } - if (bounds.empty()) - break; - - gc(); - if (m_stats.m_restarts % 10 == 0) { - if (m_reordered) - restore_order(); - apply_reorder(); - } - - init_search(); - IF_VERBOSE(2, verbose_stream() << "(nlsat-b&b :conflicts " << m_stats.m_conflicts - << " :decisions " << m_stats.m_decisions - << " :propagations " << m_stats.m_propagations - << " :clauses " << m_clauses.size() - << " :learned " << m_learned.size() << ")\n"); - for (auto const& b : bounds) { - var x = b.first; - rational lo = b.second; - rational hi = lo + 1; // rational::one(); - bool is_even = false; - polynomial_ref p(m_pm); - rational one(1); - m_lemma.reset(); - p = m_pm.mk_linear(1, &one, &x, -lo); - poly* p1 = p.get(); - m_lemma.push_back(~mk_ineq_literal(atom::GT, 1, &p1, &is_even)); - p = m_pm.mk_linear(1, &one, &x, -hi); - poly* p2 = p.get(); - m_lemma.push_back(~mk_ineq_literal(atom::LT, 1, &p2, &is_even)); - - // perform branch and bound - clause * cls = mk_clause(m_lemma.size(), m_lemma.data(), true, nullptr); - IF_VERBOSE(4, display(verbose_stream(), *cls) << "\n"); - if (cls) { - TRACE("nlsat", display(tout << "conflict " << lo << " " << hi, *cls); tout << "\n";); - } - } - } - return r; - } - - bool m_reordered = false; - - void apply_reorder() { - m_reordered = false; - if (!can_reorder()) - ; - else if (m_random_order) { - shuffle_vars(); - m_reordered = true; - } - else if (m_reorder) { - heuristic_reorder(); - m_reordered = true; - } - } - - lbool check() { - TRACE("nlsat_smt2", display_smt2(tout);); - TRACE("nlsat_fd", tout << "is_full_dimensional: " << is_full_dimensional() << "\n";); - init_search(); - m_explain.set_full_dimensional(is_full_dimensional()); - - apply_reorder(); - -#if 0 - if (!m_incremental && m_inline_vars) { - if (!m_simplify()) - return l_false; - } -#endif - IF_VERBOSE(3, verbose_stream() << "search\n"); - sort_watched_clauses(); - lbool r = search_check(); - CTRACE("nlsat_model", r == l_true, tout << "model before restore order\n"; display_assignment(tout);); - if (m_reordered) - restore_order(); - CTRACE("nlsat_model", r == l_true, tout << "model\n"; display_assignment(tout);); - CTRACE("nlsat", r == l_false, display(tout << "unsat\n");); - SASSERT(r != l_true || check_satisfied(m_clauses)); - return r; - } - - void init_search() { - undo_until_empty(); - while (m_scope_lvl > 0) { - undo_new_level(); - } - m_xk = null_var; - for (unsigned i = 0; i < m_bvalues.size(); ++i) { - m_bvalues[i] = l_undef; - } - m_assignment.reset(); - } - - lbool check(literal_vector& assumptions) { - literal_vector result; - unsigned sz = assumptions.size(); - literal const* ptr = assumptions.data(); - for (unsigned i = 0; i < sz; ++i) { - mk_external_clause(1, ptr+i, (assumption)(ptr+i)); - } - display_literal_assumption dla(*this, assumptions); - scoped_display_assumptions _scoped_display(*this, dla); - lbool r = check(); - - if (r == l_false) { - // collect used literals from m_lemma_assumptions - vector deps; - get_core(deps); - for (unsigned i = 0; i < deps.size(); ++i) { - literal const* lp = (literal const*)(deps[i]); - if (ptr <= lp && lp < ptr + sz) { - result.push_back(*lp); - } - } - } - collect(assumptions, m_clauses); - collect(assumptions, m_learned); - del_clauses(m_valids); - if (m_check_lemmas) { - for (clause* c : m_learned) { - check_lemma(c->size(), c->data(), false, nullptr); - } - } - -#if 0 - for (clause* c : m_learned) { - IF_VERBOSE(0, display(verbose_stream() << "KEEP: ", c->size(), c->c_ptr()) << "\n"); - } -#endif - assumptions.reset(); - assumptions.append(result); - return r; - } - - void get_core(vector& deps) { - m_asm.linearize(m_lemma_assumptions.get(), deps); - } - - void collect(literal_vector const& assumptions, clause_vector& clauses) { - unsigned j = 0; - for (clause * c : clauses) { - if (collect(assumptions, *c)) { - del_clause(c); - } - else { - clauses[j++] = c; - } - } - clauses.shrink(j); - } - - bool collect(literal_vector const& assumptions, clause const& c) { - unsigned sz = assumptions.size(); - literal const* ptr = assumptions.data(); - _assumption_set asms = static_cast<_assumption_set>(c.assumptions()); - if (asms == nullptr) { - return false; - } - vector deps; - m_asm.linearize(asms, deps); - for (auto dep : deps) { - if (ptr <= dep && dep < ptr + sz) { - return true; - } - } - return false; - } - - // ----------------------- - // - // Conflict Resolution - // - // ----------------------- - svector m_marks; // bool_var -> bool temp mark used during conflict resolution - unsigned m_num_marks; - scoped_literal_vector m_lemma; - scoped_literal_vector m_lazy_clause; - assumption_set_ref m_lemma_assumptions; // assumption tracking - - // Conflict resolution invariant: a marked literal is in m_lemma or on the trail stack. - - bool check_marks() { - for (unsigned m : m_marks) { - (void)m; - SASSERT(m == 0); - } - return true; - } - - unsigned scope_lvl() const { return m_scope_lvl; } - - bool is_marked(bool_var b) const { return m_marks.get(b, 0) == 1; } - - void mark(bool_var b) { m_marks.setx(b, 1, 0); } - - void reset_mark(bool_var b) { m_marks[b] = 0; } - - void reset_marks() { - for (auto const& l : m_lemma) { - reset_mark(l.var()); - } - } - - void process_antecedent(literal antecedent) { - checkpoint(); - bool_var b = antecedent.var(); - TRACE("nlsat_resolve", display(tout << "resolving antecedent: ", antecedent) << "\n";); - if (assigned_value(antecedent) == l_undef) { - checkpoint(); - // antecedent must be false in the current arith interpretation - SASSERT(value(antecedent) == l_false || m_rlimit.is_canceled()); - if (!is_marked(b)) { - SASSERT(is_arith_atom(b) && max_var(b) < m_xk); // must be in a previous stage - TRACE("nlsat_resolve", tout << "literal is unassigned, but it is false in arithmetic interpretation, adding it to lemma\n";); - mark(b); - m_lemma.push_back(antecedent); - } - return; - } - - unsigned b_lvl = m_levels[b]; - TRACE("nlsat_resolve", tout << "b_lvl: " << b_lvl << ", is_marked(b): " << is_marked(b) << ", m_num_marks: " << m_num_marks << "\n";); - if (!is_marked(b)) { - mark(b); - if (b_lvl == scope_lvl() /* same level */ && max_var(b) == m_xk /* same stage */) { - TRACE("nlsat_resolve", tout << "literal is in the same level and stage, increasing marks\n";); - m_num_marks++; - } - else { - TRACE("nlsat_resolve", tout << "previous level or stage, adding literal to lemma\n"; - tout << "max_var(b): " << max_var(b) << ", m_xk: " << m_xk << ", lvl: " << b_lvl << ", scope_lvl: " << scope_lvl() << "\n";); - m_lemma.push_back(antecedent); - } - } - } - - void resolve_clause(bool_var b, unsigned sz, literal const * c) { - TRACE("nlsat_proof", tout << "resolving "; if (b != null_bool_var) display_atom(tout, b) << "\n"; display(tout, sz, c); tout << "\n";); - TRACE("nlsat_proof_sk", tout << "resolving "; if (b != null_bool_var) tout << "b" << b; tout << "\n"; display_abst(tout, sz, c); tout << "\n";); - - for (unsigned i = 0; i < sz; i++) { - if (c[i].var() != b) - process_antecedent(c[i]); - } - } - - void resolve_clause(bool_var b, clause & c) { - TRACE("nlsat_resolve", tout << "resolving clause "; if (b != null_bool_var) tout << "for b: " << b << "\n"; display(tout, c) << "\n";); - c.set_active(true); - resolve_clause(b, c.size(), c.data()); - m_lemma_assumptions = m_asm.mk_join(static_cast<_assumption_set>(c.assumptions()), m_lemma_assumptions); - } - - void resolve_lazy_justification(bool_var b, lazy_justification const & jst) { - TRACE("nlsat_resolve", tout << "resolving lazy_justification for b" << b << "\n";); - unsigned sz = jst.num_lits(); - - // Dump lemma as Mathematica formula that must be true, - // if the current interpretation (really) makes the core in jst infeasible. - TRACE("nlsat_mathematica", - tout << "assignment lemma\n"; - literal_vector core; - for (unsigned i = 0; i < sz; i++) { - core.push_back(~jst.lit(i)); - } - display_mathematica_lemma(tout, core.size(), core.data(), true);); - - m_lazy_clause.reset(); - m_explain(jst.num_lits(), jst.lits(), m_lazy_clause); - for (unsigned i = 0; i < sz; i++) - m_lazy_clause.push_back(~jst.lit(i)); - - // lazy clause is a valid clause - TRACE("nlsat_mathematica", display_mathematica_lemma(tout, m_lazy_clause.size(), m_lazy_clause.data());); - TRACE("nlsat_proof_sk", tout << "theory lemma\n"; display_abst(tout, m_lazy_clause.size(), m_lazy_clause.data()); tout << "\n";); - TRACE("nlsat_resolve", - tout << "m_xk: " << m_xk << ", "; m_display_var(tout, m_xk) << "\n"; - tout << "new valid clause:\n"; - display(tout, m_lazy_clause.size(), m_lazy_clause.data()) << "\n";); - - - if (m_log_lemmas) - log_lemma(verbose_stream(), m_lazy_clause.size(), m_lazy_clause.data(), true); - - if (m_check_lemmas) { - check_lemma(m_lazy_clause.size(), m_lazy_clause.data(), true, nullptr); - m_valids.push_back(mk_clause_core(m_lazy_clause.size(), m_lazy_clause.data(), false, nullptr)); - } - -#ifdef Z3DEBUG - { - unsigned sz = m_lazy_clause.size(); - for (unsigned i = 0; i < sz; i++) { - literal l = m_lazy_clause[i]; - if (l.var() != b) { - if (value(l) != l_false) - display(verbose_stream() << value(l) << " ", 1, &l); - SASSERT(value(l) == l_false || m_rlimit.is_canceled()); - } - else { - SASSERT(value(l) == l_true || m_rlimit.is_canceled()); - SASSERT(!l.sign() || m_bvalues[b] == l_false); - SASSERT(l.sign() || m_bvalues[b] == l_true); - } - } - } -#endif - checkpoint(); - resolve_clause(b, m_lazy_clause.size(), m_lazy_clause.data()); - - for (unsigned i = 0; i < jst.num_clauses(); ++i) { - clause const& c = jst.clause(i); - TRACE("nlsat", display(tout << "adding clause assumptions ", c) << "\n";); - m_lemma_assumptions = m_asm.mk_join(static_cast<_assumption_set>(c.assumptions()), m_lemma_assumptions); - } - } - - /** - \brief Return true if all literals in ls are from previous stages. - */ - bool only_literals_from_previous_stages(unsigned num, literal const * ls) const { - for (unsigned i = 0; i < num; i++) { - if (max_var(ls[i]) == m_xk) - return false; - } - return true; - } - - /** - \brief Return the maximum scope level in ls. - - \pre This method assumes value(ls[i]) is l_false for i in [0, num) - */ - unsigned max_scope_lvl(unsigned num, literal const * ls) { - unsigned max = 0; - for (unsigned i = 0; i < num; i++) { - literal l = ls[i]; - bool_var b = l.var(); - SASSERT(value(ls[i]) == l_false); - if (assigned_value(l) == l_false) { - unsigned lvl = m_levels[b]; - if (lvl > max) - max = lvl; - } - else { - // l must be a literal from a previous stage that is false in the current interpretation - SASSERT(assigned_value(l) == l_undef); - SASSERT(max_var(b) != null_var); - SASSERT(m_xk != null_var); - SASSERT(max_var(b) < m_xk); - } - } - return max; - } - - /** - \brief Remove literals of the given lvl (that are in the current stage) from lemma. - - \pre This method assumes value(ls[i]) is l_false for i in [0, num) - */ - void remove_literals_from_lvl(scoped_literal_vector & lemma, unsigned lvl) { - TRACE("nlsat_resolve", tout << "removing literals from lvl: " << lvl << " and stage " << m_xk << "\n";); - unsigned sz = lemma.size(); - unsigned j = 0; - for (unsigned i = 0; i < sz; i++) { - literal l = lemma[i]; - bool_var b = l.var(); - SASSERT(is_marked(b)); - SASSERT(value(lemma[i]) == l_false); - if (assigned_value(l) == l_false && m_levels[b] == lvl && max_var(b) == m_xk) { - m_num_marks++; - continue; - } - lemma.set(j, l); - j++; - } - lemma.shrink(j); - } - - /** - \brief Return true if it is a Boolean lemma. - */ - bool is_bool_lemma(unsigned sz, literal const * ls) const { - for (unsigned i = 0; i < sz; i++) { - if (m_atoms[ls[i].var()] != nullptr) - return false; - } - return true; - } - - - /** - Return the maximal decision level in lemma for literals in the first sz-1 positions that - are at the same stage. If all these literals are from previous stages, - we just backtrack the current level. - */ - unsigned find_new_level_arith_lemma(unsigned sz, literal const * lemma) { - SASSERT(!is_bool_lemma(sz, lemma)); - unsigned new_lvl = 0; - bool found_lvl = false; - for (unsigned i = 0; i < sz - 1; i++) { - literal l = lemma[i]; - if (max_var(l) == m_xk) { - bool_var b = l.var(); - if (!found_lvl) { - found_lvl = true; - new_lvl = m_levels[b]; - } - else { - if (m_levels[b] > new_lvl) - new_lvl = m_levels[b]; - } - } - } - SASSERT(!found_lvl || new_lvl < scope_lvl()); - if (!found_lvl) { - TRACE("nlsat_resolve", tout << "fail to find new lvl, using previous one\n";); - new_lvl = scope_lvl() - 1; - } - return new_lvl; - } - - struct scoped_reset_marks { - imp& i; - scoped_reset_marks(imp& i):i(i) {} - ~scoped_reset_marks() { if (i.m_num_marks > 0) { i.m_num_marks = 0; for (char& m : i.m_marks) m = 0; } } - }; - - - /** - \brief Return true if the conflict was solved. - */ - bool resolve(clause & conflict) { - clause * conflict_clause = &conflict; - m_lemma_assumptions = nullptr; - start: - SASSERT(check_marks()); - TRACE("nlsat_proof", tout << "STARTING RESOLUTION\n";); - TRACE("nlsat_proof_sk", tout << "STARTING RESOLUTION\n";); - m_stats.m_conflicts++; - TRACE("nlsat", tout << "resolve, conflicting clause:\n"; display(tout, *conflict_clause) << "\n"; - tout << "xk: "; if (m_xk != null_var) m_display_var(tout, m_xk); else tout << ""; tout << "\n"; - tout << "scope_lvl: " << scope_lvl() << "\n"; - tout << "current assignment\n"; display_assignment(tout);); - - m_num_marks = 0; - m_lemma.reset(); - m_lemma_assumptions = nullptr; - scoped_reset_marks _sr(*this); - resolve_clause(null_bool_var, *conflict_clause); - - unsigned top = m_trail.size(); - bool found_decision; - while (true) { - found_decision = false; - while (m_num_marks > 0) { - checkpoint(); - SASSERT(top > 0); - trail & t = m_trail[top-1]; - SASSERT(t.m_kind != trail::NEW_STAGE); // we only mark literals that are in the same stage - if (t.m_kind == trail::BVAR_ASSIGNMENT) { - bool_var b = t.m_b; - if (is_marked(b)) { - TRACE("nlsat_resolve", tout << "found marked: b" << b << "\n"; display_atom(tout, b) << "\n";); - m_num_marks--; - reset_mark(b); - justification jst = m_justifications[b]; - switch (jst.get_kind()) { - case justification::CLAUSE: - resolve_clause(b, *(jst.get_clause())); - break; - case justification::LAZY: - resolve_lazy_justification(b, *(jst.get_lazy())); - break; - case justification::DECISION: - SASSERT(m_num_marks == 0); - found_decision = true; - TRACE("nlsat_resolve", tout << "found decision\n";); - m_lemma.push_back(literal(b, m_bvalues[b] == l_true)); - break; - default: - UNREACHABLE(); - break; - } - } - } - top--; - } - - // m_lemma is an implicating clause after backtracking current scope level. - if (found_decision) - break; - - // If lemma only contains literals from previous stages, then we can stop. - // We make progress by returning to a previous stage with additional information (new lemma) - // that forces us to select a new partial interpretation - if (only_literals_from_previous_stages(m_lemma.size(), m_lemma.data())) - break; - - // Conflict does not depend on the current decision, and it is still in the current stage. - // We should find - // - the maximal scope level in the lemma - // - remove literal assigned in the scope level from m_lemma - // - backtrack to this level - // - and continue conflict resolution from there - // - we must bump m_num_marks for literals removed from m_lemma - unsigned max_lvl = max_scope_lvl(m_lemma.size(), m_lemma.data()); - TRACE("nlsat_resolve", tout << "conflict does not depend on current decision, backtracking to level: " << max_lvl << "\n";); - SASSERT(max_lvl < scope_lvl()); - remove_literals_from_lvl(m_lemma, max_lvl); - undo_until_level(max_lvl); - top = m_trail.size(); - TRACE("nlsat_resolve", tout << "scope_lvl: " << scope_lvl() << " num marks: " << m_num_marks << "\n";); - SASSERT(scope_lvl() == max_lvl); - } - - TRACE("nlsat_proof", tout << "New lemma\n"; display(tout, m_lemma); tout << "\n=========================\n";); - TRACE("nlsat_proof_sk", tout << "New lemma\n"; display_abst(tout, m_lemma); tout << "\n=========================\n";); - - if (m_lemma.empty()) { - TRACE("nlsat", tout << "empty clause generated\n";); - return false; // problem is unsat, empty clause was generated - } - - reset_marks(); // remove marks from the literals in m_lemmas. - TRACE("nlsat", tout << "new lemma:\n"; display(tout, m_lemma.size(), m_lemma.data()); tout << "\n"; - tout << "found_decision: " << found_decision << "\n";); - - if (m_check_lemmas) { - check_lemma(m_lemma.size(), m_lemma.data(), false, m_lemma_assumptions.get()); - } - - if (m_log_lemmas) - log_lemma(verbose_stream(), m_lemma.size(), m_lemma.data(), false); - - // There are two possibilities: - // 1) m_lemma contains only literals from previous stages, and they - // are false in the current interpretation. We make progress - // by returning to a previous stage with additional information (new clause) - // that forces us to select a new partial interpretation - // >>> Return to some previous stage (we may also backjump many decisions and stages). - // - // 2) m_lemma contains at most one literal from the current level (the last literal). - // Moreover, this literal was a decision, but the new lemma forces it to - // be assigned to a different value. - // >>> In this case, we remain in the same stage but, we add a new asserted literal - // in a previous scope level. We may backjump many decisions. - // - unsigned sz = m_lemma.size(); - clause * new_cls = nullptr; - if (!found_decision) { - // Case 1) - // We just have to find the maximal variable in m_lemma, and return to that stage - // Remark: the lemma may contain only boolean literals, in this case new_max_var == null_var; - var new_max_var = max_var(sz, m_lemma.data()); - TRACE("nlsat_resolve", tout << "backtracking to stage: " << new_max_var << ", curr: " << m_xk << "\n";); - undo_until_stage(new_max_var); - SASSERT(m_xk == new_max_var); - new_cls = mk_clause(sz, m_lemma.data(), true, m_lemma_assumptions.get()); - TRACE("nlsat", tout << "new_level: " << scope_lvl() << "\nnew_stage: " << new_max_var << "\n"; - if (new_max_var != null_var) m_display_var(tout, new_max_var) << "\n";); - } - else { - SASSERT(scope_lvl() >= 1); - // Case 2) - if (is_bool_lemma(m_lemma.size(), m_lemma.data())) { - // boolean lemma, we just backtrack until the last literal is unassigned. - bool_var max_bool_var = m_lemma[m_lemma.size()-1].var(); - undo_until_unassigned(max_bool_var); - } - else { - // We must find the maximal decision level in literals in the first sz-1 positions that - // are at the same stage. If all these literals are from previous stages, - // we just backtrack the current level. - unsigned new_lvl = find_new_level_arith_lemma(m_lemma.size(), m_lemma.data()); - TRACE("nlsat", tout << "backtracking to new level: " << new_lvl << ", curr: " << m_scope_lvl << "\n";); - undo_until_level(new_lvl); - } - - if (lemma_is_clause(*conflict_clause)) { - TRACE("nlsat", tout << "found decision literal in conflict clause\n";); - VERIFY(process_clause(*conflict_clause, true)); - return true; - } - new_cls = mk_clause(sz, m_lemma.data(), true, m_lemma_assumptions.get()); - } - NLSAT_VERBOSE(display(verbose_stream(), *new_cls) << "\n";); - if (!process_clause(*new_cls, true)) { - TRACE("nlsat", tout << "new clause triggered another conflict, restarting conflict resolution...\n"; - display(tout, *new_cls) << "\n"; - ); - // we are still in conflict - conflict_clause = new_cls; - goto start; - } - TRACE("nlsat_resolve_done", display_assignment(tout);); - return true; - } - - bool lemma_is_clause(clause const& cls) const { - bool same = (m_lemma.size() == cls.size()); - for (unsigned i = 0; same && i < m_lemma.size(); ++i) { - same = m_lemma[i] == cls[i]; - } - return same; - } - - - // ----------------------- - // - // Debugging - // - // ----------------------- - - bool check_watches() const { -#ifdef Z3DEBUG - for (var x = 0; x < num_vars(); x++) { - clause_vector const & cs = m_watches[x]; - unsigned sz = cs.size(); - for (unsigned i = 0; i < sz; i++) { - SASSERT(max_var(*(cs[i])) == x); - } - } -#endif - return true; - } - - bool check_bwatches() const { -#ifdef Z3DEBUG - for (bool_var b = 0; b < m_bwatches.size(); b++) { - clause_vector const & cs = m_bwatches[b]; - unsigned sz = cs.size(); - for (unsigned i = 0; i < sz; i++) { - clause const & c = *(cs[i]); - SASSERT(max_var(c) == null_var); - SASSERT(max_bvar(c) == b); - } - } -#endif - return true; - } - - bool check_invariant() const { - SASSERT(check_watches()); - SASSERT(check_bwatches()); - return true; - } - - bool check_satisfied(clause_vector const & cs) const { - unsigned sz = cs.size(); - for (unsigned i = 0; i < sz; i++) { - clause const & c = *(cs[i]); - if (!is_satisfied(c)) { - TRACE("nlsat", tout << "not satisfied\n"; display(tout, c); tout << "\n";); - return false; - } - } - return true; - } - - bool check_satisfied() const { - TRACE("nlsat", tout << "bk: b" << m_bk << ", xk: x" << m_xk << "\n"; if (m_xk != null_var) { m_display_var(tout, m_xk); tout << "\n"; }); - unsigned num = m_atoms.size(); - if (m_bk != null_bool_var) - num = m_bk; - for (bool_var b = 0; b < num; b++) { - if (!check_satisfied(m_bwatches[b])) { - UNREACHABLE(); - return false; - } - } - if (m_xk != null_var) { - for (var x = 0; x < m_xk; x++) { - if (!check_satisfied(m_watches[x])) { - UNREACHABLE(); - return false; - } - } - } - return true; - } - - // ----------------------- - // - // Statistics - // - // ----------------------- - - void collect_statistics(statistics & st) { - st.update("nlsat conflicts", m_stats.m_conflicts); - st.update("nlsat propagations", m_stats.m_propagations); - st.update("nlsat decisions", m_stats.m_decisions); - st.update("nlsat restarts", m_stats.m_restarts); - st.update("nlsat stages", m_stats.m_stages); - st.update("nlsat simplifications", m_stats.m_simplifications); - st.update("nlsat irrational assignments", m_stats.m_irrational_assignments); - } - - void reset_statistics() { - m_stats.reset(); - } - - // ----------------------- - // - // Variable reordering - // - // ----------------------- - - struct var_info_collector { - pmanager & pm; - atom_vector const & m_atoms; - var_vector m_shuffle; - unsigned_vector m_max_degree; - unsigned_vector m_num_occs; - - var_info_collector(pmanager & _pm, atom_vector const & atoms, unsigned num_vars): - pm(_pm), - m_atoms(atoms) { - m_max_degree.resize(num_vars, 0); - m_num_occs.resize(num_vars, 0); - } - - var_vector m_vars; - void collect(poly * p) { - m_vars.reset(); - pm.vars(p, m_vars); - unsigned sz = m_vars.size(); - for (unsigned i = 0; i < sz; i++) { - var x = m_vars[i]; - unsigned k = pm.degree(p, x); - m_num_occs[x]++; - if (k > m_max_degree[x]) - m_max_degree[x] = k; - } - } - - void collect(literal l) { - bool_var b = l.var(); - atom * a = m_atoms[b]; - if (a == nullptr) - return; - if (a->is_ineq_atom()) { - unsigned sz = to_ineq_atom(a)->size(); - for (unsigned i = 0; i < sz; i++) { - collect(to_ineq_atom(a)->p(i)); - } - } - else { - collect(to_root_atom(a)->p()); - } - } - - void collect(clause const & c) { - unsigned sz = c.size(); - for (unsigned i = 0; i < sz; i++) - collect(c[i]); - } - - void collect(clause_vector const & cs) { - unsigned sz = cs.size(); - for (unsigned i = 0; i < sz; i++) - collect(*(cs[i])); - } - - std::ostream& display(std::ostream & out, display_var_proc const & proc) { - unsigned sz = m_num_occs.size(); - for (unsigned i = 0; i < sz; i++) { - proc(out, i); out << " -> " << m_max_degree[i] << " : " << m_num_occs[i] << "\n"; - } - return out; - } - }; - - struct reorder_lt { - var_info_collector const & m_info; - reorder_lt(var_info_collector const & info):m_info(info) {} - bool operator()(var x, var y) const { - // high degree first - if (m_info.m_max_degree[x] < m_info.m_max_degree[y]) - return false; - if (m_info.m_max_degree[x] > m_info.m_max_degree[y]) - return true; - // more constrained first - if (m_info.m_num_occs[x] < m_info.m_num_occs[y]) - return false; - if (m_info.m_num_occs[x] > m_info.m_num_occs[y]) - return true; - return m_info.m_shuffle[x] < m_info.m_shuffle[y]; - } - }; - - // Order variables by degree and number of occurrences - void heuristic_reorder() { - unsigned num = num_vars(); - var_info_collector collector(m_pm, m_atoms, num); - collector.collect(m_clauses); - collector.collect(m_learned); - init_shuffle(collector.m_shuffle); - TRACE("nlsat_reorder", collector.display(tout, m_display_var);); - var_vector new_order; - for (var x = 0; x < num; x++) - new_order.push_back(x); - - std::sort(new_order.begin(), new_order.end(), reorder_lt(collector)); - TRACE("nlsat_reorder", - tout << "new order: "; for (unsigned i = 0; i < num; i++) tout << new_order[i] << " "; tout << "\n";); - var_vector perm; - perm.resize(num, 0); - for (var x = 0; x < num; x++) { - perm[new_order[x]] = x; - } - reorder(perm.size(), perm.data()); - SASSERT(check_invariant()); - } - - void init_shuffle(var_vector& p) { - unsigned num = num_vars(); - for (var x = 0; x < num; x++) - p.push_back(x); - - random_gen r(++m_random_seed); - shuffle(p.size(), p.data(), r); - } - - void shuffle_vars() { - var_vector p; - init_shuffle(p); - reorder(p.size(), p.data()); - } - - bool can_reorder() const { - return all_of(m_learned, [&](clause* c) { return !has_root_atom(*c); }) - && all_of(m_clauses, [&](clause* c) { return !has_root_atom(*c); }); - } - - /** - \brief Reorder variables using the giving permutation. - p maps internal variables to their new positions - */ - - - void reorder(unsigned sz, var const * p) { - - remove_learned_roots(); - SASSERT(can_reorder()); - TRACE("nlsat_reorder", tout << "solver before variable reorder\n"; display(tout); - display_vars(tout); - tout << "\npermutation:\n"; - for (unsigned i = 0; i < sz; i++) tout << p[i] << " "; tout << "\n"; - ); - // verbose_stream() << "\npermutation: " << p[0] << " count " << count << " " << m_rlimit.is_canceled() << "\n"; - reinit_cache(); - SASSERT(num_vars() == sz); - TRACE("nlsat_bool_assignment_bug", tout << "before reset watches\n"; display_bool_assignment(tout);); - reset_watches(); - assignment new_assignment(m_am); - for (var x = 0; x < num_vars(); x++) { - if (m_assignment.is_assigned(x)) - new_assignment.set(p[x], m_assignment.value(x)); - } - var_vector new_inv_perm; - new_inv_perm.resize(sz); - // the undo_until_size(0) statement erases the Boolean assignment. - // undo_until_size(0) - undo_until_stage(null_var); - m_cache.reset(); -#ifdef Z3DEBUG - for (var x = 0; x < num_vars(); x++) { - SASSERT(m_watches[x].empty()); - } -#endif - // update m_perm mapping - for (unsigned ext_x = 0; ext_x < sz; ext_x++) { - // p: internal -> new pos - // m_perm: internal -> external - // m_inv_perm: external -> internal - new_inv_perm[ext_x] = p[m_inv_perm[ext_x]]; - m_perm.set(new_inv_perm[ext_x], ext_x); - } - bool_vector is_int; - is_int.swap(m_is_int); - for (var x = 0; x < sz; x++) { - m_is_int.setx(p[x], is_int[x], false); - SASSERT(m_infeasible[x] == 0); - } - m_inv_perm.swap(new_inv_perm); -#ifdef Z3DEBUG - for (var x = 0; x < num_vars(); x++) { - SASSERT(x == m_inv_perm[m_perm[x]]); - SASSERT(m_watches[x].empty()); - } -#endif - m_pm.rename(sz, p); - for (auto& b : m_bounds) - b.x = p[b.x]; - TRACE("nlsat_bool_assignment_bug", tout << "before reinit cache\n"; display_bool_assignment(tout);); - reinit_cache(); - m_assignment.swap(new_assignment); - reattach_arith_clauses(m_clauses); - reattach_arith_clauses(m_learned); - TRACE("nlsat_reorder", tout << "solver after variable reorder\n"; display(tout); display_vars(tout);); - } - - - /** - \brief Restore variable order. - */ - void restore_order() { - // m_perm: internal -> external - // m_inv_perm: external -> internal - var_vector p; - p.append(m_perm); - reorder(p.size(), p.data()); -#ifdef Z3DEBUG - for (var x = 0; x < num_vars(); x++) { - SASSERT(m_perm[x] == x); - SASSERT(m_inv_perm[x] == x); - } -#endif - } - - /** - \brief After variable reordering some lemmas containing root atoms may be ill-formed. - */ - void remove_learned_roots() { - unsigned j = 0; - for (clause* c : m_learned) { - if (has_root_atom(*c)) { - del_clause(c); - } - else { - m_learned[j++] = c; - } - } - m_learned.shrink(j); - } - - /** - \brief Return true if the clause contains an ill formed root atom - */ - bool has_root_atom(clause const & c) const { - for (literal lit : c) { - bool_var b = lit.var(); - atom * a = m_atoms[b]; - if (a && a->is_root_atom()) - return true; - } - return false; - } - - /** - \brief reinsert all polynomials in the unique cache - */ - void reinit_cache() { - reinit_cache(m_clauses); - reinit_cache(m_learned); - for (atom* a : m_atoms) - reinit_cache(a); - } - void reinit_cache(clause_vector const & cs) { - for (clause* c : cs) - reinit_cache(*c); - } - void reinit_cache(clause const & c) { - for (literal l : c) - reinit_cache(l); - } - void reinit_cache(literal l) { - bool_var b = l.var(); - reinit_cache(m_atoms[b]); - } - void reinit_cache(atom* a) { - if (a == nullptr) { - - } - else if (a->is_ineq_atom()) { - var max = 0; - unsigned sz = to_ineq_atom(a)->size(); - for (unsigned i = 0; i < sz; i++) { - poly * p = to_ineq_atom(a)->p(i); - VERIFY(m_cache.mk_unique(p) == p); - var x = m_pm.max_var(p); - if (x > max) - max = x; - } - a->m_max_var = max; - } - else { - poly * p = to_root_atom(a)->p(); - VERIFY(m_cache.mk_unique(p) == p); - a->m_max_var = m_pm.max_var(p); - } - } - - void reset_watches() { - unsigned num = num_vars(); - for (var x = 0; x < num; x++) { - m_watches[x].reset(); - } - } - - void reattach_arith_clauses(clause_vector const & cs) { - for (clause* cp : cs) { - var x = max_var(*cp); - if (x != null_var) - m_watches[x].push_back(cp); - } - } - - // ----------------------- - // - // Solver initialization - // - // ----------------------- - - struct degree_lt { - unsigned_vector & m_degrees; - degree_lt(unsigned_vector & ds):m_degrees(ds) {} - bool operator()(unsigned i1, unsigned i2) const { - if (m_degrees[i1] < m_degrees[i2]) - return true; - if (m_degrees[i1] > m_degrees[i2]) - return false; - return i1 < i2; - } - }; - - unsigned_vector m_cs_degrees; - unsigned_vector m_cs_p; - void sort_clauses_by_degree(unsigned sz, clause ** cs) { - if (sz <= 1) - return; - TRACE("nlsat_reorder_clauses", tout << "before:\n"; for (unsigned i = 0; i < sz; i++) { display(tout, *(cs[i])); tout << "\n"; }); - m_cs_degrees.reset(); - m_cs_p.reset(); - for (unsigned i = 0; i < sz; i++) { - m_cs_p.push_back(i); - m_cs_degrees.push_back(degree(*(cs[i]))); - } - std::sort(m_cs_p.begin(), m_cs_p.end(), degree_lt(m_cs_degrees)); - TRACE("nlsat_reorder_clauses", tout << "permutation: "; ::display(tout, m_cs_p.begin(), m_cs_p.end()); tout << "\n";); - apply_permutation(sz, cs, m_cs_p.data()); - TRACE("nlsat_reorder_clauses", tout << "after:\n"; for (unsigned i = 0; i < sz; i++) { display(tout, *(cs[i])); tout << "\n"; }); - } - - void sort_watched_clauses() { - unsigned num = num_vars(); - for (unsigned i = 0; i < num; i++) { - clause_vector & ws = m_watches[i]; - sort_clauses_by_degree(ws.size(), ws.data()); - } - } - - // ----------------------- - // - // Full dimensional - // - // A problem is in the full dimensional fragment if it does - // not contain equalities or non-strict inequalities. - // - // ----------------------- - - bool is_full_dimensional(literal l) const { - atom * a = m_atoms[l.var()]; - if (a == nullptr) - return true; - switch (a->get_kind()) { - case atom::EQ: return l.sign(); - case atom::LT: return !l.sign(); - case atom::GT: return !l.sign(); - case atom::ROOT_EQ: return l.sign(); - case atom::ROOT_LT: return !l.sign(); - case atom::ROOT_GT: return !l.sign(); - case atom::ROOT_LE: return l.sign(); - case atom::ROOT_GE: return l.sign(); - default: - UNREACHABLE(); - return false; - } - } - - bool is_full_dimensional(clause const & c) const { - for (literal l : c) { - if (!is_full_dimensional(l)) - return false; - } - return true; - } - - bool is_full_dimensional(clause_vector const & cs) const { - for (clause* c : cs) { - if (!is_full_dimensional(*c)) - return false; - } - return true; - } - - bool is_full_dimensional() const { - return is_full_dimensional(m_clauses); - } - - - // ----------------------- - // - // Simplification - // - // ----------------------- - - // solve simple equalities - // TBD WU-Reit decomposition? - - // - elim_unconstrained - // - solve_eqs - // - fm - - /** - \brief isolate variables in unit equalities. - Assume a clause is c == v*p + q - and the context implies p > 0 - - replace v by -q/p - remove clause c, - The for other occurrences of v, - replace v*r + v*v*r' > 0 by - by p*p*v*r + p*p*v*v*r' > 0 - by p*q*r + q*q*r' > 0 - - The method ignores lemmas and assumes constraints don't use roots. - */ - - - - // Eliminated variables are tracked in m_bounds. - // Each element in m_bounds tracks the eliminated variable and an upper or lower bound - // that has to be satisfied. Variables that are eliminated through equalities are tracked - // by non-strict bounds. A satisfiable solution is required to provide an evaluation that - // is consistent with the bounds. For equalities, the non-strict lower or upper bound can - // always be assigned as a value to the variable. - - void fix_patch() { - m_lo.reset(); m_hi.reset(); - for (auto& b : m_bounds) - m_assignment.reset(b.x); - for (unsigned i = m_bounds.size(); i-- > 0; ) - fix_patch(m_bounds[i]); - } - - // x is unassigned, lo < x -> x <- lo + 1 - // x is unassigned, x < hi -> x <- hi - 1 - // x is unassigned, lo <= x -> x <- lo - // x is unassigned, x <= hi -> x <- hi - // x is assigned above hi, lo is strict lo < x < hi -> set x <- (lo + hi)/2 - // x is assigned below hi, above lo -> no-op - // x is assigned below lo, hi is strict lo < x < hi -> set x <-> (lo + hi)/2 - // x is assigned above hi, x <= hi -> x <- hi - // x is assigned blow lo, lo <= x -> x <- lo - void fix_patch(bound_constraint& b) { - var x = b.x; - scoped_anum Av(m_am), Bv(m_am), val(m_am); - m_pm.eval(b.A, m_assignment, Av); - m_pm.eval(b.B, m_assignment, Bv); - m_am.neg(Bv); - val = Bv / Av; - // Ax >= B - // is-lower : A > 0 - // is-upper: A < 0 - // x <- B / A - bool is_lower = m_am.is_pos(Av); - TRACE("nlsat", - m_display_var(tout << "patch v" << x << " ", x) << "\n"; - if (m_assignment.is_assigned(x)) m_am.display(tout << "previous value: ", m_assignment.value(x)); tout << "\n"; - m_am.display(tout << "updated value: ", val); tout << "\n"; - ); - - if (!m_assignment.is_assigned(x)) { - if (!b.is_strict) - m_assignment.set_core(x, val); - else if (is_lower) - m_assignment.set_core(x, val + 1); - else - m_assignment.set_core(x, val - 1); - } - else { - auto& aval = m_assignment.value(x); - if (is_lower) { - // lo < value(x), lo < x -> x is unchanged - if (b.is_strict && m_am.lt(val, aval)) - ; - else if (!b.is_strict && m_am.le(val, aval)) - ; - else if (!b.is_strict) - m_assignment.set_core(x, val); - // aval < lo < x, hi is unassigned: x <- lo + 1 - else if (!m_hi.is_assigned(x)) - m_assignment.set_core(x, val + 1); - // aval < lo < x, hi is assigned: x <- (lo + hi) / 2 - else { - scoped_anum mid(m_am); - m_am.add(m_hi.value(x), val, mid); - mid = mid / 2; - m_assignment.set_core(x, mid); - } - } - else { - // dual to lower bounds - if (b.is_strict && m_am.lt(aval, val)) - ; - else if (!b.is_strict && m_am.le(aval, val)) - ; - else if (!b.is_strict) - m_assignment.set_core(x, val); - else if (!m_lo.is_assigned(x)) - m_assignment.set_core(x, val - 1); - else { - scoped_anum mid(m_am); - m_am.add(m_lo.value(x), val, mid); - mid = mid / 2; - m_assignment.set_core(x, mid); - } - } - } - - if (is_lower) { - if (!m_lo.is_assigned(x) || m_am.lt(m_lo.value(x), val)) - m_lo.set_core(x, val); - } - else { - if (!m_hi.is_assigned(x) || m_am.gt(m_hi.value(x), val)) - m_hi.set_core(x, val); - } - } - - bool is_unit_ineq(clause const& c) const { - return - c.size() == 1 && - m_atoms[c[0].var()] && - m_atoms[c[0].var()]->is_ineq_atom(); - } - - bool is_unit_eq(clause const& c) const { - return - is_unit_ineq(c) && - !c[0].sign() && - m_atoms[c[0].var()]->is_eq(); - } - - /** - \brief determine whether the clause is a comparison v > k or v < k', where k >= 0 or k' <= 0. - */ - lbool is_cmp0(clause const& c, var& v) { - if (!is_unit_ineq(c)) - return l_undef; - literal lit = c[0]; - ineq_atom const& a = *to_ineq_atom(m_atoms[lit.var()]); - bool sign = lit.sign(); - poly * p0; - if (!is_single_poly(a, p0)) - return l_undef; - if (m_pm.is_var(p0, v)) { - if (!sign && a.get_kind() == atom::GT) { - return l_true; - } - if (!sign && a.get_kind() == atom::LT) { - return l_false; - } - return l_undef; - } - polynomial::scoped_numeral n(m_pm.m()); - if (m_pm.is_var_num(p0, v, n)) { - // x - k > 0 - if (!sign && a.get_kind() == atom::GT && m_pm.m().is_nonneg(n)) { - return l_true; - } - // x + k < 0 - if (!sign && a.get_kind() == atom::LT && m_pm.m().is_nonpos(n)) { - return l_false; - } - // !(x + k > 0) - if (sign && a.get_kind() == atom::GT && m_pm.m().is_pos(n)) { - return l_false; - } - // !(x - k < 0) - if (sign && a.get_kind() == atom::LT && m_pm.m().is_neg(n)) { - return l_true; - } - } - return l_undef; - } - - bool is_single_poly(ineq_atom const& a, poly*& p) { - unsigned sz = a.size(); - return sz == 1 && a.is_odd(0) && (p = a.p(0), true); - } - - bool is_unit(polynomial_ref const& p) { - if (!m_pm.is_const(p)) - return false; - auto const& c = m_pm.coeff(p, 0); - return m_pm.m().is_one(c) || m_pm.m().is_minus_one(c); - } - - // ----------------------- - // - // Pretty printing - // - // ----------------------- - - std::ostream& display_num_assignment(std::ostream & out, display_var_proc const & proc) const { - for (var x = 0; x < num_vars(); x++) { - if (m_assignment.is_assigned(x)) { - proc(out, x); - out << " -> "; - m_am.display_decimal(out, m_assignment.value(x)); - out << "\n"; - } - } - return out; - } - - std::ostream& display_bool_assignment(std::ostream & out) const { - unsigned sz = m_atoms.size(); - for (bool_var b = 0; b < sz; b++) { - if (m_atoms[b] == nullptr && m_bvalues[b] != l_undef) { - out << "b" << b << " -> " << (m_bvalues[b] == l_true ? "true" : "false") << " @" << m_levels[b] << "\n"; - } - else if (m_atoms[b] != nullptr && m_bvalues[b] != l_undef) { - display(out << "b" << b << " ", *m_atoms[b]) << " -> " << (m_bvalues[b] == l_true ? "true" : "false") << " @" << m_levels[b] << "\n"; - } - } - TRACE("nlsat_bool_assignment", - for (bool_var b = 0; b < sz; b++) { - out << "b" << b << " -> " << m_bvalues[b] << " "; - if (m_atoms[b]) display(out, *m_atoms[b]); - out << "\n"; - }); - return out; - } - - bool display_mathematica_assignment(std::ostream & out) const { - bool first = true; - for (var x = 0; x < num_vars(); x++) { - if (m_assignment.is_assigned(x)) { - if (first) - first = false; - else - out << " && "; - out << "x" << x << " == "; - m_am.display_mathematica(out, m_assignment.value(x)); - } - } - return !first; - } - - std::ostream& display_num_assignment(std::ostream & out) const { - return display_num_assignment(out, m_display_var); - } - - std::ostream& display_assignment(std::ostream& out) const { - display_bool_assignment(out); - display_num_assignment(out); - return out; - } - - std::ostream& display(std::ostream& out, justification j) const { - switch (j.get_kind()) { - case justification::CLAUSE: - display(out, *j.get_clause()) << "\n"; - break; - case justification::LAZY: { - lazy_justification const& lz = *j.get_lazy(); - display_not(out, lz.num_lits(), lz.lits()) << "\n"; - for (unsigned i = 0; i < lz.num_clauses(); ++i) { - display(out, lz.clause(i)) << "\n"; - } - break; - } - default: - out << j.get_kind() << "\n"; - break; - } - return out; - } - - bool m_display_eval = false; - std::ostream& display_eval(std::ostream& out, justification j) { - flet _display(m_display_eval, true); - return display(out, j); - } - - std::ostream& display_ineq(std::ostream & out, ineq_atom const & a, display_var_proc const & proc, bool use_star = false) const { - unsigned sz = a.size(); - for (unsigned i = 0; i < sz; i++) { - if (use_star && i > 0) - out << "*"; - bool is_even = a.is_even(i); - if (is_even || sz > 1) - out << "("; - display_polynomial(out, a.p(i), proc, use_star); - if (is_even || sz > 1) - out << ")"; - if (is_even) - out << "^2"; - } - switch (a.get_kind()) { - case atom::LT: out << " < 0"; break; - case atom::GT: out << " > 0"; break; - case atom::EQ: out << " = 0"; break; - default: UNREACHABLE(); break; - } - return out; - } - - std::ostream& display_mathematica(std::ostream & out, ineq_atom const & a) const { - unsigned sz = a.size(); - for (unsigned i = 0; i < sz; i++) { - if (i > 0) - out << "*"; - bool is_even = a.is_even(i); - if (sz > 1) - out << "("; - if (is_even) - out << "("; - m_pm.display(out, a.p(i), display_var_proc(), true); - if (is_even) - out << "^2)"; - if (sz > 1) - out << ")"; - } - switch (a.get_kind()) { - case atom::LT: out << " < 0"; break; - case atom::GT: out << " > 0"; break; - case atom::EQ: out << " == 0"; break; - default: UNREACHABLE(); break; - } - return out; - } - - std::ostream& display_polynomial_smt2(std::ostream & out, poly const* p, display_var_proc const & proc) const { - return m_pm.display_smt2(out, p, proc); - } - - std::ostream& display_ineq_smt2(std::ostream & out, ineq_atom const & a, display_var_proc const & proc) const { - switch (a.get_kind()) { - case atom::LT: out << "(< "; break; - case atom::GT: out << "(> "; break; - case atom::EQ: out << "(= "; break; - default: UNREACHABLE(); break; - } - unsigned sz = a.size(); - if (sz > 1) - out << "(* "; - for (unsigned i = 0; i < sz; i++) { - if (i > 0) out << " "; - if (a.is_even(i)) { - out << "(* "; - display_polynomial_smt2(out, a.p(i), proc); - out << " "; - display_polynomial_smt2(out, a.p(i), proc); - out << ")"; - } - else { - display_polynomial_smt2(out, a.p(i), proc); - } - } - if (sz > 1) - out << ")"; - out << " 0)"; - return out; - } - - std::ostream& display_poly_root(std::ostream& out, char const* y, root_atom const& a, display_var_proc const& proc) const { - out << "(exists (("; proc(out,a.x()); out << " Real))\n"; - out << "(and (= " << y << " "; - proc(out, a.x()); - out << ") (= 0 "; - display_polynomial_smt2(out, a.p(), proc); - out << ")))\n"; - return out; - } - - std::ostream& display_binary_smt2(std::ostream& out, poly const* p1, char const* rel, poly const* p2, display_var_proc const& proc) const { - out << "(" << rel << " "; - display_polynomial_smt2(out, p1, proc); - out << " "; - display_polynomial_smt2(out, p2, proc); - out << ")"; - return out; - } - - - std::ostream& display_linear_root_smt2(std::ostream & out, root_atom const & a, display_var_proc const & proc) const { - polynomial_ref A(m_pm), B(m_pm), Z(m_pm), Ax(m_pm); - polynomial::scoped_numeral zero(m_qm); - m_pm.m().set(zero, 0); - A = m_pm.derivative(a.p(), a.x()); - B = m_pm.neg(m_pm.substitute(a.p(), a.x(), zero)); - Z = m_pm.mk_zero(); - - Ax = m_pm.mul(m_pm.mk_polynomial(a.x()), A); - - // x < root[1](ax + b) == (a > 0 => ax + b < 0) & (a < 0 => ax + b > 0) - // x < root[1](ax + b) == (a > 0 => ax < -b) & (a < 0 => ax > -b) - - char const* rel1 = "<", *rel2 = ">"; - switch (a.get_kind()) { - case atom::ROOT_LT: rel1 = "<"; rel2 = ">"; break; - case atom::ROOT_GT: rel1 = ">"; rel2 = "<"; break; - case atom::ROOT_LE: rel1 = "<="; rel2 = ">="; break; - case atom::ROOT_GE: rel1 = ">="; rel2 = "<="; break; - case atom::ROOT_EQ: rel1 = rel2 = "="; break; - default: UNREACHABLE(); break; - } - - out << "(and "; - out << "(=> "; display_binary_smt2(out, A, ">", Z, proc); display_binary_smt2(out, Ax, rel1, B, proc); out << ") "; - out << "(=> "; display_binary_smt2(out, A, "<", Z, proc); display_binary_smt2(out, Ax, rel2, B, proc); out << ") "; - out << ")"; - - return out; - } - - - std::ostream& display_root_smt2(std::ostream& out, root_atom const& a, display_var_proc const& proc) const { - if (a.i() == 1 && m_pm.degree(a.p(), a.x()) == 1) - return display_linear_root_smt2(out, a, proc); -#if 1 - out << "(exists ("; - for (unsigned j = 0; j < a.i(); ++j) { - std::string y = std::string("y") + std::to_string(j); - out << "(" << y << " Real) "; - } - out << ")\n"; - out << "(and\n"; - for (unsigned j = 0; j < a.i(); ++j) { - std::string y = std::string("y") + std::to_string(j); - display_poly_root(out, y.c_str(), a, proc); - } - for (unsigned j = 0; j + 1 < a.i(); ++j) { - std::string y1 = std::string("y") + std::to_string(j); - std::string y2 = std::string("y") + std::to_string(j+1); - out << "(< " << y1 << " " << y2 << ")\n"; - } - - std::string yn = "y" + std::to_string(a.i() - 1); - - // TODO we need (forall z : z < yn . p(z) => z = y1 or ... z = y_{n-1}) - // to say y1, .., yn are the first n distinct roots. - // - out << "(forall ((z Real)) (=> (and (< z " << yn << ") "; display_poly_root(out, "z", a, proc) << ") "; - if (a.i() == 1) { - out << "false))\n"; - } - else { - out << "(or "; - for (unsigned j = 0; j + 1 < a.i(); ++j) { - std::string y1 = std::string("y") + std::to_string(j); - out << "(= z " << y1 << ") "; - } - out << ")))\n"; - } - switch (a.get_kind()) { - case atom::ROOT_LT: out << "(< "; proc(out, a.x()); out << " " << yn << ")"; break; - case atom::ROOT_GT: out << "(> "; proc(out, a.x()); out << " " << yn << ")"; break; - case atom::ROOT_LE: out << "(<= "; proc(out, a.x()); out << " " << yn << ")"; break; - case atom::ROOT_GE: out << "(>= "; proc(out, a.x()); out << " " << yn << ")"; break; - case atom::ROOT_EQ: out << "(= "; proc(out, a.x()); out << " " << yn << ")"; NOT_IMPLEMENTED_YET(); break; - default: UNREACHABLE(); break; - } - out << "))"; - return out; -#endif - - - return display_root(out, a, proc); - } - - std::ostream& display_root(std::ostream & out, root_atom const & a, display_var_proc const & proc) const { - proc(out, a.x()); - switch (a.get_kind()) { - case atom::ROOT_LT: out << " < "; break; - case atom::ROOT_GT: out << " > "; break; - case atom::ROOT_LE: out << " <= "; break; - case atom::ROOT_GE: out << " >= "; break; - case atom::ROOT_EQ: out << " = "; break; - default: UNREACHABLE(); break; - } - out << "root[" << a.i() << "]("; - display_polynomial(out, a.p(), proc); - out << ")"; - return out; - } - - struct mathematica_var_proc : public display_var_proc { - var m_x; - public: - mathematica_var_proc(var x):m_x(x) {} - std::ostream& operator()(std::ostream & out, var x) const override { - if (m_x == x) - return out << "#1"; - else - return out << "x" << x; - } - }; - - std::ostream& display_mathematica(std::ostream & out, root_atom const & a) const { - out << "x" << a.x(); - switch (a.get_kind()) { - case atom::ROOT_LT: out << " < "; break; - case atom::ROOT_GT: out << " > "; break; - case atom::ROOT_LE: out << " <= "; break; - case atom::ROOT_GE: out << " >= "; break; - case atom::ROOT_EQ: out << " == "; break; - default: UNREACHABLE(); break; - } - out << "Root["; - display_polynomial(out, a.p(), mathematica_var_proc(a.x()), true); - out << " &, " << a.i() << "]"; - return out; - } - - std::ostream& display(std::ostream & out, atom const & a, display_var_proc const & proc) const { - if (a.is_ineq_atom()) - return display_ineq(out, static_cast(a), proc); - else - return display_root(out, static_cast(a), proc); - } - - std::ostream& display(std::ostream & out, atom const & a) const { - return display(out, a, m_display_var); - } - - std::ostream& display_mathematica(std::ostream & out, atom const & a) const { - if (a.is_ineq_atom()) - return display_mathematica(out, static_cast(a)); - else - return display_mathematica(out, static_cast(a)); - } - - std::ostream& display_smt2(std::ostream & out, atom const & a, display_var_proc const & proc) const { - if (a.is_ineq_atom()) - return display_ineq_smt2(out, static_cast(a), proc); - else - return display_root_smt2(out, static_cast(a), proc); - } - - std::ostream& display_atom(std::ostream & out, bool_var b, display_var_proc const & proc) const { - if (b == 0) - out << "true"; - else if (m_atoms[b] == 0) - out << "b" << b; - else - display(out, *(m_atoms[b]), proc); - return out; - } - - std::ostream& display_atom(std::ostream & out, bool_var b) const { - return display_atom(out, b, m_display_var); - } - - std::ostream& display_mathematica_atom(std::ostream & out, bool_var b) const { - if (b == 0) - out << "(0 < 1)"; - else if (m_atoms[b] == 0) - out << "b" << b; - else - display_mathematica(out, *(m_atoms[b])); - return out; - } - - std::ostream& display_smt2_atom(std::ostream & out, bool_var b, display_var_proc const & proc) const { - if (b == 0) - out << "true"; - else if (m_atoms[b] == 0) - out << "b" << b; - else - display_smt2(out, *(m_atoms[b]), proc); - return out; - } - - std::ostream& display(std::ostream & out, literal l, display_var_proc const & proc) const { - if (l.sign()) { - bool_var b = l.var(); - out << "!"; - if (m_atoms[b] != 0) - out << "("; - display_atom(out, b, proc); - if (m_atoms[b] != 0) - out << ")"; - } - else { - display_atom(out, l.var(), proc); - } - return out; - } - - std::ostream& display(std::ostream & out, literal l) const { - return display(out, l, m_display_var); - } - - std::ostream& display_smt2(std::ostream & out, literal l) const { - return display_smt2(out, l, m_display_var); - } - - std::ostream& display_mathematica(std::ostream & out, literal l) const { - if (l.sign()) { - bool_var b = l.var(); - out << "!"; - if (m_atoms[b] != 0) - out << "("; - display_mathematica_atom(out, b); - if (m_atoms[b] != 0) - out << ")"; - } - else { - display_mathematica_atom(out, l.var()); - } - return out; - } - - std::ostream& display_smt2(std::ostream & out, literal l, display_var_proc const & proc) const { - if (l.sign()) { - bool_var b = l.var(); - out << "(not "; - display_smt2_atom(out, b, proc); - out << ")"; - } - else { - display_smt2_atom(out, l.var(), proc); - } - return out; - } - - std::ostream& display_assumptions(std::ostream & out, _assumption_set s) const { - if (!m_display_assumption) - return out; - vector deps; - m_asm.linearize(s, deps); - bool first = true; - for (auto dep : deps) { - if (first) first = false; else out << " "; - (*m_display_assumption)(out, dep); - } - return out; - } - - std::ostream& display(std::ostream & out, unsigned num, literal const * ls, display_var_proc const & proc) const { - for (unsigned i = 0; i < num; i++) { - if (i > 0) - out << " or "; - display(out, ls[i], proc); - } - return out; - } - - std::ostream& display(std::ostream & out, unsigned num, literal const * ls) const { - return display(out, num, ls, m_display_var); - } - - std::ostream& display_not(std::ostream & out, unsigned num, literal const * ls, display_var_proc const & proc) const { - for (unsigned i = 0; i < num; i++) { - if (i > 0) - out << " or "; - display(out, ~ls[i], proc); - } - return out; - } - - std::ostream& display_not(std::ostream & out, unsigned num, literal const * ls) const { - return display_not(out, num, ls, m_display_var); - } - - std::ostream& display(std::ostream & out, scoped_literal_vector const & cs) { - return display(out, cs.size(), cs.data(), m_display_var); - } - - std::ostream& display(std::ostream & out, clause const & c, display_var_proc const & proc) const { - if (c.assumptions() != nullptr) { - display_assumptions(out, static_cast<_assumption_set>(c.assumptions())); - out << " |- "; - } - return display(out, c.size(), c.data(), proc); - } - - std::ostream& display(std::ostream & out, clause const & c) const { - return display(out, c, m_display_var); - } - - - std::ostream& display_polynomial(std::ostream& out, poly* p, display_var_proc const & proc, bool use_star = false) const { - if (m_display_eval) { - polynomial_ref q(m_pm); - q = p; - for (var x = 0; x < num_vars(); x++) - if (m_assignment.is_assigned(x)) { - auto& a = m_assignment.value(x); - if (!m_am.is_rational(a)) - continue; - mpq r; - m_am.to_rational(a, r); - q = m_pm.substitute(q, 1, &x, &r); - } - m_pm.display(out, q, proc, use_star); - } - else - m_pm.display(out, p, proc, use_star); - return out; - } - - // -- - - std::ostream& display_smt2(std::ostream & out, unsigned n, literal const* ls) const { - return display_smt2(out, n, ls, display_var_proc()); - } - - - std::ostream& display_smt2(std::ostream & out, unsigned num, literal const * ls, display_var_proc const & proc) const { - if (num == 0) { - out << "false"; - } - else if (num == 1) { - display_smt2(out, ls[0], proc); - } - else { - out << "(or"; - for (unsigned i = 0; i < num; i++) { - out << " "; - display_smt2(out, ls[i], proc); - } - out << ")"; - } - return out; - } - - std::ostream& display_smt2(std::ostream & out, clause const & c, display_var_proc const & proc = display_var_proc()) const { - return display_smt2(out, c.size(), c.data(), proc); - } - - std::ostream& display_abst(std::ostream & out, literal l) const { - if (l.sign()) { - bool_var b = l.var(); - out << "!"; - if (b == true_bool_var) - out << "true"; - else - out << "b" << b; - } - else { - out << "b" << l.var(); - } - return out; - } - - std::ostream& display_abst(std::ostream & out, unsigned num, literal const * ls) const { - for (unsigned i = 0; i < num; i++) { - if (i > 0) - out << " or "; - display_abst(out, ls[i]); - } - return out; - } - - std::ostream& display_abst(std::ostream & out, scoped_literal_vector const & cs) const { - return display_abst(out, cs.size(), cs.data()); - } - - std::ostream& display_abst(std::ostream & out, clause const & c) const { - return display_abst(out, c.size(), c.data()); - } - - std::ostream& display_mathematica(std::ostream & out, clause const & c) const { - out << "("; - unsigned sz = c.size(); - for (unsigned i = 0; i < sz; i++) { - if (i > 0) - out << " || "; - display_mathematica(out, c[i]); - } - out << ")"; - return out; - } - - // Debugging support: - // Display generated lemma in Mathematica format. - // Mathematica must reduce lemma to True (modulo resource constraints). - std::ostream& display_mathematica_lemma(std::ostream & out, unsigned num, literal const * ls, bool include_assignment = false) const { - out << "Resolve[ForAll[{"; - // var definition - for (unsigned i = 0; i < num_vars(); i++) { - if (i > 0) - out << ", "; - out << "x" << i; - } - out << "}, "; - if (include_assignment) { - out << "!("; - if (!display_mathematica_assignment(out)) - out << "0 < 1"; // nothing was printed - out << ") || "; - } - for (unsigned i = 0; i < num; i++) { - if (i > 0) - out << " || "; - display_mathematica(out, ls[i]); - } - out << "], Reals]\n"; // end of exists - return out; - } - - std::ostream& display(std::ostream & out, clause_vector const & cs, display_var_proc const & proc) const { - for (clause* c : cs) { - display(out, *c, proc) << "\n"; - } - return out; - } - - std::ostream& display(std::ostream & out, clause_vector const & cs) const { - return display(out, cs, m_display_var); - } - - std::ostream& display_mathematica(std::ostream & out, clause_vector const & cs) const { - unsigned sz = cs.size(); - for (unsigned i = 0; i < sz; i++) { - if (i > 0) out << ",\n"; - display_mathematica(out << " ", *(cs[i])); - } - return out; - } - - std::ostream& display_abst(std::ostream & out, clause_vector const & cs) const { - for (clause* c : cs) { - display_abst(out, *c) << "\n"; - } - return out; - } - - std::ostream& display(std::ostream & out, display_var_proc const & proc) const { - display(out, m_clauses, proc); - if (!m_learned.empty()) { - display(out << "Lemmas:\n", m_learned, proc); - } - return out; - } - - std::ostream& display_mathematica(std::ostream & out) const { - return display_mathematica(out << "{\n", m_clauses) << "}\n"; - } - - std::ostream& display_abst(std::ostream & out) const { - display_abst(out, m_clauses); - if (!m_learned.empty()) { - display_abst(out << "Lemmas:\n", m_learned); - } - return out; - } - - std::ostream& display(std::ostream & out) const { - display(out, m_display_var); - display_assignment(out << "assignment:\n"); - return out << "---\n"; - } - - std::ostream& display_vars(std::ostream & out) const { - for (unsigned i = 0; i < num_vars(); i++) { - out << i << " -> "; m_display_var(out, i); out << "\n"; - } - return out; - } - - std::ostream& display_smt2_arith_decls(std::ostream & out) const { - unsigned sz = m_is_int.size(); - for (unsigned i = 0; i < sz; i++) { - if (is_int(i)) { - out << "(declare-fun "; m_display_var(out, i) << " () Int)\n"; - } - else { - out << "(declare-fun "; m_display_var(out, i) << " () Real)\n"; - } - } - return out; - } - - std::ostream& display_smt2_bool_decls(std::ostream & out) const { - unsigned sz = m_atoms.size(); - for (unsigned i = 0; i < sz; i++) { - if (m_atoms[i] == nullptr) - out << "(declare-fun b" << i << " () Bool)\n"; - } - return out; - } - - std::ostream& display_smt2(std::ostream & out) const { - display_smt2_bool_decls(out); - display_smt2_arith_decls(out); - out << "(assert (and true\n"; - for (clause* c : m_clauses) { - display_smt2(out, *c, m_display_var) << "\n"; - } - out << "))\n" << std::endl; - return out; - } - }; - - solver::solver(reslimit& rlim, params_ref const & p, bool incremental) { - m_ctx = alloc(ctx, rlim, p, incremental); - m_imp = alloc(imp, *this, *m_ctx); - } - - solver::solver(ctx& ctx) { - m_ctx = nullptr; - m_imp = alloc(imp, *this, ctx); - } - - solver::~solver() { - dealloc(m_imp); - dealloc(m_ctx); - } - - lbool solver::check() { - return m_imp->check(); - } - - lbool solver::check(literal_vector& assumptions) { - return m_imp->check(assumptions); - } - - void solver::get_core(vector& assumptions) { - return m_imp->get_core(assumptions); - } - - void solver::reset() { - m_imp->reset(); - } - - - void solver::updt_params(params_ref const & p) { - m_imp->updt_params(p); - } - - - void solver::collect_param_descrs(param_descrs & d) { - algebraic_numbers::manager::collect_param_descrs(d); - nlsat_params::collect_param_descrs(d); - } - - unsynch_mpq_manager & solver::qm() { - return m_imp->m_qm; - } - - anum_manager & solver::am() { - return m_imp->m_am; - } - - pmanager & solver::pm() { - return m_imp->m_pm; - } - - void solver::set_display_var(display_var_proc const & proc) { - m_imp->m_display_var.m_proc = &proc; - } - - void solver::set_display_assumption(display_assumption_proc const& proc) { - m_imp->m_display_assumption = &proc; - } - - - unsigned solver::num_vars() const { - return m_imp->num_vars(); - } - - bool solver::is_int(var x) const { - return m_imp->is_int(x); - } - - bool_var solver::mk_bool_var() { - return m_imp->mk_bool_var(); - } - - literal solver::mk_true() { - return literal(0, false); - } - - atom * solver::bool_var2atom(bool_var b) { - return m_imp->m_atoms[b]; - } - - void solver::vars(literal l, var_vector& vs) { - m_imp->vars(l, vs); - } - - atom_vector const& solver::get_atoms() { - return m_imp->m_atoms; - } - - atom_vector const& solver::get_var2eq() { - return m_imp->m_var2eq; - } - - evaluator& solver::get_evaluator() { - return m_imp->m_evaluator; - } - - explain& solver::get_explain() { - return m_imp->m_explain; - } - - void solver::reorder(unsigned sz, var const* p) { - m_imp->reorder(sz, p); - } - - void solver::restore_order() { - m_imp->restore_order(); - } - - void solver::set_rvalues(assignment const& as) { - m_imp->m_assignment.copy(as); - } - - void solver::get_rvalues(assignment& as) { - as.copy(m_imp->m_assignment); - } - - void solver::get_bvalues(svector const& bvars, svector& vs) { - vs.reset(); - for (bool_var b : bvars) { - vs.reserve(b + 1, l_undef); - if (!m_imp->m_atoms[b]) { - vs[b] = m_imp->m_bvalues[b]; - } - } - TRACE("nlsat", display(tout);); - } - - void solver::set_bvalues(svector const& vs) { - TRACE("nlsat", display(tout);); - for (bool_var b = 0; b < vs.size(); ++b) { - if (vs[b] != l_undef) { - m_imp->m_bvalues[b] = vs[b]; - SASSERT(!m_imp->m_atoms[b]); - } - } -#if 0 - m_imp->m_bvalues.reset(); - m_imp->m_bvalues.append(vs); - m_imp->m_bvalues.resize(m_imp->m_atoms.size(), l_undef); - for (unsigned i = 0; i < m_imp->m_atoms.size(); ++i) { - atom* a = m_imp->m_atoms[i]; - SASSERT(!a); - if (a) { - m_imp->m_bvalues[i] = to_lbool(m_imp->m_evaluator.eval(a, false)); - } - } -#endif - TRACE("nlsat", display(tout);); - } - - void solver::del_clause(clause* c) { - m_imp->del_clause(c); - } - - var solver::mk_var(bool is_int) { - return m_imp->mk_var(is_int); - } - - bool_var solver::mk_ineq_atom(atom::kind k, unsigned sz, poly * const * ps, bool const * is_even) { - return m_imp->mk_ineq_atom(k, sz, ps, is_even); - } - - literal solver::mk_ineq_literal(atom::kind k, unsigned sz, poly * const * ps, bool const * is_even, bool simplify) { - return m_imp->mk_ineq_literal(k, sz, ps, is_even, simplify); - } - - bool_var solver::mk_root_atom(atom::kind k, var x, unsigned i, poly * p) { - return m_imp->mk_root_atom(k, x, i, p); - } - - void solver::inc_ref(bool_var b) { - m_imp->inc_ref(b); - } - - void solver::dec_ref(bool_var b) { - m_imp->dec_ref(b); - } - - void solver::inc_ref(assumption a) { - m_imp->inc_ref(static_cast(a)); - } - - void solver::dec_ref(assumption a) { - m_imp->dec_ref(static_cast(a)); - } - - void solver::mk_clause(unsigned num_lits, literal * lits, assumption a) { - return m_imp->mk_external_clause(num_lits, lits, a); - } - - std::ostream& solver::display(std::ostream & out) const { - return m_imp->display(out); - } - - std::ostream& solver::display(std::ostream & out, literal l) const { - return m_imp->display(out, l); - } - - std::ostream& solver::display(std::ostream & out, unsigned n, literal const* ls) const { - for (unsigned i = 0; i < n; ++i) { - display(out, ls[i]); - out << "; "; - } - return out; - } - - std::ostream& solver::display(std::ostream & out, literal_vector const& ls) const { - return display(out, ls.size(), ls.data()); - } - - std::ostream& solver::display_smt2(std::ostream & out, literal l) const { - return m_imp->display_smt2(out, l); - } - - std::ostream& solver::display_smt2(std::ostream & out, unsigned n, literal const* ls) const { - for (unsigned i = 0; i < n; ++i) { - display_smt2(out, ls[i]); - out << " "; - } - return out; - } - - std::ostream& solver::display(std::ostream& out, clause const& c) const { - return m_imp->display(out, c); - } - - std::ostream& solver::display_smt2(std::ostream & out) const { - return m_imp->display_smt2(out); - } - - std::ostream& solver::display_smt2(std::ostream & out, literal_vector const& ls) const { - return display_smt2(out, ls.size(), ls.data()); - } - - std::ostream& solver::display(std::ostream & out, var x) const { - return m_imp->m_display_var(out, x); - } - - std::ostream& solver::display(std::ostream & out, atom const& a) const { - return m_imp->display(out, a, m_imp->m_display_var); - } - - display_var_proc const & solver::display_proc() const { - return m_imp->m_display_var; - } - - anum const & solver::value(var x) const { - if (m_imp->m_assignment.is_assigned(x)) - return m_imp->m_assignment.value(x); - return m_imp->m_zero; - } - - lbool solver::bvalue(bool_var b) const { - return m_imp->m_bvalues[b]; - } - - lbool solver::value(literal l) const { - return m_imp->value(l); - } - - bool solver::is_interpreted(bool_var b) const { - return m_imp->m_atoms[b] != 0; - } - - void solver::reset_statistics() { - return m_imp->reset_statistics(); - } - - void solver::collect_statistics(statistics & st) { - return m_imp->collect_statistics(st); - } - - clause* solver::mk_clause(unsigned n, literal const* lits, bool learned, internal_assumption a) { - return m_imp->mk_clause(n, lits, learned, static_cast(a)); - } - - void solver::inc_simplify() { - m_imp->m_stats.m_simplifications++; - } - - bool solver::has_root_atom(clause const& c) const { - return m_imp->has_root_atom(c); - } - - void solver::add_bound(bound_constraint const& c) { - m_imp->m_bounds.push_back(c); - } - - assumption solver::join(assumption a, assumption b) { - return (m_imp->m_asm.mk_join(static_cast(a), static_cast(b))); - } - -}; +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + nlsat_solver.cpp + +Abstract: + + Nonlinear arithmetic satisfiability procedure. The procedure is + complete for nonlinear real arithmetic, but it also has limited + support for integers. + +Author: + + Leonardo de Moura (leonardo) 2012-01-02. + +Revision History: + +--*/ +#include "util/z3_exception.h" +#include "util/chashtable.h" +#include "util/id_gen.h" +#include "util/map.h" +#include "util/dependency.h" +#include "util/permutation.h" +#include "math/polynomial/algebraic_numbers.h" +#include "math/polynomial/polynomial_cache.h" +#include "nlsat/nlsat_solver.h" +#include "nlsat/nlsat_clause.h" +#include "nlsat/nlsat_assignment.h" +#include "nlsat/nlsat_justification.h" +#include "nlsat/nlsat_evaluator.h" +#include "nlsat/nlsat_explain.h" +#include "nlsat/nlsat_params.hpp" +#include "nlsat/nlsat_simplify.h" +#include "nlsat/nlsat_simple_checker.h" +#include "nlsat/nlsat_variable_ordering_strategy.h" + +#define NLSAT_EXTRA_VERBOSE + +#ifdef NLSAT_EXTRA_VERBOSE +#define NLSAT_VERBOSE(CODE) IF_VERBOSE(10, CODE) +#else +#define NLSAT_VERBOSE(CODE) ((void)0) +#endif + +namespace nlsat { + + + typedef chashtable ineq_atom_table; + typedef chashtable root_atom_table; + + // for apply_permutation procedure + void swap(clause * & c1, clause * & c2) noexcept { + std::swap(c1, c2); + } + + struct solver::ctx { + params_ref m_params; + reslimit& m_rlimit; + small_object_allocator m_allocator; + unsynch_mpq_manager m_qm; + pmanager m_pm; + anum_manager m_am; + bool m_incremental; + ctx(reslimit& rlim, params_ref const & p, bool incremental): + m_params(p), + m_rlimit(rlim), + m_allocator("nlsat"), + m_pm(rlim, m_qm, &m_allocator), + m_am(rlim, m_qm, p, &m_allocator), + m_incremental(incremental) + {} + }; + + struct solver::imp { + + + struct dconfig { + typedef imp value_manager; + typedef small_object_allocator allocator; + typedef void* value; + static const bool ref_count = false; + }; + + typedef dependency_manager assumption_manager; + typedef assumption_manager::dependency* _assumption_set; + + typedef obj_ref assumption_set_ref; + + + typedef polynomial::cache cache; + typedef ptr_vector interval_set_vector; + + + + ctx& m_ctx; + solver& m_solver; + reslimit& m_rlimit; + small_object_allocator& m_allocator; + bool m_incremental; + unsynch_mpq_manager& m_qm; + pmanager& m_pm; + cache m_cache; + anum_manager& m_am; + mutable assumption_manager m_asm; + assignment m_assignment, m_lo, m_hi; // partial interpretation + evaluator m_evaluator; + interval_set_manager & m_ism; + ineq_atom_table m_ineq_atoms; + root_atom_table m_root_atoms; + + + vector m_bounds; + + id_gen m_cid_gen; + clause_vector m_clauses; // set of clauses + clause_vector m_learned; // set of learned clauses + clause_vector m_valids; + + unsigned m_num_bool_vars; + atom_vector m_atoms; // bool_var -> atom + svector m_bvalues; // boolean assignment + unsigned_vector m_levels; // bool_var -> level + svector m_justifications; + vector m_bwatches; // bool_var (that are not attached to atoms) -> clauses where it is maximal + bool_vector m_dead; // mark dead boolean variables + id_gen m_bid_gen; + + simplify m_simplify; + + bool_vector m_is_int; // m_is_int[x] is true if variable is integer + vector m_watches; // var -> clauses where variable is maximal + interval_set_vector m_infeasible; // var -> to a set of interval where the variable cannot be assigned to. + atom_vector m_var2eq; // var -> to asserted equality + var_vector m_perm; // var -> var permutation of the variables + var_vector m_inv_perm; + // m_perm: internal -> external + // m_inv_perm: external -> internal + struct perm_display_var_proc : public display_var_proc { + var_vector & m_perm; + display_var_proc m_default_display_var; + display_var_proc const * m_proc; // display external var ids + perm_display_var_proc(var_vector & perm): + m_perm(perm), + m_proc(nullptr) { + } + std::ostream& operator()(std::ostream & out, var x) const override { + if (m_proc == nullptr) + m_default_display_var(out, x); + else + (*m_proc)(out, m_perm[x]); + return out; + } + }; + perm_display_var_proc m_display_var; + + display_assumption_proc const* m_display_assumption; + struct display_literal_assumption : public display_assumption_proc { + imp& i; + literal_vector const& lits; + display_literal_assumption(imp& i, literal_vector const& lits): i(i), lits(lits) {} + std::ostream& operator()(std::ostream& out, assumption a) const override { + if (lits.begin() <= a && a < lits.end()) { + out << *((literal const*)a); + } + else if (i.m_display_assumption) { + (*i.m_display_assumption)(out, a); + } + return out; + } + + }; + struct scoped_display_assumptions { + imp& i; + display_assumption_proc const* m_save; + scoped_display_assumptions(imp& i, display_assumption_proc const& p): i(i), m_save(i.m_display_assumption) { + i.m_display_assumption = &p; + } + ~scoped_display_assumptions() { + i.m_display_assumption = m_save; + } + }; + + explain m_explain; + + bool_var m_bk; // current Boolean variable we are processing + var m_xk; // current arith variable we are processing + + unsigned m_scope_lvl; + + struct bvar_assignment {}; + struct stage {}; + struct trail { + enum kind { BVAR_ASSIGNMENT, INFEASIBLE_UPDT, NEW_LEVEL, NEW_STAGE, UPDT_EQ }; + kind m_kind; + union { + bool_var m_b; + interval_set * m_old_set; + atom * m_old_eq; + }; + trail(bool_var b, bvar_assignment):m_kind(BVAR_ASSIGNMENT), m_b(b) {} + trail(interval_set * old_set):m_kind(INFEASIBLE_UPDT), m_old_set(old_set) {} + trail(bool s, stage):m_kind(s ? NEW_STAGE : NEW_LEVEL) {} + trail(atom * a):m_kind(UPDT_EQ), m_old_eq(a) {} + }; + svector m_trail; + + anum m_zero; + + // configuration + unsigned long long m_max_memory; + unsigned m_lazy; // how lazy the solver is: 0 - satisfy all learned clauses, 1 - process only unit and empty learned clauses, 2 - use only conflict clauses for resolving conflicts + bool m_simplify_cores; + bool m_reorder; + bool m_randomize; + bool m_random_order; + unsigned m_random_seed; + bool m_inline_vars; + bool m_log_lemmas; + bool m_check_lemmas; + unsigned m_max_conflicts; + unsigned m_lemma_count; + bool m_simple_check = false; + unsigned m_variable_ordering_strategy; + bool m_set_0_more; + bool m_cell_sample; + + struct stats { + unsigned m_simplifications; + unsigned m_restarts; + unsigned m_conflicts; + unsigned m_propagations; + unsigned m_decisions; + unsigned m_stages; + unsigned m_irrational_assignments; // number of irrational witnesses + void reset() { memset(this, 0, sizeof(*this)); } + stats() { reset(); } + }; + // statistics + stats m_stats; + + imp(solver& s, ctx& c): + m_ctx(c), + m_solver(s), + m_rlimit(c.m_rlimit), + m_allocator(c.m_allocator), + m_incremental(c.m_incremental), + m_qm(c.m_qm), + m_pm(c.m_pm), + m_cache(m_pm), + m_am(c.m_am), + m_asm(*this, m_allocator), + m_assignment(m_am), m_lo(m_am), m_hi(m_am), + m_evaluator(s, m_assignment, m_pm, m_allocator), + m_ism(m_evaluator.ism()), + m_num_bool_vars(0), + m_simplify(s, m_atoms, m_clauses, m_learned, m_pm), + m_display_var(m_perm), + m_display_assumption(nullptr), + m_explain(s, m_assignment, m_cache, m_atoms, m_var2eq, m_evaluator, nlsat_params(c.m_params).cell_sample()), + m_scope_lvl(0), + m_lemma(s), + m_lazy_clause(s), + m_lemma_assumptions(m_asm) { + updt_params(c.m_params); + reset_statistics(); + mk_true_bvar(); + m_lemma_count = 0; + } + + ~imp() { + clear(); + } + + void mk_true_bvar() { + bool_var b = mk_bool_var(); + SASSERT(b == true_bool_var); + literal true_lit(b, false); + mk_clause(1, &true_lit, false, nullptr); + } + + void updt_params(params_ref const & _p) { + nlsat_params p(_p); + m_max_memory = p.max_memory(); + m_lazy = p.lazy(); + m_simplify_cores = p.simplify_conflicts(); + bool min_cores = p.minimize_conflicts(); + m_reorder = p.reorder(); + m_randomize = p.randomize(); + m_max_conflicts = p.max_conflicts(); + m_random_order = p.shuffle_vars(); + m_random_seed = p.seed(); + m_inline_vars = p.inline_vars(); + m_log_lemmas = p.log_lemmas(); + m_check_lemmas = p.check_lemmas(); + m_variable_ordering_strategy = p.variable_ordering_strategy(); + + + m_cell_sample = p.cell_sample(); + + + m_ism.set_seed(m_random_seed); + m_explain.set_simplify_cores(m_simplify_cores); + m_explain.set_minimize_cores(min_cores); + m_explain.set_factor(p.factor()); + m_am.updt_params(p.p); + } + + void reset() { + m_explain.reset(); + m_lemma.reset(); + m_lazy_clause.reset(); + undo_until_size(0); + del_clauses(); + del_unref_atoms(); + m_cache.reset(); + m_assignment.reset(); + m_lo.reset(); + m_hi.reset(); + } + + void clear() { + m_explain.reset(); + m_lemma.reset(); + m_lazy_clause.reset(); + undo_until_size(0); + del_clauses(); + del_unref_atoms(); + } + + void checkpoint() { + if (!m_rlimit.inc()) throw solver_exception(m_rlimit.get_cancel_msg()); + if (memory::get_allocation_size() > m_max_memory) throw solver_exception(Z3_MAX_MEMORY_MSG); + } + + // ----------------------- + // + // Basic + // + // ----------------------- + + unsigned num_bool_vars() const { + return m_num_bool_vars; + } + + unsigned num_vars() const { + return m_is_int.size(); + } + + bool is_int(var x) const { + return m_is_int[x]; + } + + void inc_ref(assumption) {} + + void dec_ref(assumption) {} + + void inc_ref(_assumption_set a) { + if (a != nullptr) m_asm.inc_ref(a); + } + + void dec_ref(_assumption_set a) { + if (a != nullptr) m_asm.dec_ref(a); + } + + void inc_ref(bool_var b) { + if (b == null_bool_var) + return; + atom * a = m_atoms[b]; + if (a == nullptr) + return; + TRACE("ref", display(tout << "inc: " << b << " " << a->ref_count() << " ", *a) << "\n";); + a->inc_ref(); + } + + void inc_ref(literal l) { + inc_ref(l.var()); + } + + void dec_ref(bool_var b) { + if (b == null_bool_var) + return; + atom * a = m_atoms[b]; + if (a == nullptr) + return; + SASSERT(a->ref_count() > 0); + a->dec_ref(); + TRACE("ref", display(tout << "dec: " << b << " " << a->ref_count() << " ", *a) << "\n";); + if (a->ref_count() == 0) + del(a); + } + + void dec_ref(literal l) { + dec_ref(l.var()); + } + + bool is_arith_atom(bool_var b) const { return m_atoms[b] != nullptr; } + + bool is_arith_literal(literal l) const { return is_arith_atom(l.var()); } + + var max_var(poly const * p) const { + return m_pm.max_var(p); + } + + var max_var(bool_var b) const { + if (!is_arith_atom(b)) + return null_var; + else + return m_atoms[b]->max_var(); + } + + var max_var(literal l) const { + return max_var(l.var()); + } + + /** + \brief Return the maximum variable occurring in cls. + */ + var max_var(unsigned sz, literal const * cls) const { + var x = null_var; + for (unsigned i = 0; i < sz; i++) { + literal l = cls[i]; + if (is_arith_literal(l)) { + var y = max_var(l); + if (x == null_var || y > x) + x = y; + } + } + return x; + } + + var max_var(clause const & cls) const { + return max_var(cls.size(), cls.data()); + } + + /** + \brief Return the maximum Boolean variable occurring in cls. + */ + bool_var max_bvar(clause const & cls) const { + bool_var b = null_bool_var; + for (literal l : cls) { + if (b == null_bool_var || l.var() > b) + b = l.var(); + } + return b; + } + + /** + \brief Return the degree of the maximal variable of the given atom + */ + unsigned degree(atom const * a) const { + if (a->is_ineq_atom()) { + unsigned max = 0; + unsigned sz = to_ineq_atom(a)->size(); + var x = a->max_var(); + for (unsigned i = 0; i < sz; i++) { + unsigned d = m_pm.degree(to_ineq_atom(a)->p(i), x); + if (d > max) + max = d; + } + return max; + } + else { + return m_pm.degree(to_root_atom(a)->p(), a->max_var()); + } + } + + /** + \brief Return the degree of the maximal variable in c + */ + unsigned degree(clause const & c) const { + var x = max_var(c); + if (x == null_var) + return 0; + unsigned max = 0; + for (literal l : c) { + atom const * a = m_atoms[l.var()]; + if (a == nullptr) + continue; + unsigned d = degree(a); + if (d > max) + max = d; + } + return max; + } + + // ----------------------- + // + // Variable, Atoms, Clauses & Assumption creation + // + // ----------------------- + + bool_var mk_bool_var_core() { + bool_var b = m_bid_gen.mk(); + m_num_bool_vars++; + m_atoms .setx(b, nullptr, nullptr); + m_bvalues .setx(b, l_undef, l_undef); + m_levels .setx(b, UINT_MAX, UINT_MAX); + m_justifications.setx(b, null_justification, null_justification); + m_bwatches .setx(b, clause_vector(), clause_vector()); + m_dead .setx(b, false, true); + return b; + } + + bool_var mk_bool_var() { + return mk_bool_var_core(); + } + + var mk_var(bool is_int) { + var x = m_pm.mk_var(); + register_var(x, is_int); + return x; + } + void register_var(var x, bool is_int) { + SASSERT(x == num_vars()); + m_is_int. push_back(is_int); + m_watches. push_back(clause_vector()); + m_infeasible.push_back(nullptr); + m_var2eq. push_back(nullptr); + m_perm. push_back(x); + m_inv_perm. push_back(x); + SASSERT(m_is_int.size() == m_watches.size()); + SASSERT(m_is_int.size() == m_infeasible.size()); + SASSERT(m_is_int.size() == m_var2eq.size()); + SASSERT(m_is_int.size() == m_perm.size()); + SASSERT(m_is_int.size() == m_inv_perm.size()); + } + + bool_vector m_found_vars; + void vars(literal l, var_vector& vs) { + vs.reset(); + atom * a = m_atoms[l.var()]; + if (a == nullptr) { + + } + else if (a->is_ineq_atom()) { + unsigned sz = to_ineq_atom(a)->size(); + var_vector new_vs; + for (unsigned j = 0; j < sz; j++) { + m_found_vars.reset(); + m_pm.vars(to_ineq_atom(a)->p(j), new_vs); + for (unsigned i = 0; i < new_vs.size(); ++i) { + if (!m_found_vars.get(new_vs[i], false)) { + m_found_vars.setx(new_vs[i], true, false); + vs.push_back(new_vs[i]); + } + } + } + } + else { + m_pm.vars(to_root_atom(a)->p(), vs); + //vs.erase(max_var(to_root_atom(a)->p())); + vs.push_back(to_root_atom(a)->x()); + } + } + + void deallocate(ineq_atom * a) { + unsigned obj_sz = ineq_atom::get_obj_size(a->size()); + a->~ineq_atom(); + m_allocator.deallocate(obj_sz, a); + } + + void deallocate(root_atom * a) { + a->~root_atom(); + m_allocator.deallocate(sizeof(root_atom), a); + } + + void del(bool_var b) { + SASSERT(m_bwatches[b].empty()); + //SASSERT(m_bvalues[b] == l_undef); + m_num_bool_vars--; + m_dead[b] = true; + m_atoms[b] = nullptr; + m_bvalues[b] = l_undef; + m_bid_gen.recycle(b); + } + + void del(ineq_atom * a) { + CTRACE("nlsat_solver", a->ref_count() > 0, display(tout, *a) << "\n";); + // this triggers in too many benign cases: + // SASSERT(a->ref_count() == 0); + m_ineq_atoms.erase(a); + del(a->bvar()); + unsigned sz = a->size(); + for (unsigned i = 0; i < sz; i++) + m_pm.dec_ref(a->p(i)); + deallocate(a); + } + + void del(root_atom * a) { + SASSERT(a->ref_count() == 0); + m_root_atoms.erase(a); + del(a->bvar()); + m_pm.dec_ref(a->p()); + deallocate(a); + } + + void del(atom * a) { + if (a == nullptr) + return; + TRACE("nlsat_verbose", display(tout << "del: b" << a->m_bool_var << " " << a->ref_count() << " ", *a) << "\n";); + if (a->is_ineq_atom()) + del(to_ineq_atom(a)); + else + del(to_root_atom(a)); + } + + // Delete atoms with ref_count == 0 + void del_unref_atoms() { + for (auto* a : m_atoms) { + del(a); + } + } + + + ineq_atom* mk_ineq_atom(atom::kind k, unsigned sz, poly * const * ps, bool const * is_even, bool& is_new, bool simplify) { + SASSERT(sz >= 1); + SASSERT(k == atom::LT || k == atom::GT || k == atom::EQ); + int sign = 1; + polynomial_ref p(m_pm); + ptr_buffer uniq_ps; + var max = null_var; + for (unsigned i = 0; i < sz; i++) { + p = m_pm.flip_sign_if_lm_neg(ps[i]); + if (p.get() != ps[i] && !is_even[i]) { + sign = -sign; + } + var curr_max = max_var(p.get()); + if (curr_max > max || max == null_var) + max = curr_max; + if (sz == 1 && simplify) { + if (sign < 0) + k = atom::flip(k); + sign = 1; + polynomial::manager::ineq_type t = polynomial::manager::ineq_type::EQ; + switch (k) { + case atom::EQ: t = polynomial::manager::ineq_type::EQ; break; + case atom::LT: t = polynomial::manager::ineq_type::LT; break; + case atom::GT: t = polynomial::manager::ineq_type::GT; break; + default: UNREACHABLE(); break; + } + polynomial::var_vector vars; + m_pm.vars(p, vars); + bool all_int = all_of(vars, [&](var x) { return is_int(x); }); + if (!all_int) + t = polynomial::manager::ineq_type::EQ; + m_pm.gcd_simplify(p, t); + } + uniq_ps.push_back(m_cache.mk_unique(p)); + TRACE("nlsat_table_bug", tout << "p: " << p << ", uniq: " << uniq_ps.back() << "\n";); + //verbose_stream() << "p: " << p.get() << ", uniq: " << uniq_ps.back() << "\n"; + } + void * mem = m_allocator.allocate(ineq_atom::get_obj_size(sz)); + if (sign < 0) + k = atom::flip(k); + ineq_atom * tmp_atom = new (mem) ineq_atom(k, sz, uniq_ps.data(), is_even, max); + ineq_atom * atom = m_ineq_atoms.insert_if_not_there(tmp_atom); + CTRACE("nlsat_table_bug", tmp_atom != atom, ineq_atom::hash_proc h; + tout << "mk_ineq_atom hash: " << h(tmp_atom) << "\n"; display(tout, *tmp_atom, m_display_var) << "\n";); + CTRACE("nlsat_table_bug", atom->max_var() != max, display(tout << "nonmax: ", *atom, m_display_var) << "\n";); + SASSERT(atom->max_var() == max); + is_new = (atom == tmp_atom); + if (is_new) { + for (unsigned i = 0; i < sz; i++) { + m_pm.inc_ref(atom->p(i)); + } + } + else { + deallocate(tmp_atom); + } + return atom; + } + + bool_var mk_ineq_atom(atom::kind k, unsigned sz, poly * const * ps, bool const * is_even, bool simplify = false) { + bool is_new = false; + ineq_atom* atom = mk_ineq_atom(k, sz, ps, is_even, is_new, simplify); + if (!is_new) { + return atom->bvar(); + } + else { + bool_var b = mk_bool_var_core(); + m_atoms[b] = atom; + atom->m_bool_var = b; + TRACE("nlsat_verbose", display(tout << "create: b" << atom->m_bool_var << " ", *atom) << "\n";); + return b; + } + } + + literal mk_ineq_literal(atom::kind k, unsigned sz, poly * const * ps, bool const * is_even, bool simplify = false) { + SASSERT(k == atom::LT || k == atom::GT || k == atom::EQ); + bool is_const = true; + polynomial::manager::scoped_numeral cnst(m_pm.m()); + m_pm.m().set(cnst, 1); + for (unsigned i = 0; i < sz; ++i) { + if (m_pm.is_const(ps[i])) { + if (m_pm.is_zero(ps[i])) { + m_pm.m().set(cnst, 0); + is_const = true; + break; + } + auto const& c = m_pm.coeff(ps[i], 0); + m_pm.m().mul(cnst, c, cnst); + if (is_even[i] && m_pm.m().is_neg(c)) { + m_pm.m().neg(cnst); + } + } + else { + is_const = false; + } + } + if (is_const) { + if (m_pm.m().is_pos(cnst) && k == atom::GT) return true_literal; + if (m_pm.m().is_neg(cnst) && k == atom::LT) return true_literal; + if (m_pm.m().is_zero(cnst) && k == atom::EQ) return true_literal; + return false_literal; + } + return literal(mk_ineq_atom(k, sz, ps, is_even, simplify), false); + } + + bool_var mk_root_atom(atom::kind k, var x, unsigned i, poly * p) { + polynomial_ref p1(m_pm), uniq_p(m_pm); + p1 = m_pm.flip_sign_if_lm_neg(p); // flipping the sign of the polynomial will not change its roots. + uniq_p = m_cache.mk_unique(p1); + TRACE("nlsat_solver", tout << x << " " << p1 << " " << uniq_p << "\n";); + SASSERT(i > 0); + SASSERT(x >= max_var(p)); + SASSERT(k == atom::ROOT_LT || k == atom::ROOT_GT || k == atom::ROOT_EQ || k == atom::ROOT_LE || k == atom::ROOT_GE); + + void * mem = m_allocator.allocate(sizeof(root_atom)); + root_atom * new_atom = new (mem) root_atom(k, x, i, uniq_p); + root_atom * old_atom = m_root_atoms.insert_if_not_there(new_atom); + SASSERT(old_atom->max_var() == x); + if (old_atom != new_atom) { + deallocate(new_atom); + return old_atom->bvar(); + } + bool_var b = mk_bool_var_core(); + m_atoms[b] = new_atom; + new_atom->m_bool_var = b; + m_pm.inc_ref(new_atom->p()); + return b; + } + + void attach_clause(clause & cls) { + var x = max_var(cls); + if (x != null_var) { + m_watches[x].push_back(&cls); + } + else { + bool_var b = max_bvar(cls); + m_bwatches[b].push_back(&cls); + } + } + + void deattach_clause(clause & cls) { + var x = max_var(cls); + if (x != null_var) { + m_watches[x].erase(&cls); + } + else { + bool_var b = max_bvar(cls); + m_bwatches[b].erase(&cls); + } + } + + void deallocate(clause * cls) { + size_t obj_sz = clause::get_obj_size(cls->size()); + cls->~clause(); + m_allocator.deallocate(obj_sz, cls); + } + + void del_clause(clause * cls) { + deattach_clause(*cls); + m_cid_gen.recycle(cls->id()); + unsigned sz = cls->size(); + for (unsigned i = 0; i < sz; i++) + dec_ref((*cls)[i]); + _assumption_set a = static_cast<_assumption_set>(cls->assumptions()); + dec_ref(a); + deallocate(cls); + } + + void del_clause(clause * cls, clause_vector& clauses) { + clauses.erase(cls); + del_clause(cls); + } + + void del_clauses(ptr_vector & cs) { + for (clause* cp : cs) + del_clause(cp); + cs.reset(); + } + + void del_clauses() { + del_clauses(m_clauses); + del_clauses(m_learned); + del_clauses(m_valids); + } + + // We use a simple heuristic to sort literals + // - bool literals < arith literals + // - sort literals based on max_var + // - sort literal with the same max_var using degree + // break ties using the fact that ineqs are usually cheaper to process than eqs. + struct lit_lt { + imp & m; + lit_lt(imp & _m):m(_m) {} + + bool operator()(literal l1, literal l2) const { + atom * a1 = m.m_atoms[l1.var()]; + atom * a2 = m.m_atoms[l2.var()]; + if (a1 == nullptr && a2 == nullptr) + return l1.index() < l2.index(); + if (a1 == nullptr) + return true; + if (a2 == nullptr) + return false; + var x1 = a1->max_var(); + var x2 = a2->max_var(); + if (x1 < x2) + return true; + if (x1 > x2) + return false; + SASSERT(x1 == x2); + unsigned d1 = m.degree(a1); + unsigned d2 = m.degree(a2); + if (d1 < d2) + return true; + if (d1 > d2) + return false; + if (!a1->is_eq() && a2->is_eq()) + return true; + if (a1->is_eq() && !a2->is_eq()) + return false; + return l1.index() < l2.index(); + } + }; + + class scoped_bool_vars { + imp& s; + svector vec; + public: + scoped_bool_vars(imp& s):s(s) {} + ~scoped_bool_vars() { + for (bool_var v : vec) { + s.dec_ref(v); + } + } + void push_back(bool_var v) { + s.inc_ref(v); + vec.push_back(v); + } + bool_var const* begin() const { return vec.begin(); } + bool_var const* end() const { return vec.end(); } + bool_var operator[](bool_var v) const { return vec[v]; } + }; + + void check_lemma(unsigned n, literal const* cls, bool is_valid, assumption_set a) { + TRACE("nlsat", display(tout << "check lemma: ", n, cls) << "\n"; + display(tout);); + IF_VERBOSE(2, display(verbose_stream() << "check lemma " << (is_valid?"valid: ":"consequence: "), n, cls) << "\n"); + for (clause* c : m_learned) IF_VERBOSE(1, display(verbose_stream() << "lemma: ", *c) << "\n"); + scoped_suspend_rlimit _limit(m_rlimit); + ctx c(m_rlimit, m_ctx.m_params, m_ctx.m_incremental); + solver solver2(c); + imp& checker = *(solver2.m_imp); + checker.m_check_lemmas = false; + checker.m_log_lemmas = false; + checker.m_inline_vars = false; + + auto pconvert = [&](poly* p) { + return convert(m_pm, p, checker.m_pm); + }; + + // need to translate Boolean variables and literals + scoped_bool_vars tr(checker); + for (var x = 0; x < m_is_int.size(); ++x) { + checker.register_var(x, is_int(x)); + } + bool_var bv = 0; + tr.push_back(bv); + for (bool_var b = 1; b < m_atoms.size(); ++b) { + atom* a = m_atoms[b]; + if (a == nullptr) { + bv = checker.mk_bool_var(); + } + else if (a->is_ineq_atom()) { + ineq_atom& ia = *to_ineq_atom(a); + unsigned sz = ia.size(); + polynomial_ref_vector ps(checker.m_pm); + bool_vector is_even; + for (unsigned i = 0; i < sz; ++i) { + ps.push_back(pconvert(ia.p(i))); + is_even.push_back(ia.is_even(i)); + } + bv = checker.mk_ineq_atom(ia.get_kind(), sz, ps.data(), is_even.data()); + } + else if (a->is_root_atom()) { + root_atom& r = *to_root_atom(a); + if (r.x() >= max_var(r.p())) { + // permutation may be reverted after check completes, + // but then root atoms are not used in lemmas. + bv = checker.mk_root_atom(r.get_kind(), r.x(), r.i(), pconvert(r.p())); + } + } + else { + UNREACHABLE(); + } + tr.push_back(bv); + } + if (!is_valid) { + for (clause* c : m_clauses) { + if (!a && c->assumptions()) { + continue; + } + literal_vector lits; + for (literal lit : *c) { + lits.push_back(literal(tr[lit.var()], lit.sign())); + } + checker.mk_external_clause(lits.size(), lits.data(), nullptr); + } + } + for (unsigned i = 0; i < n; ++i) { + literal lit = cls[i]; + literal nlit(tr[lit.var()], !lit.sign()); + checker.mk_external_clause(1, &nlit, nullptr); + } + lbool r = checker.check(); + if (r == l_true) { + for (bool_var b : tr) { + literal lit(b, false); + IF_VERBOSE(0, checker.display(verbose_stream(), lit) << " := " << checker.value(lit) << "\n"); + TRACE("nlsat", checker.display(tout, lit) << " := " << checker.value(lit) << "\n";); + } + for (clause* c : m_learned) { + bool found = false; + for (literal lit: *c) { + literal tlit(tr[lit.var()], lit.sign()); + found |= checker.value(tlit) == l_true; + } + if (!found) { + IF_VERBOSE(0, display(verbose_stream() << "violdated clause: ", *c) << "\n"); + TRACE("nlsat", display(tout << "violdated clause: ", *c) << "\n";); + } + } + for (clause* c : m_valids) { + bool found = false; + for (literal lit: *c) { + literal tlit(tr[lit.var()], lit.sign()); + found |= checker.value(tlit) == l_true; + } + if (!found) { + IF_VERBOSE(0, display(verbose_stream() << "violdated tautology clause: ", *c) << "\n"); + TRACE("nlsat", display(tout << "violdated tautology clause: ", *c) << "\n";); + } + } + throw default_exception("lemma did not check"); + UNREACHABLE(); + } + } + + void log_lemma(std::ostream& out, clause const& cls) { + log_lemma(out, cls.size(), cls.data(), false); + } + + void log_lemma(std::ostream& out, unsigned n, literal const* cls, bool is_valid) { + ++m_lemma_count; + out << "(set-logic NRA)\n"; + if (is_valid) { + display_smt2_bool_decls(out); + display_smt2_arith_decls(out); + } + else + display_smt2(out); + for (unsigned i = 0; i < n; ++i) + display_smt2(out << "(assert ", ~cls[i]) << ")\n"; + display(out << "(echo \"#" << m_lemma_count << " ", n, cls) << "\")\n"; + out << "(check-sat)\n(reset)\n"; + + TRACE("nlsat", display(tout << "(echo \"#" << m_lemma_count << " ", n, cls) << "\")\n"); + } + + clause * mk_clause_core(unsigned num_lits, literal const * lits, bool learned, _assumption_set a) { + SASSERT(num_lits > 0); + unsigned cid = m_cid_gen.mk(); + void * mem = m_allocator.allocate(clause::get_obj_size(num_lits)); + clause * cls = new (mem) clause(cid, num_lits, lits, learned, a); + for (unsigned i = 0; i < num_lits; i++) + inc_ref(lits[i]); + inc_ref(a); + return cls; + } + + clause * mk_clause(unsigned num_lits, literal const * lits, bool learned, _assumption_set a) { + if (num_lits == 0) { + num_lits = 1; + lits = &false_literal; + } + SASSERT(num_lits > 0); + clause * cls = mk_clause_core(num_lits, lits, learned, a); + TRACE("nlsat_sort", display(tout << "mk_clause:\n", *cls) << "\n";); + std::sort(cls->begin(), cls->end(), lit_lt(*this)); + TRACE("nlsat", display(tout << " after sort:\n", *cls) << "\n";); + if (learned && m_log_lemmas) { + log_lemma(verbose_stream(), *cls); + } + if (learned && m_check_lemmas && false) { + check_lemma(cls->size(), cls->data(), false, cls->assumptions()); + } + if (learned) + m_learned.push_back(cls); + else + m_clauses.push_back(cls); + attach_clause(*cls); + return cls; + } + + void mk_external_clause(unsigned num_lits, literal const * lits, assumption a) { + _assumption_set as = nullptr; + if (a != nullptr) + as = m_asm.mk_leaf(a); + if (num_lits == 0) { + num_lits = 1; + lits = &false_literal; + } + mk_clause(num_lits, lits, false, as); + } + + // ----------------------- + // + // Search + // + // ----------------------- + + void save_assign_trail(bool_var b) { + m_trail.push_back(trail(b, bvar_assignment())); + } + + void save_set_updt_trail(interval_set * old_set) { + m_trail.push_back(trail(old_set)); + } + + void save_updt_eq_trail(atom * old_eq) { + m_trail.push_back(trail(old_eq)); + } + + void save_new_stage_trail() { + m_trail.push_back(trail(true, stage())); + } + + void save_new_level_trail() { + m_trail.push_back(trail(false, stage())); + } + + void undo_bvar_assignment(bool_var b) { + m_bvalues[b] = l_undef; + m_levels[b] = UINT_MAX; + del_jst(m_allocator, m_justifications[b]); + m_justifications[b] = null_justification; + if (m_atoms[b] == nullptr && b < m_bk) + m_bk = b; + } + + void undo_set_updt(interval_set * old_set) { + if (m_xk == null_var) + return; + var x = m_xk; + if (x < m_infeasible.size()) { + m_ism.dec_ref(m_infeasible[x]); + m_infeasible[x] = old_set; + } + } + + void undo_new_stage() { + if (m_xk == 0) { + m_xk = null_var; + } + else if (m_xk != null_var) { + m_xk--; + m_assignment.reset(m_xk); + } + } + + void undo_new_level() { + SASSERT(m_scope_lvl > 0); + m_scope_lvl--; + m_evaluator.pop(1); + } + + void undo_updt_eq(atom * a) { + if (m_var2eq.size() > m_xk) + m_var2eq[m_xk] = a; + } + + template + void undo_until(Predicate const & pred) { + while (pred() && !m_trail.empty()) { + trail & t = m_trail.back(); + switch (t.m_kind) { + case trail::BVAR_ASSIGNMENT: + undo_bvar_assignment(t.m_b); + break; + case trail::INFEASIBLE_UPDT: + undo_set_updt(t.m_old_set); + break; + case trail::NEW_STAGE: + undo_new_stage(); + break; + case trail::NEW_LEVEL: + undo_new_level(); + break; + case trail::UPDT_EQ: + undo_updt_eq(t.m_old_eq); + break; + default: + break; + } + m_trail.pop_back(); + } + } + + struct size_pred { + svector & m_trail; + unsigned m_old_size; + size_pred(svector & trail, unsigned old_size):m_trail(trail), m_old_size(old_size) {} + bool operator()() const { return m_trail.size() > m_old_size; } + }; + + // Keep undoing until trail has the given size + void undo_until_size(unsigned old_size) { + SASSERT(m_trail.size() >= old_size); + undo_until(size_pred(m_trail, old_size)); + } + + struct stage_pred { + var const & m_xk; + var m_target; + stage_pred(var const & xk, var target):m_xk(xk), m_target(target) {} + bool operator()() const { return m_xk != m_target; } + }; + + // Keep undoing until stage is new_xk + void undo_until_stage(var new_xk) { + undo_until(stage_pred(m_xk, new_xk)); + } + + struct level_pred { + unsigned const & m_scope_lvl; + unsigned m_new_lvl; + level_pred(unsigned const & scope_lvl, unsigned new_lvl):m_scope_lvl(scope_lvl), m_new_lvl(new_lvl) {} + bool operator()() const { return m_scope_lvl > m_new_lvl; } + }; + + // Keep undoing until level is new_lvl + void undo_until_level(unsigned new_lvl) { + undo_until(level_pred(m_scope_lvl, new_lvl)); + } + + struct unassigned_pred { + bool_var m_b; + svector const & m_bvalues; + unassigned_pred(svector const & bvalues, bool_var b): + m_b(b), + m_bvalues(bvalues) {} + bool operator()() const { return m_bvalues[m_b] != l_undef; } + }; + + // Keep undoing until b is unassigned + void undo_until_unassigned(bool_var b) { + undo_until(unassigned_pred(m_bvalues, b)); + SASSERT(m_bvalues[b] == l_undef); + } + + struct true_pred { + bool operator()() const { return true; } + }; + + void undo_until_empty() { + undo_until(true_pred()); + } + + /** + \brief Create a new scope level + */ + void new_level() { + m_evaluator.push(); + m_scope_lvl++; + save_new_level_trail(); + } + + /** + \brief Return the value of the given literal that was assigned by the search + engine. + */ + lbool assigned_value(literal l) const { + bool_var b = l.var(); + if (l.sign()) + return ~m_bvalues[b]; + else + return m_bvalues[b]; + } + + /** + \brief Assign literal using the given justification + */ + void assign(literal l, justification j) { + TRACE("nlsat_assign", + display(tout << "assigning literal: ", l); + display(tout << " <- ", j);); + + SASSERT(assigned_value(l) == l_undef); + SASSERT(j != null_justification); + SASSERT(!j.is_null()); + if (j.is_decision()) + m_stats.m_decisions++; + else + m_stats.m_propagations++; + bool_var b = l.var(); + m_bvalues[b] = to_lbool(!l.sign()); + m_levels[b] = m_scope_lvl; + m_justifications[b] = j; + save_assign_trail(b); + updt_eq(b, j); + TRACE("nlsat_assign", tout << "b" << b << " -> " << m_bvalues[b] << "\n";); + } + + /** + \brief Create a "case-split" + */ + void decide(literal l) { + new_level(); + assign(l, decided_justification); + } + + /** + \brief Return the value of a literal as defined in Dejan and Leo's paper. + */ + lbool value(literal l) { + lbool val = assigned_value(l); + if (val != l_undef) { + TRACE("nlsat_verbose", display(tout << " assigned value " << val << " for ", l) << "\n";); + return val; + } + bool_var b = l.var(); + atom * a = m_atoms[b]; + if (a == nullptr) { + TRACE("nlsat_verbose", display(tout << " no atom for ", l) << "\n";); + return l_undef; + } + var max = a->max_var(); + if (!m_assignment.is_assigned(max)) { + TRACE("nlsat_verbose", display(tout << " maximal variable not assigned ", l) << "\n";); + return l_undef; + } + val = to_lbool(m_evaluator.eval(a, l.sign())); + TRACE("nlsat_verbose", display(tout << " evaluated value " << val << " for ", l) << "\n";); + TRACE("value_bug", tout << "value of: "; display(tout, l); tout << " := " << val << "\n"; + tout << "xk: " << m_xk << ", a->max_var(): " << a->max_var() << "\n"; + display_assignment(tout);); + return val; + } + + /** + \brief Return true if the given clause is already satisfied in the current partial interpretation. + */ + bool is_satisfied(clause const & cls) const { + for (literal l : cls) { + if (const_cast(this)->value(l) == l_true) { + TRACE("value_bug:", tout << l << " := true\n";); + return true; + } + } + return false; + } + + /** + \brief Return true if the given clause is false in the current partial interpretation. + */ + bool is_inconsistent(unsigned sz, literal const * cls) { + for (unsigned i = 0; i < sz; i++) { + if (value(cls[i]) != l_false) { + TRACE("is_inconsistent", tout << "literal is not false:\n"; display(tout, cls[i]); tout << "\n";); + return false; + } + } + return true; + } + + /** + \brief Process a clauses that contains only Boolean literals. + */ + bool process_boolean_clause(clause const & cls) { + SASSERT(m_xk == null_var); + unsigned num_undef = 0; + unsigned first_undef = UINT_MAX; + unsigned sz = cls.size(); + for (unsigned i = 0; i < sz; i++) { + literal l = cls[i]; + SASSERT(m_atoms[l.var()] == nullptr); + SASSERT(value(l) != l_true); + if (value(l) == l_false) + continue; + SASSERT(value(l) == l_undef); + num_undef++; + if (first_undef == UINT_MAX) + first_undef = i; + } + if (num_undef == 0) + return false; + SASSERT(first_undef != UINT_MAX); + if (num_undef == 1) + assign(cls[first_undef], mk_clause_jst(&cls)); // unit clause + else + decide(cls[first_undef]); + return true; + } + + /** + \brief assign l to true, because l + (justification of) s is infeasible in RCF in the current interpretation. + */ + literal_vector core; + ptr_vector clauses; + void R_propagate(literal l, interval_set const * s, bool include_l = true) { + m_ism.get_justifications(s, core, clauses); + if (include_l) + core.push_back(~l); + auto j = mk_lazy_jst(m_allocator, core.size(), core.data(), clauses.size(), clauses.data()); + TRACE("nlsat_resolve", display(tout, j); display_eval(tout << "evaluated:", j)); + assign(l, j); + SASSERT(value(l) == l_true); + } + + /** + \brief m_infeasible[m_xk] <- m_infeasible[m_xk] Union s + */ + void updt_infeasible(interval_set const * s) { + SASSERT(m_xk != null_var); + interval_set * xk_set = m_infeasible[m_xk]; + save_set_updt_trail(xk_set); + interval_set_ref new_set(m_ism); + TRACE("nlsat_inf_set", tout << "updating infeasible set\n"; m_ism.display(tout, xk_set) << "\n"; m_ism.display(tout, s) << "\n";); + new_set = m_ism.mk_union(s, xk_set); + TRACE("nlsat_inf_set", tout << "new infeasible set:\n"; m_ism.display(tout, new_set) << "\n";); + SASSERT(!m_ism.is_full(new_set)); + m_ism.inc_ref(new_set); + m_infeasible[m_xk] = new_set; + } + + /** + \brief Update m_var2eq mapping. + */ + void updt_eq(bool_var b, justification j) { + if (!m_simplify_cores) + return; + if (m_bvalues[b] != l_true) + return; + atom * a = m_atoms[b]; + if (a == nullptr || a->get_kind() != atom::EQ || to_ineq_atom(a)->size() > 1 || to_ineq_atom(a)->is_even(0)) + return; + switch (j.get_kind()) { + case justification::CLAUSE: + if (j.get_clause()->assumptions() != nullptr) return; + break; + case justification::LAZY: + if (j.get_lazy()->num_clauses() > 0) return; + if (j.get_lazy()->num_lits() > 0) return; + break; + default: + break; + } + var x = m_xk; + SASSERT(a->max_var() == x); + SASSERT(x != null_var); + if (m_var2eq[x] != 0 && degree(m_var2eq[x]) <= degree(a)) + return; // we only update m_var2eq if the new equality has smaller degree + TRACE("nlsat_simplify_core", tout << "Saving equality for "; m_display_var(tout, x) << " (x" << x << ") "; + tout << "scope-lvl: " << scope_lvl() << "\n"; display(tout, literal(b, false)) << "\n"; + display(tout, j); + ); + save_updt_eq_trail(m_var2eq[x]); + m_var2eq[x] = a; + } + + /** + \brief Process a clause that contains nonlinear arithmetic literals + + If satisfy_learned is true, then learned clauses are satisfied even if m_lazy > 0 + */ + bool process_arith_clause(clause const & cls, bool satisfy_learned) { + if (!satisfy_learned && m_lazy >= 2 && cls.is_learned()) { + TRACE("nlsat", tout << "skip learned\n";); + return true; // ignore lemmas in super lazy mode + } + SASSERT(m_xk == max_var(cls)); + unsigned num_undef = 0; // number of undefined literals + unsigned first_undef = UINT_MAX; // position of the first undefined literal + interval_set_ref first_undef_set(m_ism); // infeasible region of the first undefined literal + interval_set * xk_set = m_infeasible[m_xk]; // current set of infeasible interval for current variable + SASSERT(!m_ism.is_full(xk_set)); + for (unsigned idx = 0; idx < cls.size(); ++idx) { + literal l = cls[idx]; + checkpoint(); + if (value(l) == l_false) + continue; + if (value(l) == l_true) + return true; // could happen if clause is a tautology + CTRACE("nlsat", max_var(l) != m_xk || value(l) != l_undef, display(tout); + tout << "xk: " << m_xk << ", max_var(l): " << max_var(l) << ", l: "; display(tout, l) << "\n"; + display(tout, cls) << "\n";); + SASSERT(value(l) == l_undef); + SASSERT(max_var(l) == m_xk); + bool_var b = l.var(); + atom * a = m_atoms[b]; + SASSERT(a != nullptr); + interval_set_ref curr_set(m_ism); + curr_set = m_evaluator.infeasible_intervals(a, l.sign(), &cls); + TRACE("nlsat_inf_set", tout << "infeasible set for literal: "; display(tout, l); tout << "\n"; m_ism.display(tout, curr_set); tout << "\n"; + display(tout, cls) << "\n";); + if (m_ism.is_empty(curr_set)) { + TRACE("nlsat_inf_set", tout << "infeasible set is empty, found literal\n";); + R_propagate(l, nullptr); + SASSERT(is_satisfied(cls)); + return true; + } + if (m_ism.is_full(curr_set)) { + TRACE("nlsat_inf_set", tout << "infeasible set is R, skip literal\n";); + R_propagate(~l, nullptr); + continue; + } + if (m_ism.subset(curr_set, xk_set)) { + TRACE("nlsat_inf_set", tout << "infeasible set is a subset of current set, found literal\n";); + R_propagate(l, xk_set); + return true; + } + interval_set_ref tmp(m_ism); + tmp = m_ism.mk_union(curr_set, xk_set); + if (m_ism.is_full(tmp)) { + TRACE("nlsat_inf_set", tout << "infeasible set + current set = R, skip literal\n"; + display(tout, cls) << "\n"; + m_ism.display(tout, tmp); tout << "\n"; + ); + R_propagate(~l, tmp, false); + continue; + } + num_undef++; + if (first_undef == UINT_MAX) { + first_undef = idx; + first_undef_set = curr_set; + } + } + TRACE("nlsat_inf_set", tout << "num_undef: " << num_undef << "\n";); + if (num_undef == 0) + return false; + SASSERT(first_undef != UINT_MAX); + if (num_undef == 1) { + // unit clause + assign(cls[first_undef], mk_clause_jst(&cls)); + updt_infeasible(first_undef_set); + } + else if ( satisfy_learned || + !cls.is_learned() /* must always satisfy input clauses */ || + m_lazy == 0 /* if not in lazy mode, we also satiffy lemmas */) { + decide(cls[first_undef]); + updt_infeasible(first_undef_set); + } + else { + TRACE("nlsat_lazy", tout << "skipping clause, satisfy_learned: " << satisfy_learned << ", cls.is_learned(): " << cls.is_learned() + << ", lazy: " << m_lazy << "\n";); + } + return true; + } + + /** + \brief Try to satisfy the given clause. Return true if succeeded. + + If satisfy_learned is true, then (arithmetic) learned clauses are satisfied even if m_lazy > 0 + */ + bool process_clause(clause const & cls, bool satisfy_learned) { + if (is_satisfied(cls)) + return true; + if (m_xk == null_var) + return process_boolean_clause(cls); + else + return process_arith_clause(cls, satisfy_learned); + } + + /** + \brief Try to satisfy the given "set" of clauses. + Return 0, if the set was satisfied, or the violating clause otherwise + */ + clause * process_clauses(clause_vector const & cs) { + for (clause* c : cs) { + if (!process_clause(*c, false)) + return c; + } + return nullptr; // succeeded + } + + /** + \brief Make sure m_bk is the first unassigned pure Boolean variable. + Set m_bk == null_bool_var if there is no unassigned pure Boolean variable. + */ + void peek_next_bool_var() { + while (m_bk < m_atoms.size()) { + if (!m_dead[m_bk] && m_atoms[m_bk] == nullptr && m_bvalues[m_bk] == l_undef) { + return; + } + m_bk++; + } + m_bk = null_bool_var; + } + + /** + \brief Create a new stage. See Dejan and Leo's paper. + */ + void new_stage() { + m_stats.m_stages++; + save_new_stage_trail(); + if (m_xk == null_var) + m_xk = 0; + else + m_xk++; + } + + /** + \brief Assign m_xk + */ + void select_witness() { + scoped_anum w(m_am); + SASSERT(!m_ism.is_full(m_infeasible[m_xk])); + m_ism.pick_in_complement(m_infeasible[m_xk], is_int(m_xk), w, m_randomize); + TRACE("nlsat", + tout << "infeasible intervals: "; m_ism.display(tout, m_infeasible[m_xk]); tout << "\n"; + tout << "assigning "; m_display_var(tout, m_xk) << "(x" << m_xk << ") -> " << w << "\n";); + TRACE("nlsat_root", tout << "value as root object: "; m_am.display_root(tout, w); tout << "\n";); + if (!m_am.is_rational(w)) + m_stats.m_irrational_assignments++; + m_assignment.set_core(m_xk, w); + } + + + + bool is_satisfied() { + if (m_bk == null_bool_var && m_xk >= num_vars()) { + TRACE("nlsat", tout << "found model\n"; display_assignment(tout);); + fix_patch(); + SASSERT(check_satisfied(m_clauses)); + return true; // all variables were assigned, and all clauses were satisfied. + } + else { + return false; + } + } + + + /** + \brief main procedure + */ + lbool search() { + TRACE("nlsat", tout << "starting search...\n"; display(tout); tout << "\nvar order:\n"; display_vars(tout);); + TRACE("nlsat_proof", tout << "ASSERTED\n"; display(tout);); + TRACE("nlsat_proof_sk", tout << "ASSERTED\n"; display_abst(tout);); + TRACE("nlsat_mathematica", display_mathematica(tout);); + TRACE("nlsat", display_smt2(tout);); + m_bk = 0; + m_xk = null_var; + + while (true) { + if (should_reorder()) + do_reorder(); + +#if 0 + if (should_gc()) + do_gc(); +#endif + + if (should_simplify()) + do_simplify(); + + CASSERT("nlsat", check_satisfied()); + if (m_xk == null_var) { + peek_next_bool_var(); + if (m_bk == null_bool_var) + new_stage(); // move to arith vars + } + else { + new_stage(); // peek next arith var + } + TRACE("nlsat_bug", tout << "xk: x" << m_xk << " bk: b" << m_bk << "\n";); + if (is_satisfied()) { + return l_true; + } + while (true) { + TRACE("nlsat_verbose", tout << "processing variable "; + if (m_xk != null_var) { + m_display_var(tout, m_xk); tout << " " << m_watches[m_xk].size(); + } + else { + tout << m_bwatches[m_bk].size() << " boolean b" << m_bk; + } + tout << "\n";); + checkpoint(); + clause * conflict_clause; + if (m_xk == null_var) + conflict_clause = process_clauses(m_bwatches[m_bk]); + else + conflict_clause = process_clauses(m_watches[m_xk]); + if (conflict_clause == nullptr) + break; + if (!resolve(*conflict_clause)) + return l_false; + if (m_stats.m_conflicts >= m_max_conflicts) + return l_undef; + log(); + } + + if (m_xk == null_var) { + if (m_bvalues[m_bk] == l_undef) { + decide(literal(m_bk, true)); + m_bk++; + } + } + else { + select_witness(); + } + } + } + + void gc() { + if (m_learned.size() <= 4*m_clauses.size()) + return; + reset_watches(); + reinit_cache(); + unsigned j = 0; + for (unsigned i = 0; i < m_learned.size(); ++i) { + auto cls = m_learned[i]; + if (i - j < m_clauses.size() && cls->size() > 1 && !cls->is_active()) + del_clause(cls); + else { + m_learned[j++] = cls; + cls->set_active(false); + } + } + m_learned.shrink(j); + reattach_arith_clauses(m_clauses); + reattach_arith_clauses(m_learned); + } + + + bool should_gc() { + return m_learned.size() > 10 * m_clauses.size(); + } + + void do_gc() { + undo_to_base(); + gc(); + } + + void undo_to_base() { + init_search(); + m_bk = 0; + m_xk = null_var; + } + + unsigned m_restart_threshold = 10000; + bool should_reorder() { + return m_stats.m_conflicts > 0 && m_stats.m_conflicts % m_restart_threshold == 0; + } + + void do_reorder() { + undo_to_base(); + m_stats.m_restarts++; + m_stats.m_conflicts++; + if (m_reordered) + restore_order(); + apply_reorder(); + } + + bool m_did_simplify = false; + bool should_simplify() { + return + !m_did_simplify && m_inline_vars && + !m_incremental && m_stats.m_conflicts > 100; + } + + void do_simplify() { + undo_to_base(); + m_did_simplify = true; + m_simplify(); + } + + unsigned m_next_conflict = 100; + void log() { + if (m_stats.m_conflicts != 1 && m_stats.m_conflicts < m_next_conflict) + return; + m_next_conflict += 100; + IF_VERBOSE(2, verbose_stream() << "(nlsat :conflicts " << m_stats.m_conflicts + << " :decisions " << m_stats.m_decisions + << " :propagations " << m_stats.m_propagations + << " :clauses " << m_clauses.size() + << " :learned " << m_learned.size() << ")\n"); + } + + + lbool search_check() { + lbool r = l_undef; + m_stats.m_conflicts = 0; + m_stats.m_restarts = 0; + m_next_conflict = 0; + while (true) { + r = search(); + if (r != l_true) + break; + ++m_stats.m_restarts; + vector> bounds; + + for (var x = 0; x < num_vars(); x++) { + if (is_int(x) && m_assignment.is_assigned(x) && !m_am.is_int(m_assignment.value(x))) { + scoped_anum v(m_am), vlo(m_am); + v = m_assignment.value(x); + rational lo; + m_am.int_lt(v, vlo); + if (!m_am.is_int(vlo)) + continue; + m_am.to_rational(vlo, lo); + // derive tight bounds. + while (true) { + lo++; + if (!m_am.gt(v, lo.to_mpq())) { + lo--; + break; + } + } + bounds.push_back(std::make_pair(x, lo)); + } + } + if (bounds.empty()) + break; + + gc(); + if (m_stats.m_restarts % 10 == 0) { + if (m_reordered) + restore_order(); + apply_reorder(); + } + + init_search(); + IF_VERBOSE(2, verbose_stream() << "(nlsat-b&b :conflicts " << m_stats.m_conflicts + << " :decisions " << m_stats.m_decisions + << " :propagations " << m_stats.m_propagations + << " :clauses " << m_clauses.size() + << " :learned " << m_learned.size() << ")\n"); + for (auto const& b : bounds) { + var x = b.first; + rational lo = b.second; + rational hi = lo + 1; // rational::one(); + bool is_even = false; + polynomial_ref p(m_pm); + rational one(1); + m_lemma.reset(); + p = m_pm.mk_linear(1, &one, &x, -lo); + poly* p1 = p.get(); + m_lemma.push_back(~mk_ineq_literal(atom::GT, 1, &p1, &is_even)); + p = m_pm.mk_linear(1, &one, &x, -hi); + poly* p2 = p.get(); + m_lemma.push_back(~mk_ineq_literal(atom::LT, 1, &p2, &is_even)); + + // perform branch and bound + clause * cls = mk_clause(m_lemma.size(), m_lemma.data(), true, nullptr); + IF_VERBOSE(4, display(verbose_stream(), *cls) << "\n"); + if (cls) { + TRACE("nlsat", display(tout << "conflict " << lo << " " << hi, *cls); tout << "\n";); + } + } + } + return r; + } + + bool m_reordered = false; + bool simple_check() { + literal_vector learned_unit; + simple_checker checker(m_pm, m_am, m_clauses, learned_unit, m_atoms, m_is_int.size()); + if (!checker()) + return false; + for (unsigned i = 0, sz = learned_unit.size(); i < sz; ++i) { + clause *cla = mk_clause(1, &learned_unit[i], true, nullptr); + if (m_atoms[learned_unit[i].var()] == nullptr) { + assign(learned_unit[i], mk_clause_jst(cla)); + } + } + return true; + } + + + void run_variable_ordering_strategy() { + TRACE("reorder", tout << "runing vos: " << m_variable_ordering_strategy << '\n';); + + unsigned num = num_vars(); + vos_var_info_collector vos_collector(m_pm, m_atoms, num, m_variable_ordering_strategy); + vos_collector.collect(m_clauses); + vos_collector.collect(m_learned); + + var_vector perm; + vos_collector(perm); + reorder(perm.size(), perm.data()); + } + + void apply_reorder() { + m_reordered = false; + if (!can_reorder()) + ; + else if (m_random_order) { + shuffle_vars(); + m_reordered = true; + } + else if (m_reorder) { + heuristic_reorder(); + m_reordered = true; + } + } + + lbool check() { + + if (m_simple_check) { + if (!simple_check()) { + TRACE("simple_check", tout << "real unsat\n";); + return l_false; + } + TRACE("simple_checker_learned", + tout << "simple check done\n"; + ); + } + + TRACE("nlsat_smt2", display_smt2(tout);); + TRACE("nlsat_fd", tout << "is_full_dimensional: " << is_full_dimensional() << "\n";); + init_search(); + m_explain.set_full_dimensional(is_full_dimensional()); + bool reordered = false; + + + if (!can_reorder()) { + + } + else if (m_variable_ordering_strategy > 0) { + run_variable_ordering_strategy(); + reordered = true; + } + else if (m_random_order) { + shuffle_vars(); + reordered = true; + } + else if (m_reorder) { + heuristic_reorder(); + reordered = true; + } + sort_watched_clauses(); + lbool r = search_check(); + CTRACE("nlsat_model", r == l_true, tout << "model before restore order\n"; display_assignment(tout);); + if (reordered) { + restore_order(); + } + CTRACE("nlsat_model", r == l_true, tout << "model\n"; display_assignment(tout);); + CTRACE("nlsat", r == l_false, display(tout << "unsat\n");); + SASSERT(r != l_true || check_satisfied(m_clauses)); + return r; + } + + void init_search() { + undo_until_empty(); + while (m_scope_lvl > 0) { + undo_new_level(); + } + m_xk = null_var; + for (unsigned i = 0; i < m_bvalues.size(); ++i) { + m_bvalues[i] = l_undef; + } + m_assignment.reset(); + } + + lbool check(literal_vector& assumptions) { + literal_vector result; + unsigned sz = assumptions.size(); + literal const* ptr = assumptions.data(); + for (unsigned i = 0; i < sz; ++i) { + mk_external_clause(1, ptr+i, (assumption)(ptr+i)); + } + display_literal_assumption dla(*this, assumptions); + scoped_display_assumptions _scoped_display(*this, dla); + lbool r = check(); + + if (r == l_false) { + // collect used literals from m_lemma_assumptions + vector deps; + get_core(deps); + for (unsigned i = 0; i < deps.size(); ++i) { + literal const* lp = (literal const*)(deps[i]); + if (ptr <= lp && lp < ptr + sz) { + result.push_back(*lp); + } + } + } + collect(assumptions, m_clauses); + collect(assumptions, m_learned); + del_clauses(m_valids); + if (m_check_lemmas) { + for (clause* c : m_learned) { + check_lemma(c->size(), c->data(), false, nullptr); + } + } + +#if 0 + for (clause* c : m_learned) { + IF_VERBOSE(0, display(verbose_stream() << "KEEP: ", c->size(), c->c_ptr()) << "\n"); + } +#endif + assumptions.reset(); + assumptions.append(result); + return r; + } + + void get_core(vector& deps) { + m_asm.linearize(m_lemma_assumptions.get(), deps); + } + + void collect(literal_vector const& assumptions, clause_vector& clauses) { + unsigned j = 0; + for (clause * c : clauses) { + if (collect(assumptions, *c)) { + del_clause(c); + } + else { + clauses[j++] = c; + } + } + clauses.shrink(j); + } + + bool collect(literal_vector const& assumptions, clause const& c) { + unsigned sz = assumptions.size(); + literal const* ptr = assumptions.data(); + _assumption_set asms = static_cast<_assumption_set>(c.assumptions()); + if (asms == nullptr) { + return false; + } + vector deps; + m_asm.linearize(asms, deps); + for (auto dep : deps) { + if (ptr <= dep && dep < ptr + sz) { + return true; + } + } + return false; + } + + // ----------------------- + // + // Conflict Resolution + // + // ----------------------- + svector m_marks; // bool_var -> bool temp mark used during conflict resolution + unsigned m_num_marks; + scoped_literal_vector m_lemma; + scoped_literal_vector m_lazy_clause; + assumption_set_ref m_lemma_assumptions; // assumption tracking + + // Conflict resolution invariant: a marked literal is in m_lemma or on the trail stack. + + bool check_marks() { + for (unsigned m : m_marks) { + (void)m; + SASSERT(m == 0); + } + return true; + } + + unsigned scope_lvl() const { return m_scope_lvl; } + + bool is_marked(bool_var b) const { return m_marks.get(b, 0) == 1; } + + void mark(bool_var b) { m_marks.setx(b, 1, 0); } + + void reset_mark(bool_var b) { m_marks[b] = 0; } + + void reset_marks() { + for (auto const& l : m_lemma) { + reset_mark(l.var()); + } + } + + void process_antecedent(literal antecedent) { + checkpoint(); + bool_var b = antecedent.var(); + TRACE("nlsat_resolve", display(tout << "resolving antecedent: ", antecedent) << "\n";); + if (assigned_value(antecedent) == l_undef) { + checkpoint(); + // antecedent must be false in the current arith interpretation + SASSERT(value(antecedent) == l_false || m_rlimit.is_canceled()); + if (!is_marked(b)) { + SASSERT(is_arith_atom(b) && max_var(b) < m_xk); // must be in a previous stage + TRACE("nlsat_resolve", tout << "literal is unassigned, but it is false in arithmetic interpretation, adding it to lemma\n";); + mark(b); + m_lemma.push_back(antecedent); + } + return; + } + + unsigned b_lvl = m_levels[b]; + TRACE("nlsat_resolve", tout << "b_lvl: " << b_lvl << ", is_marked(b): " << is_marked(b) << ", m_num_marks: " << m_num_marks << "\n";); + if (!is_marked(b)) { + mark(b); + if (b_lvl == scope_lvl() /* same level */ && max_var(b) == m_xk /* same stage */) { + TRACE("nlsat_resolve", tout << "literal is in the same level and stage, increasing marks\n";); + m_num_marks++; + } + else { + TRACE("nlsat_resolve", tout << "previous level or stage, adding literal to lemma\n"; + tout << "max_var(b): " << max_var(b) << ", m_xk: " << m_xk << ", lvl: " << b_lvl << ", scope_lvl: " << scope_lvl() << "\n";); + m_lemma.push_back(antecedent); + } + } + } + + void resolve_clause(bool_var b, unsigned sz, literal const * c) { + TRACE("nlsat_proof", tout << "resolving "; if (b != null_bool_var) display_atom(tout, b) << "\n"; display(tout, sz, c); tout << "\n";); + TRACE("nlsat_proof_sk", tout << "resolving "; if (b != null_bool_var) tout << "b" << b; tout << "\n"; display_abst(tout, sz, c); tout << "\n";); + + for (unsigned i = 0; i < sz; i++) { + if (c[i].var() != b) + process_antecedent(c[i]); + } + } + + void resolve_clause(bool_var b, clause & c) { + TRACE("nlsat_resolve", tout << "resolving clause "; if (b != null_bool_var) tout << "for b: " << b << "\n"; display(tout, c) << "\n";); + c.set_active(true); + resolve_clause(b, c.size(), c.data()); + m_lemma_assumptions = m_asm.mk_join(static_cast<_assumption_set>(c.assumptions()), m_lemma_assumptions); + } + + void resolve_lazy_justification(bool_var b, lazy_justification const & jst) { + TRACE("nlsat_resolve", tout << "resolving lazy_justification for b" << b << "\n";); + unsigned sz = jst.num_lits(); + + // Dump lemma as Mathematica formula that must be true, + // if the current interpretation (really) makes the core in jst infeasible. + TRACE("nlsat_mathematica", + tout << "assignment lemma\n"; + literal_vector core; + for (unsigned i = 0; i < sz; i++) { + core.push_back(~jst.lit(i)); + } + display_mathematica_lemma(tout, core.size(), core.data(), true);); + + m_lazy_clause.reset(); + m_explain(jst.num_lits(), jst.lits(), m_lazy_clause); + for (unsigned i = 0; i < sz; i++) + m_lazy_clause.push_back(~jst.lit(i)); + + // lazy clause is a valid clause + TRACE("nlsat_mathematica", display_mathematica_lemma(tout, m_lazy_clause.size(), m_lazy_clause.data());); + TRACE("nlsat_proof_sk", tout << "theory lemma\n"; display_abst(tout, m_lazy_clause.size(), m_lazy_clause.data()); tout << "\n";); + TRACE("nlsat_resolve", + tout << "m_xk: " << m_xk << ", "; m_display_var(tout, m_xk) << "\n"; + tout << "new valid clause:\n"; + display(tout, m_lazy_clause.size(), m_lazy_clause.data()) << "\n";); + + + if (m_log_lemmas) + log_lemma(verbose_stream(), m_lazy_clause.size(), m_lazy_clause.data(), true); + + if (m_check_lemmas) { + check_lemma(m_lazy_clause.size(), m_lazy_clause.data(), true, nullptr); + m_valids.push_back(mk_clause_core(m_lazy_clause.size(), m_lazy_clause.data(), false, nullptr)); + } + +#ifdef Z3DEBUG + { + unsigned sz = m_lazy_clause.size(); + for (unsigned i = 0; i < sz; i++) { + literal l = m_lazy_clause[i]; + if (l.var() != b) { + if (value(l) != l_false) + display(verbose_stream() << value(l) << " ", 1, &l); + SASSERT(value(l) == l_false || m_rlimit.is_canceled()); + } + else { + SASSERT(value(l) == l_true || m_rlimit.is_canceled()); + SASSERT(!l.sign() || m_bvalues[b] == l_false); + SASSERT(l.sign() || m_bvalues[b] == l_true); + } + } + } +#endif + checkpoint(); + resolve_clause(b, m_lazy_clause.size(), m_lazy_clause.data()); + + for (unsigned i = 0; i < jst.num_clauses(); ++i) { + clause const& c = jst.clause(i); + TRACE("nlsat", display(tout << "adding clause assumptions ", c) << "\n";); + m_lemma_assumptions = m_asm.mk_join(static_cast<_assumption_set>(c.assumptions()), m_lemma_assumptions); + } + } + + /** + \brief Return true if all literals in ls are from previous stages. + */ + bool only_literals_from_previous_stages(unsigned num, literal const * ls) const { + for (unsigned i = 0; i < num; i++) { + if (max_var(ls[i]) == m_xk) + return false; + } + return true; + } + + /** + \brief Return the maximum scope level in ls. + + \pre This method assumes value(ls[i]) is l_false for i in [0, num) + */ + unsigned max_scope_lvl(unsigned num, literal const * ls) { + unsigned max = 0; + for (unsigned i = 0; i < num; i++) { + literal l = ls[i]; + bool_var b = l.var(); + SASSERT(value(ls[i]) == l_false); + if (assigned_value(l) == l_false) { + unsigned lvl = m_levels[b]; + if (lvl > max) + max = lvl; + } + else { + // l must be a literal from a previous stage that is false in the current interpretation + SASSERT(assigned_value(l) == l_undef); + SASSERT(max_var(b) != null_var); + SASSERT(m_xk != null_var); + SASSERT(max_var(b) < m_xk); + } + } + return max; + } + + /** + \brief Remove literals of the given lvl (that are in the current stage) from lemma. + + \pre This method assumes value(ls[i]) is l_false for i in [0, num) + */ + void remove_literals_from_lvl(scoped_literal_vector & lemma, unsigned lvl) { + TRACE("nlsat_resolve", tout << "removing literals from lvl: " << lvl << " and stage " << m_xk << "\n";); + unsigned sz = lemma.size(); + unsigned j = 0; + for (unsigned i = 0; i < sz; i++) { + literal l = lemma[i]; + bool_var b = l.var(); + SASSERT(is_marked(b)); + SASSERT(value(lemma[i]) == l_false); + if (assigned_value(l) == l_false && m_levels[b] == lvl && max_var(b) == m_xk) { + m_num_marks++; + continue; + } + lemma.set(j, l); + j++; + } + lemma.shrink(j); + } + + /** + \brief Return true if it is a Boolean lemma. + */ + bool is_bool_lemma(unsigned sz, literal const * ls) const { + for (unsigned i = 0; i < sz; i++) { + if (m_atoms[ls[i].var()] != nullptr) + return false; + } + return true; + } + + + /** + Return the maximal decision level in lemma for literals in the first sz-1 positions that + are at the same stage. If all these literals are from previous stages, + we just backtrack the current level. + */ + unsigned find_new_level_arith_lemma(unsigned sz, literal const * lemma) { + SASSERT(!is_bool_lemma(sz, lemma)); + unsigned new_lvl = 0; + bool found_lvl = false; + for (unsigned i = 0; i < sz - 1; i++) { + literal l = lemma[i]; + if (max_var(l) == m_xk) { + bool_var b = l.var(); + if (!found_lvl) { + found_lvl = true; + new_lvl = m_levels[b]; + } + else { + if (m_levels[b] > new_lvl) + new_lvl = m_levels[b]; + } + } + } + SASSERT(!found_lvl || new_lvl < scope_lvl()); + if (!found_lvl) { + TRACE("nlsat_resolve", tout << "fail to find new lvl, using previous one\n";); + new_lvl = scope_lvl() - 1; + } + return new_lvl; + } + + struct scoped_reset_marks { + imp& i; + scoped_reset_marks(imp& i):i(i) {} + ~scoped_reset_marks() { if (i.m_num_marks > 0) { i.m_num_marks = 0; for (char& m : i.m_marks) m = 0; } } + }; + + + /** + \brief Return true if the conflict was solved. + */ + bool resolve(clause & conflict) { + clause * conflict_clause = &conflict; + m_lemma_assumptions = nullptr; + start: + SASSERT(check_marks()); + TRACE("nlsat_proof", tout << "STARTING RESOLUTION\n";); + TRACE("nlsat_proof_sk", tout << "STARTING RESOLUTION\n";); + m_stats.m_conflicts++; + TRACE("nlsat", tout << "resolve, conflicting clause:\n"; display(tout, *conflict_clause) << "\n"; + tout << "xk: "; if (m_xk != null_var) m_display_var(tout, m_xk); else tout << ""; tout << "\n"; + tout << "scope_lvl: " << scope_lvl() << "\n"; + tout << "current assignment\n"; display_assignment(tout);); + + m_num_marks = 0; + m_lemma.reset(); + m_lemma_assumptions = nullptr; + scoped_reset_marks _sr(*this); + resolve_clause(null_bool_var, *conflict_clause); + + unsigned top = m_trail.size(); + bool found_decision; + while (true) { + found_decision = false; + while (m_num_marks > 0) { + checkpoint(); + SASSERT(top > 0); + trail & t = m_trail[top-1]; + SASSERT(t.m_kind != trail::NEW_STAGE); // we only mark literals that are in the same stage + if (t.m_kind == trail::BVAR_ASSIGNMENT) { + bool_var b = t.m_b; + if (is_marked(b)) { + TRACE("nlsat_resolve", tout << "found marked: b" << b << "\n"; display_atom(tout, b) << "\n";); + m_num_marks--; + reset_mark(b); + justification jst = m_justifications[b]; + switch (jst.get_kind()) { + case justification::CLAUSE: + resolve_clause(b, *(jst.get_clause())); + break; + case justification::LAZY: + resolve_lazy_justification(b, *(jst.get_lazy())); + break; + case justification::DECISION: + SASSERT(m_num_marks == 0); + found_decision = true; + TRACE("nlsat_resolve", tout << "found decision\n";); + m_lemma.push_back(literal(b, m_bvalues[b] == l_true)); + break; + default: + UNREACHABLE(); + break; + } + } + } + top--; + } + + // m_lemma is an implicating clause after backtracking current scope level. + if (found_decision) + break; + + // If lemma only contains literals from previous stages, then we can stop. + // We make progress by returning to a previous stage with additional information (new lemma) + // that forces us to select a new partial interpretation + if (only_literals_from_previous_stages(m_lemma.size(), m_lemma.data())) + break; + + // Conflict does not depend on the current decision, and it is still in the current stage. + // We should find + // - the maximal scope level in the lemma + // - remove literal assigned in the scope level from m_lemma + // - backtrack to this level + // - and continue conflict resolution from there + // - we must bump m_num_marks for literals removed from m_lemma + unsigned max_lvl = max_scope_lvl(m_lemma.size(), m_lemma.data()); + TRACE("nlsat_resolve", tout << "conflict does not depend on current decision, backtracking to level: " << max_lvl << "\n";); + SASSERT(max_lvl < scope_lvl()); + remove_literals_from_lvl(m_lemma, max_lvl); + undo_until_level(max_lvl); + top = m_trail.size(); + TRACE("nlsat_resolve", tout << "scope_lvl: " << scope_lvl() << " num marks: " << m_num_marks << "\n";); + SASSERT(scope_lvl() == max_lvl); + } + + TRACE("nlsat_proof", tout << "New lemma\n"; display(tout, m_lemma); tout << "\n=========================\n";); + TRACE("nlsat_proof_sk", tout << "New lemma\n"; display_abst(tout, m_lemma); tout << "\n=========================\n";); + + if (m_lemma.empty()) { + TRACE("nlsat", tout << "empty clause generated\n";); + return false; // problem is unsat, empty clause was generated + } + + reset_marks(); // remove marks from the literals in m_lemmas. + TRACE("nlsat", tout << "new lemma:\n"; display(tout, m_lemma.size(), m_lemma.data()); tout << "\n"; + tout << "found_decision: " << found_decision << "\n";); + + if (m_check_lemmas) { + check_lemma(m_lemma.size(), m_lemma.data(), false, m_lemma_assumptions.get()); + } + + if (m_log_lemmas) + log_lemma(verbose_stream(), m_lemma.size(), m_lemma.data(), false); + + // There are two possibilities: + // 1) m_lemma contains only literals from previous stages, and they + // are false in the current interpretation. We make progress + // by returning to a previous stage with additional information (new clause) + // that forces us to select a new partial interpretation + // >>> Return to some previous stage (we may also backjump many decisions and stages). + // + // 2) m_lemma contains at most one literal from the current level (the last literal). + // Moreover, this literal was a decision, but the new lemma forces it to + // be assigned to a different value. + // >>> In this case, we remain in the same stage but, we add a new asserted literal + // in a previous scope level. We may backjump many decisions. + // + unsigned sz = m_lemma.size(); + clause * new_cls = nullptr; + if (!found_decision) { + // Case 1) + // We just have to find the maximal variable in m_lemma, and return to that stage + // Remark: the lemma may contain only boolean literals, in this case new_max_var == null_var; + var new_max_var = max_var(sz, m_lemma.data()); + TRACE("nlsat_resolve", tout << "backtracking to stage: " << new_max_var << ", curr: " << m_xk << "\n";); + undo_until_stage(new_max_var); + SASSERT(m_xk == new_max_var); + new_cls = mk_clause(sz, m_lemma.data(), true, m_lemma_assumptions.get()); + TRACE("nlsat", tout << "new_level: " << scope_lvl() << "\nnew_stage: " << new_max_var << "\n"; + if (new_max_var != null_var) m_display_var(tout, new_max_var) << "\n";); + } + else { + SASSERT(scope_lvl() >= 1); + // Case 2) + if (is_bool_lemma(m_lemma.size(), m_lemma.data())) { + // boolean lemma, we just backtrack until the last literal is unassigned. + bool_var max_bool_var = m_lemma[m_lemma.size()-1].var(); + undo_until_unassigned(max_bool_var); + } + else { + // We must find the maximal decision level in literals in the first sz-1 positions that + // are at the same stage. If all these literals are from previous stages, + // we just backtrack the current level. + unsigned new_lvl = find_new_level_arith_lemma(m_lemma.size(), m_lemma.data()); + TRACE("nlsat", tout << "backtracking to new level: " << new_lvl << ", curr: " << m_scope_lvl << "\n";); + undo_until_level(new_lvl); + } + + if (lemma_is_clause(*conflict_clause)) { + TRACE("nlsat", tout << "found decision literal in conflict clause\n";); + VERIFY(process_clause(*conflict_clause, true)); + return true; + } + new_cls = mk_clause(sz, m_lemma.data(), true, m_lemma_assumptions.get()); + } + NLSAT_VERBOSE(display(verbose_stream(), *new_cls) << "\n";); + if (!process_clause(*new_cls, true)) { + TRACE("nlsat", tout << "new clause triggered another conflict, restarting conflict resolution...\n"; + display(tout, *new_cls) << "\n"; + ); + // we are still in conflict + conflict_clause = new_cls; + goto start; + } + TRACE("nlsat_resolve_done", display_assignment(tout);); + return true; + } + + bool lemma_is_clause(clause const& cls) const { + bool same = (m_lemma.size() == cls.size()); + for (unsigned i = 0; same && i < m_lemma.size(); ++i) { + same = m_lemma[i] == cls[i]; + } + return same; + } + + + // ----------------------- + // + // Debugging + // + // ----------------------- + + bool check_watches() const { +#ifdef Z3DEBUG + for (var x = 0; x < num_vars(); x++) { + clause_vector const & cs = m_watches[x]; + unsigned sz = cs.size(); + for (unsigned i = 0; i < sz; i++) { + SASSERT(max_var(*(cs[i])) == x); + } + } +#endif + return true; + } + + bool check_bwatches() const { +#ifdef Z3DEBUG + for (bool_var b = 0; b < m_bwatches.size(); b++) { + clause_vector const & cs = m_bwatches[b]; + unsigned sz = cs.size(); + for (unsigned i = 0; i < sz; i++) { + clause const & c = *(cs[i]); + SASSERT(max_var(c) == null_var); + SASSERT(max_bvar(c) == b); + } + } +#endif + return true; + } + + bool check_invariant() const { + SASSERT(check_watches()); + SASSERT(check_bwatches()); + return true; + } + + bool check_satisfied(clause_vector const & cs) const { + unsigned sz = cs.size(); + for (unsigned i = 0; i < sz; i++) { + clause const & c = *(cs[i]); + if (!is_satisfied(c)) { + TRACE("nlsat", tout << "not satisfied\n"; display(tout, c); tout << "\n";); + return false; + } + } + return true; + } + + bool check_satisfied() const { + TRACE("nlsat", tout << "bk: b" << m_bk << ", xk: x" << m_xk << "\n"; if (m_xk != null_var) { m_display_var(tout, m_xk); tout << "\n"; }); + unsigned num = m_atoms.size(); + if (m_bk != null_bool_var) + num = m_bk; + for (bool_var b = 0; b < num; b++) { + if (!check_satisfied(m_bwatches[b])) { + UNREACHABLE(); + return false; + } + } + if (m_xk != null_var) { + for (var x = 0; x < m_xk; x++) { + if (!check_satisfied(m_watches[x])) { + UNREACHABLE(); + return false; + } + } + } + return true; + } + + // ----------------------- + // + // Statistics + // + // ----------------------- + + void collect_statistics(statistics & st) { + st.update("nlsat conflicts", m_stats.m_conflicts); + st.update("nlsat propagations", m_stats.m_propagations); + st.update("nlsat decisions", m_stats.m_decisions); + st.update("nlsat restarts", m_stats.m_restarts); + st.update("nlsat stages", m_stats.m_stages); + st.update("nlsat simplifications", m_stats.m_simplifications); + st.update("nlsat irrational assignments", m_stats.m_irrational_assignments); + } + + void reset_statistics() { + m_stats.reset(); + } + + // ----------------------- + // + // Variable reordering + // + // ----------------------- + + struct var_info_collector { + pmanager & pm; + atom_vector const & m_atoms; + var_vector m_shuffle; + unsigned_vector m_max_degree; + unsigned_vector m_num_occs; + + var_info_collector(pmanager & _pm, atom_vector const & atoms, unsigned num_vars): + pm(_pm), + m_atoms(atoms) { + m_max_degree.resize(num_vars, 0); + m_num_occs.resize(num_vars, 0); + } + + var_vector m_vars; + void collect(poly * p) { + m_vars.reset(); + pm.vars(p, m_vars); + unsigned sz = m_vars.size(); + for (unsigned i = 0; i < sz; i++) { + var x = m_vars[i]; + unsigned k = pm.degree(p, x); + m_num_occs[x]++; + if (k > m_max_degree[x]) + m_max_degree[x] = k; + } + } + + void collect(literal l) { + bool_var b = l.var(); + atom * a = m_atoms[b]; + if (a == nullptr) + return; + if (a->is_ineq_atom()) { + unsigned sz = to_ineq_atom(a)->size(); + for (unsigned i = 0; i < sz; i++) { + collect(to_ineq_atom(a)->p(i)); + } + } + else { + collect(to_root_atom(a)->p()); + } + } + + void collect(clause const & c) { + unsigned sz = c.size(); + for (unsigned i = 0; i < sz; i++) + collect(c[i]); + } + + void collect(clause_vector const & cs) { + unsigned sz = cs.size(); + for (unsigned i = 0; i < sz; i++) + collect(*(cs[i])); + } + + std::ostream& display(std::ostream & out, display_var_proc const & proc) { + unsigned sz = m_num_occs.size(); + for (unsigned i = 0; i < sz; i++) { + proc(out, i); out << " -> " << m_max_degree[i] << " : " << m_num_occs[i] << "\n"; + } + return out; + } + }; + + struct reorder_lt { + var_info_collector const & m_info; + reorder_lt(var_info_collector const & info):m_info(info) {} + bool operator()(var x, var y) const { + // high degree first + if (m_info.m_max_degree[x] < m_info.m_max_degree[y]) + return false; + if (m_info.m_max_degree[x] > m_info.m_max_degree[y]) + return true; + // more constrained first + if (m_info.m_num_occs[x] < m_info.m_num_occs[y]) + return false; + if (m_info.m_num_occs[x] > m_info.m_num_occs[y]) + return true; + return m_info.m_shuffle[x] < m_info.m_shuffle[y]; + } + }; + + // Order variables by degree and number of occurrences + void heuristic_reorder() { + unsigned num = num_vars(); + var_info_collector collector(m_pm, m_atoms, num); + collector.collect(m_clauses); + collector.collect(m_learned); + init_shuffle(collector.m_shuffle); + TRACE("nlsat_reorder", collector.display(tout, m_display_var);); + var_vector new_order; + for (var x = 0; x < num; x++) + new_order.push_back(x); + + std::sort(new_order.begin(), new_order.end(), reorder_lt(collector)); + TRACE("nlsat_reorder", + tout << "new order: "; for (unsigned i = 0; i < num; i++) tout << new_order[i] << " "; tout << "\n";); + var_vector perm; + perm.resize(num, 0); + for (var x = 0; x < num; x++) { + perm[new_order[x]] = x; + } + reorder(perm.size(), perm.data()); + SASSERT(check_invariant()); + } + + void init_shuffle(var_vector& p) { + unsigned num = num_vars(); + for (var x = 0; x < num; x++) + p.push_back(x); + + random_gen r(++m_random_seed); + shuffle(p.size(), p.data(), r); + } + + void shuffle_vars() { + var_vector p; + init_shuffle(p); + reorder(p.size(), p.data()); + } + + bool can_reorder() const { + return all_of(m_learned, [&](clause* c) { return !has_root_atom(*c); }) + && all_of(m_clauses, [&](clause* c) { return !has_root_atom(*c); }); + } + + /** + \brief Reorder variables using the giving permutation. + p maps internal variables to their new positions + */ + + + void reorder(unsigned sz, var const * p) { + + remove_learned_roots(); + SASSERT(can_reorder()); + TRACE("nlsat_reorder", tout << "solver before variable reorder\n"; display(tout); + display_vars(tout); + tout << "\npermutation:\n"; + for (unsigned i = 0; i < sz; i++) tout << p[i] << " "; tout << "\n"; + ); + // verbose_stream() << "\npermutation: " << p[0] << " count " << count << " " << m_rlimit.is_canceled() << "\n"; + reinit_cache(); + SASSERT(num_vars() == sz); + TRACE("nlsat_bool_assignment_bug", tout << "before reset watches\n"; display_bool_assignment(tout);); + reset_watches(); + assignment new_assignment(m_am); + for (var x = 0; x < num_vars(); x++) { + if (m_assignment.is_assigned(x)) + new_assignment.set(p[x], m_assignment.value(x)); + } + var_vector new_inv_perm; + new_inv_perm.resize(sz); + // the undo_until_size(0) statement erases the Boolean assignment. + // undo_until_size(0) + undo_until_stage(null_var); + m_cache.reset(); +#ifdef Z3DEBUG + for (var x = 0; x < num_vars(); x++) { + SASSERT(m_watches[x].empty()); + } +#endif + // update m_perm mapping + for (unsigned ext_x = 0; ext_x < sz; ext_x++) { + // p: internal -> new pos + // m_perm: internal -> external + // m_inv_perm: external -> internal + new_inv_perm[ext_x] = p[m_inv_perm[ext_x]]; + m_perm.set(new_inv_perm[ext_x], ext_x); + } + bool_vector is_int; + is_int.swap(m_is_int); + for (var x = 0; x < sz; x++) { + m_is_int.setx(p[x], is_int[x], false); + SASSERT(m_infeasible[x] == 0); + } + m_inv_perm.swap(new_inv_perm); +#ifdef Z3DEBUG + for (var x = 0; x < num_vars(); x++) { + SASSERT(x == m_inv_perm[m_perm[x]]); + SASSERT(m_watches[x].empty()); + } +#endif + m_pm.rename(sz, p); + for (auto& b : m_bounds) + b.x = p[b.x]; + TRACE("nlsat_bool_assignment_bug", tout << "before reinit cache\n"; display_bool_assignment(tout);); + reinit_cache(); + m_assignment.swap(new_assignment); + reattach_arith_clauses(m_clauses); + reattach_arith_clauses(m_learned); + TRACE("nlsat_reorder", tout << "solver after variable reorder\n"; display(tout); display_vars(tout);); + } + + + /** + \brief Restore variable order. + */ + void restore_order() { + // m_perm: internal -> external + // m_inv_perm: external -> internal + var_vector p; + p.append(m_perm); + reorder(p.size(), p.data()); +#ifdef Z3DEBUG + for (var x = 0; x < num_vars(); x++) { + SASSERT(m_perm[x] == x); + SASSERT(m_inv_perm[x] == x); + } +#endif + } + + /** + \brief After variable reordering some lemmas containing root atoms may be ill-formed. + */ + void remove_learned_roots() { + unsigned j = 0; + for (clause* c : m_learned) { + if (has_root_atom(*c)) { + del_clause(c); + } + else { + m_learned[j++] = c; + } + } + m_learned.shrink(j); + } + + /** + \brief Return true if the clause contains an ill formed root atom + */ + bool has_root_atom(clause const & c) const { + for (literal lit : c) { + bool_var b = lit.var(); + atom * a = m_atoms[b]; + if (a && a->is_root_atom()) + return true; + } + return false; + } + + /** + \brief reinsert all polynomials in the unique cache + */ + void reinit_cache() { + reinit_cache(m_clauses); + reinit_cache(m_learned); + for (atom* a : m_atoms) + reinit_cache(a); + } + void reinit_cache(clause_vector const & cs) { + for (clause* c : cs) + reinit_cache(*c); + } + void reinit_cache(clause const & c) { + for (literal l : c) + reinit_cache(l); + } + void reinit_cache(literal l) { + bool_var b = l.var(); + reinit_cache(m_atoms[b]); + } + void reinit_cache(atom* a) { + if (a == nullptr) { + + } + else if (a->is_ineq_atom()) { + var max = 0; + unsigned sz = to_ineq_atom(a)->size(); + for (unsigned i = 0; i < sz; i++) { + poly * p = to_ineq_atom(a)->p(i); + VERIFY(m_cache.mk_unique(p) == p); + var x = m_pm.max_var(p); + if (x > max) + max = x; + } + a->m_max_var = max; + } + else { + poly * p = to_root_atom(a)->p(); + VERIFY(m_cache.mk_unique(p) == p); + a->m_max_var = m_pm.max_var(p); + } + } + + void reset_watches() { + unsigned num = num_vars(); + for (var x = 0; x < num; x++) { + m_watches[x].reset(); + } + } + + void reattach_arith_clauses(clause_vector const & cs) { + for (clause* cp : cs) { + var x = max_var(*cp); + if (x != null_var) + m_watches[x].push_back(cp); + } + } + + // ----------------------- + // + // Solver initialization + // + // ----------------------- + + struct degree_lt { + unsigned_vector & m_degrees; + degree_lt(unsigned_vector & ds):m_degrees(ds) {} + bool operator()(unsigned i1, unsigned i2) const { + if (m_degrees[i1] < m_degrees[i2]) + return true; + if (m_degrees[i1] > m_degrees[i2]) + return false; + return i1 < i2; + } + }; + + unsigned_vector m_cs_degrees; + unsigned_vector m_cs_p; + void sort_clauses_by_degree(unsigned sz, clause ** cs) { + if (sz <= 1) + return; + TRACE("nlsat_reorder_clauses", tout << "before:\n"; for (unsigned i = 0; i < sz; i++) { display(tout, *(cs[i])); tout << "\n"; }); + m_cs_degrees.reset(); + m_cs_p.reset(); + for (unsigned i = 0; i < sz; i++) { + m_cs_p.push_back(i); + m_cs_degrees.push_back(degree(*(cs[i]))); + } + std::sort(m_cs_p.begin(), m_cs_p.end(), degree_lt(m_cs_degrees)); + TRACE("nlsat_reorder_clauses", tout << "permutation: "; ::display(tout, m_cs_p.begin(), m_cs_p.end()); tout << "\n";); + apply_permutation(sz, cs, m_cs_p.data()); + TRACE("nlsat_reorder_clauses", tout << "after:\n"; for (unsigned i = 0; i < sz; i++) { display(tout, *(cs[i])); tout << "\n"; }); + } + + + struct degree_lit_num_lt { + unsigned_vector & m_degrees; + unsigned_vector & m_lit_num; + degree_lit_num_lt(unsigned_vector & ds, unsigned_vector & ln) : + m_degrees(ds), + m_lit_num(ln) { + } + bool operator()(unsigned i1, unsigned i2) const { + if (m_lit_num[i1] == 1 && m_lit_num[i2] > 1) + return true; + if (m_lit_num[i1] > 1 && m_lit_num[i2] == 1) + return false; + if (m_degrees[i1] != m_degrees[i2]) + return m_degrees[i1] < m_degrees[i2]; + if (m_lit_num[i1] != m_lit_num[i2]) + return m_lit_num[i1] < m_lit_num[i2]; + return i1 < i2; + } + }; + + unsigned_vector m_dl_degrees; + unsigned_vector m_dl_lit_num; + unsigned_vector m_dl_p; + void sort_clauses_by_degree_lit_num(unsigned sz, clause ** cs) { + if (sz <= 1) + return; + TRACE("nlsat_reorder_clauses", tout << "before:\n"; for (unsigned i = 0; i < sz; i++) { display(tout, *(cs[i])); tout << "\n"; }); + m_dl_degrees.reset(); + m_dl_lit_num.reset(); + m_dl_p.reset(); + for (unsigned i = 0; i < sz; i++) { + m_dl_degrees.push_back(degree(*(cs[i]))); + m_dl_lit_num.push_back(cs[i]->size()); + m_dl_p.push_back(i); + } + std::sort(m_dl_p.begin(), m_dl_p.end(), degree_lit_num_lt(m_dl_degrees, m_dl_lit_num)); + TRACE("nlsat_reorder_clauses", tout << "permutation: "; ::display(tout, m_dl_p.begin(), m_dl_p.end()); tout << "\n";); + apply_permutation(sz, cs, m_dl_p.data()); + TRACE("nlsat_reorder_clauses", tout << "after:\n"; for (unsigned i = 0; i < sz; i++) { display(tout, *(cs[i])); tout << "\n"; }); + } + + void sort_watched_clauses() { + unsigned num = num_vars(); + for (unsigned i = 0; i < num; i++) { + clause_vector & ws = m_watches[i]; + // sort_clauses_by_degree(ws.size(), ws.data()); + if (m_simple_check) { + sort_clauses_by_degree_lit_num(ws.size(), ws.data()); + } + else { + sort_clauses_by_degree(ws.size(), ws.data()); + } + } + } + + // ----------------------- + // + // Full dimensional + // + // A problem is in the full dimensional fragment if it does + // not contain equalities or non-strict inequalities. + // + // ----------------------- + + bool is_full_dimensional(literal l) const { + atom * a = m_atoms[l.var()]; + if (a == nullptr) + return true; + switch (a->get_kind()) { + case atom::EQ: return l.sign(); + case atom::LT: return !l.sign(); + case atom::GT: return !l.sign(); + case atom::ROOT_EQ: return l.sign(); + case atom::ROOT_LT: return !l.sign(); + case atom::ROOT_GT: return !l.sign(); + case atom::ROOT_LE: return l.sign(); + case atom::ROOT_GE: return l.sign(); + default: + UNREACHABLE(); + return false; + } + } + + bool is_full_dimensional(clause const & c) const { + for (literal l : c) { + if (!is_full_dimensional(l)) + return false; + } + return true; + } + + bool is_full_dimensional(clause_vector const & cs) const { + for (clause* c : cs) { + if (!is_full_dimensional(*c)) + return false; + } + return true; + } + + bool is_full_dimensional() const { + return is_full_dimensional(m_clauses); + } + + + // ----------------------- + // + // Simplification + // + // ----------------------- + + // solve simple equalities + // TBD WU-Reit decomposition? + + // - elim_unconstrained + // - solve_eqs + // - fm + + /** + \brief isolate variables in unit equalities. + Assume a clause is c == v*p + q + and the context implies p > 0 + + replace v by -q/p + remove clause c, + The for other occurrences of v, + replace v*r + v*v*r' > 0 by + by p*p*v*r + p*p*v*v*r' > 0 + by p*q*r + q*q*r' > 0 + + The method ignores lemmas and assumes constraints don't use roots. + */ + + + + // Eliminated variables are tracked in m_bounds. + // Each element in m_bounds tracks the eliminated variable and an upper or lower bound + // that has to be satisfied. Variables that are eliminated through equalities are tracked + // by non-strict bounds. A satisfiable solution is required to provide an evaluation that + // is consistent with the bounds. For equalities, the non-strict lower or upper bound can + // always be assigned as a value to the variable. + + void fix_patch() { + m_lo.reset(); m_hi.reset(); + for (auto& b : m_bounds) + m_assignment.reset(b.x); + for (unsigned i = m_bounds.size(); i-- > 0; ) + fix_patch(m_bounds[i]); + } + + // x is unassigned, lo < x -> x <- lo + 1 + // x is unassigned, x < hi -> x <- hi - 1 + // x is unassigned, lo <= x -> x <- lo + // x is unassigned, x <= hi -> x <- hi + // x is assigned above hi, lo is strict lo < x < hi -> set x <- (lo + hi)/2 + // x is assigned below hi, above lo -> no-op + // x is assigned below lo, hi is strict lo < x < hi -> set x <-> (lo + hi)/2 + // x is assigned above hi, x <= hi -> x <- hi + // x is assigned blow lo, lo <= x -> x <- lo + void fix_patch(bound_constraint& b) { + var x = b.x; + scoped_anum Av(m_am), Bv(m_am), val(m_am); + m_pm.eval(b.A, m_assignment, Av); + m_pm.eval(b.B, m_assignment, Bv); + m_am.neg(Bv); + val = Bv / Av; + // Ax >= B + // is-lower : A > 0 + // is-upper: A < 0 + // x <- B / A + bool is_lower = m_am.is_pos(Av); + TRACE("nlsat", + m_display_var(tout << "patch v" << x << " ", x) << "\n"; + if (m_assignment.is_assigned(x)) m_am.display(tout << "previous value: ", m_assignment.value(x)); tout << "\n"; + m_am.display(tout << "updated value: ", val); tout << "\n"; + ); + + if (!m_assignment.is_assigned(x)) { + if (!b.is_strict) + m_assignment.set_core(x, val); + else if (is_lower) + m_assignment.set_core(x, val + 1); + else + m_assignment.set_core(x, val - 1); + } + else { + auto& aval = m_assignment.value(x); + if (is_lower) { + // lo < value(x), lo < x -> x is unchanged + if (b.is_strict && m_am.lt(val, aval)) + ; + else if (!b.is_strict && m_am.le(val, aval)) + ; + else if (!b.is_strict) + m_assignment.set_core(x, val); + // aval < lo < x, hi is unassigned: x <- lo + 1 + else if (!m_hi.is_assigned(x)) + m_assignment.set_core(x, val + 1); + // aval < lo < x, hi is assigned: x <- (lo + hi) / 2 + else { + scoped_anum mid(m_am); + m_am.add(m_hi.value(x), val, mid); + mid = mid / 2; + m_assignment.set_core(x, mid); + } + } + else { + // dual to lower bounds + if (b.is_strict && m_am.lt(aval, val)) + ; + else if (!b.is_strict && m_am.le(aval, val)) + ; + else if (!b.is_strict) + m_assignment.set_core(x, val); + else if (!m_lo.is_assigned(x)) + m_assignment.set_core(x, val - 1); + else { + scoped_anum mid(m_am); + m_am.add(m_lo.value(x), val, mid); + mid = mid / 2; + m_assignment.set_core(x, mid); + } + } + } + + if (is_lower) { + if (!m_lo.is_assigned(x) || m_am.lt(m_lo.value(x), val)) + m_lo.set_core(x, val); + } + else { + if (!m_hi.is_assigned(x) || m_am.gt(m_hi.value(x), val)) + m_hi.set_core(x, val); + } + } + + bool is_unit_ineq(clause const& c) const { + return + c.size() == 1 && + m_atoms[c[0].var()] && + m_atoms[c[0].var()]->is_ineq_atom(); + } + + bool is_unit_eq(clause const& c) const { + return + is_unit_ineq(c) && + !c[0].sign() && + m_atoms[c[0].var()]->is_eq(); + } + + /** + \brief determine whether the clause is a comparison v > k or v < k', where k >= 0 or k' <= 0. + */ + lbool is_cmp0(clause const& c, var& v) { + if (!is_unit_ineq(c)) + return l_undef; + literal lit = c[0]; + ineq_atom const& a = *to_ineq_atom(m_atoms[lit.var()]); + bool sign = lit.sign(); + poly * p0; + if (!is_single_poly(a, p0)) + return l_undef; + if (m_pm.is_var(p0, v)) { + if (!sign && a.get_kind() == atom::GT) { + return l_true; + } + if (!sign && a.get_kind() == atom::LT) { + return l_false; + } + return l_undef; + } + polynomial::scoped_numeral n(m_pm.m()); + if (m_pm.is_var_num(p0, v, n)) { + // x - k > 0 + if (!sign && a.get_kind() == atom::GT && m_pm.m().is_nonneg(n)) { + return l_true; + } + // x + k < 0 + if (!sign && a.get_kind() == atom::LT && m_pm.m().is_nonpos(n)) { + return l_false; + } + // !(x + k > 0) + if (sign && a.get_kind() == atom::GT && m_pm.m().is_pos(n)) { + return l_false; + } + // !(x - k < 0) + if (sign && a.get_kind() == atom::LT && m_pm.m().is_neg(n)) { + return l_true; + } + } + return l_undef; + } + + bool is_single_poly(ineq_atom const& a, poly*& p) { + unsigned sz = a.size(); + return sz == 1 && a.is_odd(0) && (p = a.p(0), true); + } + + bool is_unit(polynomial_ref const& p) { + if (!m_pm.is_const(p)) + return false; + auto const& c = m_pm.coeff(p, 0); + return m_pm.m().is_one(c) || m_pm.m().is_minus_one(c); + } + + // ----------------------- + // + // Pretty printing + // + // ----------------------- + + std::ostream& display_num_assignment(std::ostream & out, display_var_proc const & proc) const { + for (var x = 0; x < num_vars(); x++) { + if (m_assignment.is_assigned(x)) { + proc(out, x); + out << " -> "; + m_am.display_decimal(out, m_assignment.value(x)); + out << "\n"; + } + } + return out; + } + + std::ostream& display_bool_assignment(std::ostream & out) const { + unsigned sz = m_atoms.size(); + for (bool_var b = 0; b < sz; b++) { + if (m_atoms[b] == nullptr && m_bvalues[b] != l_undef) { + out << "b" << b << " -> " << (m_bvalues[b] == l_true ? "true" : "false") << " @" << m_levels[b] << "\n"; + } + else if (m_atoms[b] != nullptr && m_bvalues[b] != l_undef) { + display(out << "b" << b << " ", *m_atoms[b]) << " -> " << (m_bvalues[b] == l_true ? "true" : "false") << " @" << m_levels[b] << "\n"; + } + } + TRACE("nlsat_bool_assignment", + for (bool_var b = 0; b < sz; b++) { + out << "b" << b << " -> " << m_bvalues[b] << " "; + if (m_atoms[b]) display(out, *m_atoms[b]); + out << "\n"; + }); + return out; + } + + bool display_mathematica_assignment(std::ostream & out) const { + bool first = true; + for (var x = 0; x < num_vars(); x++) { + if (m_assignment.is_assigned(x)) { + if (first) + first = false; + else + out << " && "; + out << "x" << x << " == "; + m_am.display_mathematica(out, m_assignment.value(x)); + } + } + return !first; + } + + std::ostream& display_num_assignment(std::ostream & out) const { + return display_num_assignment(out, m_display_var); + } + + std::ostream& display_assignment(std::ostream& out) const { + display_bool_assignment(out); + display_num_assignment(out); + return out; + } + + std::ostream& display(std::ostream& out, justification j) const { + switch (j.get_kind()) { + case justification::CLAUSE: + display(out, *j.get_clause()) << "\n"; + break; + case justification::LAZY: { + lazy_justification const& lz = *j.get_lazy(); + display_not(out, lz.num_lits(), lz.lits()) << "\n"; + for (unsigned i = 0; i < lz.num_clauses(); ++i) { + display(out, lz.clause(i)) << "\n"; + } + break; + } + default: + out << j.get_kind() << "\n"; + break; + } + return out; + } + + bool m_display_eval = false; + std::ostream& display_eval(std::ostream& out, justification j) { + flet _display(m_display_eval, true); + return display(out, j); + } + + std::ostream& display_ineq(std::ostream & out, ineq_atom const & a, display_var_proc const & proc, bool use_star = false) const { + unsigned sz = a.size(); + for (unsigned i = 0; i < sz; i++) { + if (use_star && i > 0) + out << "*"; + bool is_even = a.is_even(i); + if (is_even || sz > 1) + out << "("; + display_polynomial(out, a.p(i), proc, use_star); + if (is_even || sz > 1) + out << ")"; + if (is_even) + out << "^2"; + } + switch (a.get_kind()) { + case atom::LT: out << " < 0"; break; + case atom::GT: out << " > 0"; break; + case atom::EQ: out << " = 0"; break; + default: UNREACHABLE(); break; + } + return out; + } + + std::ostream& display_mathematica(std::ostream & out, ineq_atom const & a) const { + unsigned sz = a.size(); + for (unsigned i = 0; i < sz; i++) { + if (i > 0) + out << "*"; + bool is_even = a.is_even(i); + if (sz > 1) + out << "("; + if (is_even) + out << "("; + m_pm.display(out, a.p(i), display_var_proc(), true); + if (is_even) + out << "^2)"; + if (sz > 1) + out << ")"; + } + switch (a.get_kind()) { + case atom::LT: out << " < 0"; break; + case atom::GT: out << " > 0"; break; + case atom::EQ: out << " == 0"; break; + default: UNREACHABLE(); break; + } + return out; + } + + std::ostream& display_polynomial_smt2(std::ostream & out, poly const* p, display_var_proc const & proc) const { + return m_pm.display_smt2(out, p, proc); + } + + std::ostream& display_ineq_smt2(std::ostream & out, ineq_atom const & a, display_var_proc const & proc) const { + switch (a.get_kind()) { + case atom::LT: out << "(< "; break; + case atom::GT: out << "(> "; break; + case atom::EQ: out << "(= "; break; + default: UNREACHABLE(); break; + } + unsigned sz = a.size(); + if (sz > 1) + out << "(* "; + for (unsigned i = 0; i < sz; i++) { + if (i > 0) out << " "; + if (a.is_even(i)) { + out << "(* "; + display_polynomial_smt2(out, a.p(i), proc); + out << " "; + display_polynomial_smt2(out, a.p(i), proc); + out << ")"; + } + else { + display_polynomial_smt2(out, a.p(i), proc); + } + } + if (sz > 1) + out << ")"; + out << " 0)"; + return out; + } + + std::ostream& display_poly_root(std::ostream& out, char const* y, root_atom const& a, display_var_proc const& proc) const { + out << "(exists (("; proc(out,a.x()); out << " Real))\n"; + out << "(and (= " << y << " "; + proc(out, a.x()); + out << ") (= 0 "; + display_polynomial_smt2(out, a.p(), proc); + out << ")))\n"; + return out; + } + + std::ostream& display_binary_smt2(std::ostream& out, poly const* p1, char const* rel, poly const* p2, display_var_proc const& proc) const { + out << "(" << rel << " "; + display_polynomial_smt2(out, p1, proc); + out << " "; + display_polynomial_smt2(out, p2, proc); + out << ")"; + return out; + } + + + std::ostream& display_linear_root_smt2(std::ostream & out, root_atom const & a, display_var_proc const & proc) const { + polynomial_ref A(m_pm), B(m_pm), Z(m_pm), Ax(m_pm); + polynomial::scoped_numeral zero(m_qm); + m_pm.m().set(zero, 0); + A = m_pm.derivative(a.p(), a.x()); + B = m_pm.neg(m_pm.substitute(a.p(), a.x(), zero)); + Z = m_pm.mk_zero(); + + Ax = m_pm.mul(m_pm.mk_polynomial(a.x()), A); + + // x < root[1](ax + b) == (a > 0 => ax + b < 0) & (a < 0 => ax + b > 0) + // x < root[1](ax + b) == (a > 0 => ax < -b) & (a < 0 => ax > -b) + + char const* rel1 = "<", *rel2 = ">"; + switch (a.get_kind()) { + case atom::ROOT_LT: rel1 = "<"; rel2 = ">"; break; + case atom::ROOT_GT: rel1 = ">"; rel2 = "<"; break; + case atom::ROOT_LE: rel1 = "<="; rel2 = ">="; break; + case atom::ROOT_GE: rel1 = ">="; rel2 = "<="; break; + case atom::ROOT_EQ: rel1 = rel2 = "="; break; + default: UNREACHABLE(); break; + } + + out << "(and "; + out << "(=> "; display_binary_smt2(out, A, ">", Z, proc); display_binary_smt2(out, Ax, rel1, B, proc); out << ") "; + out << "(=> "; display_binary_smt2(out, A, "<", Z, proc); display_binary_smt2(out, Ax, rel2, B, proc); out << ") "; + out << ")"; + + return out; + } + + + std::ostream& display_root_smt2(std::ostream& out, root_atom const& a, display_var_proc const& proc) const { + if (a.i() == 1 && m_pm.degree(a.p(), a.x()) == 1) + return display_linear_root_smt2(out, a, proc); +#if 1 + out << "(exists ("; + for (unsigned j = 0; j < a.i(); ++j) { + std::string y = std::string("y") + std::to_string(j); + out << "(" << y << " Real) "; + } + out << ")\n"; + out << "(and\n"; + for (unsigned j = 0; j < a.i(); ++j) { + std::string y = std::string("y") + std::to_string(j); + display_poly_root(out, y.c_str(), a, proc); + } + for (unsigned j = 0; j + 1 < a.i(); ++j) { + std::string y1 = std::string("y") + std::to_string(j); + std::string y2 = std::string("y") + std::to_string(j+1); + out << "(< " << y1 << " " << y2 << ")\n"; + } + + std::string yn = "y" + std::to_string(a.i() - 1); + + // TODO we need (forall z : z < yn . p(z) => z = y1 or ... z = y_{n-1}) + // to say y1, .., yn are the first n distinct roots. + // + out << "(forall ((z Real)) (=> (and (< z " << yn << ") "; display_poly_root(out, "z", a, proc) << ") "; + if (a.i() == 1) { + out << "false))\n"; + } + else { + out << "(or "; + for (unsigned j = 0; j + 1 < a.i(); ++j) { + std::string y1 = std::string("y") + std::to_string(j); + out << "(= z " << y1 << ") "; + } + out << ")))\n"; + } + switch (a.get_kind()) { + case atom::ROOT_LT: out << "(< "; proc(out, a.x()); out << " " << yn << ")"; break; + case atom::ROOT_GT: out << "(> "; proc(out, a.x()); out << " " << yn << ")"; break; + case atom::ROOT_LE: out << "(<= "; proc(out, a.x()); out << " " << yn << ")"; break; + case atom::ROOT_GE: out << "(>= "; proc(out, a.x()); out << " " << yn << ")"; break; + case atom::ROOT_EQ: out << "(= "; proc(out, a.x()); out << " " << yn << ")"; NOT_IMPLEMENTED_YET(); break; + default: UNREACHABLE(); break; + } + out << "))"; + return out; +#endif + + + return display_root(out, a, proc); + } + + std::ostream& display_root(std::ostream & out, root_atom const & a, display_var_proc const & proc) const { + proc(out, a.x()); + switch (a.get_kind()) { + case atom::ROOT_LT: out << " < "; break; + case atom::ROOT_GT: out << " > "; break; + case atom::ROOT_LE: out << " <= "; break; + case atom::ROOT_GE: out << " >= "; break; + case atom::ROOT_EQ: out << " = "; break; + default: UNREACHABLE(); break; + } + out << "root[" << a.i() << "]("; + display_polynomial(out, a.p(), proc); + out << ")"; + return out; + } + + struct mathematica_var_proc : public display_var_proc { + var m_x; + public: + mathematica_var_proc(var x):m_x(x) {} + std::ostream& operator()(std::ostream & out, var x) const override { + if (m_x == x) + return out << "#1"; + else + return out << "x" << x; + } + }; + + std::ostream& display_mathematica(std::ostream & out, root_atom const & a) const { + out << "x" << a.x(); + switch (a.get_kind()) { + case atom::ROOT_LT: out << " < "; break; + case atom::ROOT_GT: out << " > "; break; + case atom::ROOT_LE: out << " <= "; break; + case atom::ROOT_GE: out << " >= "; break; + case atom::ROOT_EQ: out << " == "; break; + default: UNREACHABLE(); break; + } + out << "Root["; + display_polynomial(out, a.p(), mathematica_var_proc(a.x()), true); + out << " &, " << a.i() << "]"; + return out; + } + + std::ostream& display(std::ostream & out, atom const & a, display_var_proc const & proc) const { + if (a.is_ineq_atom()) + return display_ineq(out, static_cast(a), proc); + else + return display_root(out, static_cast(a), proc); + } + + std::ostream& display(std::ostream & out, atom const & a) const { + return display(out, a, m_display_var); + } + + std::ostream& display_mathematica(std::ostream & out, atom const & a) const { + if (a.is_ineq_atom()) + return display_mathematica(out, static_cast(a)); + else + return display_mathematica(out, static_cast(a)); + } + + std::ostream& display_smt2(std::ostream & out, atom const & a, display_var_proc const & proc) const { + if (a.is_ineq_atom()) + return display_ineq_smt2(out, static_cast(a), proc); + else + return display_root_smt2(out, static_cast(a), proc); + } + + std::ostream& display_atom(std::ostream & out, bool_var b, display_var_proc const & proc) const { + if (b == 0) + out << "true"; + else if (m_atoms[b] == 0) + out << "b" << b; + else + display(out, *(m_atoms[b]), proc); + return out; + } + + std::ostream& display_atom(std::ostream & out, bool_var b) const { + return display_atom(out, b, m_display_var); + } + + std::ostream& display_mathematica_atom(std::ostream & out, bool_var b) const { + if (b == 0) + out << "(0 < 1)"; + else if (m_atoms[b] == 0) + out << "b" << b; + else + display_mathematica(out, *(m_atoms[b])); + return out; + } + + std::ostream& display_smt2_atom(std::ostream & out, bool_var b, display_var_proc const & proc) const { + if (b == 0) + out << "true"; + else if (m_atoms[b] == 0) + out << "b" << b; + else + display_smt2(out, *(m_atoms[b]), proc); + return out; + } + + std::ostream& display(std::ostream & out, literal l, display_var_proc const & proc) const { + if (l.sign()) { + bool_var b = l.var(); + out << "!"; + if (m_atoms[b] != 0) + out << "("; + display_atom(out, b, proc); + if (m_atoms[b] != 0) + out << ")"; + } + else { + display_atom(out, l.var(), proc); + } + return out; + } + + std::ostream& display(std::ostream & out, literal l) const { + return display(out, l, m_display_var); + } + + std::ostream& display_smt2(std::ostream & out, literal l) const { + return display_smt2(out, l, m_display_var); + } + + std::ostream& display_mathematica(std::ostream & out, literal l) const { + if (l.sign()) { + bool_var b = l.var(); + out << "!"; + if (m_atoms[b] != 0) + out << "("; + display_mathematica_atom(out, b); + if (m_atoms[b] != 0) + out << ")"; + } + else { + display_mathematica_atom(out, l.var()); + } + return out; + } + + std::ostream& display_smt2(std::ostream & out, literal l, display_var_proc const & proc) const { + if (l.sign()) { + bool_var b = l.var(); + out << "(not "; + display_smt2_atom(out, b, proc); + out << ")"; + } + else { + display_smt2_atom(out, l.var(), proc); + } + return out; + } + + std::ostream& display_assumptions(std::ostream & out, _assumption_set s) const { + if (!m_display_assumption) + return out; + vector deps; + m_asm.linearize(s, deps); + bool first = true; + for (auto dep : deps) { + if (first) first = false; else out << " "; + (*m_display_assumption)(out, dep); + } + return out; + } + + std::ostream& display(std::ostream & out, unsigned num, literal const * ls, display_var_proc const & proc) const { + for (unsigned i = 0; i < num; i++) { + if (i > 0) + out << " or "; + display(out, ls[i], proc); + } + return out; + } + + std::ostream& display(std::ostream & out, unsigned num, literal const * ls) const { + return display(out, num, ls, m_display_var); + } + + std::ostream& display_not(std::ostream & out, unsigned num, literal const * ls, display_var_proc const & proc) const { + for (unsigned i = 0; i < num; i++) { + if (i > 0) + out << " or "; + display(out, ~ls[i], proc); + } + return out; + } + + std::ostream& display_not(std::ostream & out, unsigned num, literal const * ls) const { + return display_not(out, num, ls, m_display_var); + } + + std::ostream& display(std::ostream & out, scoped_literal_vector const & cs) { + return display(out, cs.size(), cs.data(), m_display_var); + } + + std::ostream& display(std::ostream & out, clause const & c, display_var_proc const & proc) const { + if (c.assumptions() != nullptr) { + display_assumptions(out, static_cast<_assumption_set>(c.assumptions())); + out << " |- "; + } + return display(out, c.size(), c.data(), proc); + } + + std::ostream& display(std::ostream & out, clause const & c) const { + return display(out, c, m_display_var); + } + + + std::ostream& display_polynomial(std::ostream& out, poly* p, display_var_proc const & proc, bool use_star = false) const { + if (m_display_eval) { + polynomial_ref q(m_pm); + q = p; + for (var x = 0; x < num_vars(); x++) + if (m_assignment.is_assigned(x)) { + auto& a = m_assignment.value(x); + if (!m_am.is_rational(a)) + continue; + mpq r; + m_am.to_rational(a, r); + q = m_pm.substitute(q, 1, &x, &r); + } + m_pm.display(out, q, proc, use_star); + } + else + m_pm.display(out, p, proc, use_star); + return out; + } + + // -- + + std::ostream& display_smt2(std::ostream & out, unsigned n, literal const* ls) const { + return display_smt2(out, n, ls, display_var_proc()); + } + + + std::ostream& display_smt2(std::ostream & out, unsigned num, literal const * ls, display_var_proc const & proc) const { + if (num == 0) { + out << "false"; + } + else if (num == 1) { + display_smt2(out, ls[0], proc); + } + else { + out << "(or"; + for (unsigned i = 0; i < num; i++) { + out << " "; + display_smt2(out, ls[i], proc); + } + out << ")"; + } + return out; + } + + std::ostream& display_smt2(std::ostream & out, clause const & c, display_var_proc const & proc = display_var_proc()) const { + return display_smt2(out, c.size(), c.data(), proc); + } + + std::ostream& display_abst(std::ostream & out, literal l) const { + if (l.sign()) { + bool_var b = l.var(); + out << "!"; + if (b == true_bool_var) + out << "true"; + else + out << "b" << b; + } + else { + out << "b" << l.var(); + } + return out; + } + + std::ostream& display_abst(std::ostream & out, unsigned num, literal const * ls) const { + for (unsigned i = 0; i < num; i++) { + if (i > 0) + out << " or "; + display_abst(out, ls[i]); + } + return out; + } + + std::ostream& display_abst(std::ostream & out, scoped_literal_vector const & cs) const { + return display_abst(out, cs.size(), cs.data()); + } + + std::ostream& display_abst(std::ostream & out, clause const & c) const { + return display_abst(out, c.size(), c.data()); + } + + std::ostream& display_mathematica(std::ostream & out, clause const & c) const { + out << "("; + unsigned sz = c.size(); + for (unsigned i = 0; i < sz; i++) { + if (i > 0) + out << " || "; + display_mathematica(out, c[i]); + } + out << ")"; + return out; + } + + // Debugging support: + // Display generated lemma in Mathematica format. + // Mathematica must reduce lemma to True (modulo resource constraints). + std::ostream& display_mathematica_lemma(std::ostream & out, unsigned num, literal const * ls, bool include_assignment = false) const { + out << "Resolve[ForAll[{"; + // var definition + for (unsigned i = 0; i < num_vars(); i++) { + if (i > 0) + out << ", "; + out << "x" << i; + } + out << "}, "; + if (include_assignment) { + out << "!("; + if (!display_mathematica_assignment(out)) + out << "0 < 1"; // nothing was printed + out << ") || "; + } + for (unsigned i = 0; i < num; i++) { + if (i > 0) + out << " || "; + display_mathematica(out, ls[i]); + } + out << "], Reals]\n"; // end of exists + return out; + } + + std::ostream& display(std::ostream & out, clause_vector const & cs, display_var_proc const & proc) const { + for (clause* c : cs) { + display(out, *c, proc) << "\n"; + } + return out; + } + + std::ostream& display(std::ostream & out, clause_vector const & cs) const { + return display(out, cs, m_display_var); + } + + std::ostream& display_mathematica(std::ostream & out, clause_vector const & cs) const { + unsigned sz = cs.size(); + for (unsigned i = 0; i < sz; i++) { + if (i > 0) out << ",\n"; + display_mathematica(out << " ", *(cs[i])); + } + return out; + } + + std::ostream& display_abst(std::ostream & out, clause_vector const & cs) const { + for (clause* c : cs) { + display_abst(out, *c) << "\n"; + } + return out; + } + + std::ostream& display(std::ostream & out, display_var_proc const & proc) const { + display(out, m_clauses, proc); + if (!m_learned.empty()) { + display(out << "Lemmas:\n", m_learned, proc); + } + return out; + } + + std::ostream& display_mathematica(std::ostream & out) const { + return display_mathematica(out << "{\n", m_clauses) << "}\n"; + } + + std::ostream& display_abst(std::ostream & out) const { + display_abst(out, m_clauses); + if (!m_learned.empty()) { + display_abst(out << "Lemmas:\n", m_learned); + } + return out; + } + + std::ostream& display(std::ostream & out) const { + display(out, m_display_var); + display_assignment(out << "assignment:\n"); + return out << "---\n"; + } + + std::ostream& display_vars(std::ostream & out) const { + for (unsigned i = 0; i < num_vars(); i++) { + out << i << " -> "; m_display_var(out, i); out << "\n"; + } + return out; + } + + std::ostream& display_smt2_arith_decls(std::ostream & out) const { + unsigned sz = m_is_int.size(); + for (unsigned i = 0; i < sz; i++) { + if (is_int(i)) { + out << "(declare-fun "; m_display_var(out, i) << " () Int)\n"; + } + else { + out << "(declare-fun "; m_display_var(out, i) << " () Real)\n"; + } + } + return out; + } + + std::ostream& display_smt2_bool_decls(std::ostream & out) const { + unsigned sz = m_atoms.size(); + for (unsigned i = 0; i < sz; i++) { + if (m_atoms[i] == nullptr) + out << "(declare-fun b" << i << " () Bool)\n"; + } + return out; + } + + std::ostream& display_smt2(std::ostream & out) const { + display_smt2_bool_decls(out); + display_smt2_arith_decls(out); + out << "(assert (and true\n"; + for (clause* c : m_clauses) { + display_smt2(out, *c, m_display_var) << "\n"; + } + out << "))\n" << std::endl; + return out; + } + }; + + solver::solver(reslimit& rlim, params_ref const & p, bool incremental) { + m_ctx = alloc(ctx, rlim, p, incremental); + m_imp = alloc(imp, *this, *m_ctx); + } + + solver::solver(ctx& ctx) { + m_ctx = nullptr; + m_imp = alloc(imp, *this, ctx); + } + + solver::~solver() { + dealloc(m_imp); + dealloc(m_ctx); + } + + lbool solver::check() { + return m_imp->check(); + } + + lbool solver::check(literal_vector& assumptions) { + return m_imp->check(assumptions); + } + + void solver::get_core(vector& assumptions) { + return m_imp->get_core(assumptions); + } + + void solver::reset() { + m_imp->reset(); + } + + + void solver::updt_params(params_ref const & p) { + m_imp->updt_params(p); + } + + + void solver::collect_param_descrs(param_descrs & d) { + algebraic_numbers::manager::collect_param_descrs(d); + nlsat_params::collect_param_descrs(d); + } + + unsynch_mpq_manager & solver::qm() { + return m_imp->m_qm; + } + + anum_manager & solver::am() { + return m_imp->m_am; + } + + pmanager & solver::pm() { + return m_imp->m_pm; + } + + void solver::set_display_var(display_var_proc const & proc) { + m_imp->m_display_var.m_proc = &proc; + } + + void solver::set_display_assumption(display_assumption_proc const& proc) { + m_imp->m_display_assumption = &proc; + } + + + unsigned solver::num_vars() const { + return m_imp->num_vars(); + } + + bool solver::is_int(var x) const { + return m_imp->is_int(x); + } + + bool_var solver::mk_bool_var() { + return m_imp->mk_bool_var(); + } + + literal solver::mk_true() { + return literal(0, false); + } + + atom * solver::bool_var2atom(bool_var b) { + return m_imp->m_atoms[b]; + } + + void solver::vars(literal l, var_vector& vs) { + m_imp->vars(l, vs); + } + + atom_vector const& solver::get_atoms() { + return m_imp->m_atoms; + } + + atom_vector const& solver::get_var2eq() { + return m_imp->m_var2eq; + } + + evaluator& solver::get_evaluator() { + return m_imp->m_evaluator; + } + + explain& solver::get_explain() { + return m_imp->m_explain; + } + + void solver::reorder(unsigned sz, var const* p) { + m_imp->reorder(sz, p); + } + + void solver::restore_order() { + m_imp->restore_order(); + } + + void solver::set_rvalues(assignment const& as) { + m_imp->m_assignment.copy(as); + } + + void solver::get_rvalues(assignment& as) { + as.copy(m_imp->m_assignment); + } + + void solver::get_bvalues(svector const& bvars, svector& vs) { + vs.reset(); + for (bool_var b : bvars) { + vs.reserve(b + 1, l_undef); + if (!m_imp->m_atoms[b]) { + vs[b] = m_imp->m_bvalues[b]; + } + } + TRACE("nlsat", display(tout);); + } + + void solver::set_bvalues(svector const& vs) { + TRACE("nlsat", display(tout);); + for (bool_var b = 0; b < vs.size(); ++b) { + if (vs[b] != l_undef) { + m_imp->m_bvalues[b] = vs[b]; + SASSERT(!m_imp->m_atoms[b]); + } + } +#if 0 + m_imp->m_bvalues.reset(); + m_imp->m_bvalues.append(vs); + m_imp->m_bvalues.resize(m_imp->m_atoms.size(), l_undef); + for (unsigned i = 0; i < m_imp->m_atoms.size(); ++i) { + atom* a = m_imp->m_atoms[i]; + SASSERT(!a); + if (a) { + m_imp->m_bvalues[i] = to_lbool(m_imp->m_evaluator.eval(a, false)); + } + } +#endif + TRACE("nlsat", display(tout);); + } + + void solver::del_clause(clause* c) { + m_imp->del_clause(c); + } + + var solver::mk_var(bool is_int) { + return m_imp->mk_var(is_int); + } + + bool_var solver::mk_ineq_atom(atom::kind k, unsigned sz, poly * const * ps, bool const * is_even) { + return m_imp->mk_ineq_atom(k, sz, ps, is_even); + } + + literal solver::mk_ineq_literal(atom::kind k, unsigned sz, poly * const * ps, bool const * is_even, bool simplify) { + return m_imp->mk_ineq_literal(k, sz, ps, is_even, simplify); + } + + bool_var solver::mk_root_atom(atom::kind k, var x, unsigned i, poly * p) { + return m_imp->mk_root_atom(k, x, i, p); + } + + void solver::inc_ref(bool_var b) { + m_imp->inc_ref(b); + } + + void solver::dec_ref(bool_var b) { + m_imp->dec_ref(b); + } + + void solver::inc_ref(assumption a) { + m_imp->inc_ref(static_cast(a)); + } + + void solver::dec_ref(assumption a) { + m_imp->dec_ref(static_cast(a)); + } + + void solver::mk_clause(unsigned num_lits, literal * lits, assumption a) { + return m_imp->mk_external_clause(num_lits, lits, a); + } + + std::ostream& solver::display(std::ostream & out) const { + return m_imp->display(out); + } + + std::ostream& solver::display(std::ostream & out, literal l) const { + return m_imp->display(out, l); + } + + std::ostream& solver::display(std::ostream & out, unsigned n, literal const* ls) const { + for (unsigned i = 0; i < n; ++i) { + display(out, ls[i]); + out << "; "; + } + return out; + } + + std::ostream& solver::display(std::ostream & out, literal_vector const& ls) const { + return display(out, ls.size(), ls.data()); + } + + std::ostream& solver::display_smt2(std::ostream & out, literal l) const { + return m_imp->display_smt2(out, l); + } + + std::ostream& solver::display_smt2(std::ostream & out, unsigned n, literal const* ls) const { + for (unsigned i = 0; i < n; ++i) { + display_smt2(out, ls[i]); + out << " "; + } + return out; + } + + std::ostream& solver::display(std::ostream& out, clause const& c) const { + return m_imp->display(out, c); + } + + std::ostream& solver::display_smt2(std::ostream & out) const { + return m_imp->display_smt2(out); + } + + std::ostream& solver::display_smt2(std::ostream & out, literal_vector const& ls) const { + return display_smt2(out, ls.size(), ls.data()); + } + + std::ostream& solver::display(std::ostream & out, var x) const { + return m_imp->m_display_var(out, x); + } + + std::ostream& solver::display(std::ostream & out, atom const& a) const { + return m_imp->display(out, a, m_imp->m_display_var); + } + + display_var_proc const & solver::display_proc() const { + return m_imp->m_display_var; + } + + anum const & solver::value(var x) const { + if (m_imp->m_assignment.is_assigned(x)) + return m_imp->m_assignment.value(x); + return m_imp->m_zero; + } + + lbool solver::bvalue(bool_var b) const { + return m_imp->m_bvalues[b]; + } + + lbool solver::value(literal l) const { + return m_imp->value(l); + } + + bool solver::is_interpreted(bool_var b) const { + return m_imp->m_atoms[b] != 0; + } + + void solver::reset_statistics() { + return m_imp->reset_statistics(); + } + + void solver::collect_statistics(statistics & st) { + return m_imp->collect_statistics(st); + } + + clause* solver::mk_clause(unsigned n, literal const* lits, bool learned, internal_assumption a) { + return m_imp->mk_clause(n, lits, learned, static_cast(a)); + } + + void solver::inc_simplify() { + m_imp->m_stats.m_simplifications++; + } + + bool solver::has_root_atom(clause const& c) const { + return m_imp->has_root_atom(c); + } + + void solver::add_bound(bound_constraint const& c) { + m_imp->m_bounds.push_back(c); + } + + assumption solver::join(assumption a, assumption b) { + return (m_imp->m_asm.mk_join(static_cast(a), static_cast(b))); + } + +}; diff --git a/src/nlsat/nlsat_variable_ordering_strategy.cpp b/src/nlsat/nlsat_variable_ordering_strategy.cpp new file mode 100644 index 000000000..5b91501e3 --- /dev/null +++ b/src/nlsat/nlsat_variable_ordering_strategy.cpp @@ -0,0 +1,282 @@ +#include "nlsat/nlsat_variable_ordering_strategy.h" + +namespace nlsat { + struct vos_var_info_collector::imp { + pmanager & pm; + atom_vector const & m_atoms; + unsigned num_vars; + Variable_Ordering_Strategy_Type m_vos_type; + + /** Maximum degree of this variable. */ + unsigned_vector m_max_degree; + /** Sum of degrees of this variable within all polynomials. */ + unsigned_vector m_sum_poly_degree; + /** Number of polynomials that contain this variable. */ + unsigned_vector m_num_polynomials; + + /** Maximum degree of the leading coefficient of this variable. */ + unsigned_vector m_max_lc_degree; + /** Maximum of total degrees of terms that contain this variable. */ + unsigned_vector m_max_terms_tdegree; + /** Sum of degrees of this variable within all terms. */ + unsigned_vector m_sum_term_degree; + /** Number of terms that contain this variable. */ + unsigned_vector m_num_terms; + + + unsigned_vector m_num_uni; + numeral_vector m_coeffs; + + + imp(pmanager & _pm, atom_vector const & atoms, unsigned _num_vars, unsigned _vos_type): + pm(_pm), + m_atoms(atoms), + num_vars(_num_vars), + m_vos_type(Variable_Ordering_Strategy_Type(_vos_type)) { + + m_max_degree.resize(num_vars, 0); + m_sum_poly_degree.resize(num_vars, 0); + m_num_polynomials.resize(num_vars, 0); + + if (m_vos_type != ONLYPOLY) { + m_max_lc_degree.resize(num_vars, 0); + m_max_terms_tdegree.resize(num_vars, 0); + m_sum_term_degree.resize(num_vars, 0); + m_num_terms.resize(num_vars, 0); + + + m_num_uni.resize(num_vars, 0); + m_coeffs.resize(num_vars, 0); + + } + } + + void collect(monomial * m) { + unsigned mdeg = 0; + for (unsigned i = 0, sz = pm.size(m); i < sz; ++i) { + var x = pm.get_var(m, i); + mdeg += pm.degree_of(m, x); + ++m_num_terms[x]; + } + + for (unsigned i = 0, sz = pm.size(m); i < sz; ++i) { + var x = pm.get_var(m, i); + m_sum_term_degree[x] += mdeg; + if (mdeg > m_max_terms_tdegree[x]) + m_max_terms_tdegree[x] = mdeg; + unsigned lc_deg = mdeg - pm.degree_of(m, x); + if (lc_deg > m_max_lc_degree[x]) + m_max_lc_degree[x] = lc_deg; + } + } + + void collect(poly * p) { + var_vector vec_vars; + pm.vars(p, vec_vars); + + if (m_vos_type == UNIVARIATE) { + if (vec_vars.size() == 1) + ++m_num_uni[vec_vars[0]]; + } + + for (unsigned i = 0, sz = vec_vars.size(); i < sz; ++i) { + var x = vec_vars[i]; + unsigned k = pm.degree(p, x); + ++m_num_polynomials[x]; + m_sum_poly_degree[x] += k; + if (k > m_max_degree[x]) + m_max_degree[x] = k; + + if (m_vos_type == FEATURE){ + for (unsigned kl = 0; kl <= k; kl++) { + scoped_numeral curr(pm.m()); + if (pm.const_coeff(p, x, kl, curr)) { + pm.m().abs(curr); + if (pm.m().gt(curr, m_coeffs[x])) { + pm.m().set(m_coeffs[x], curr); + } + } + } + } + + } + + if (m_vos_type != ONLYPOLY && m_vos_type != UNIVARIATE){ + for (unsigned i = 0, sz = pm.size(p); i < sz; ++i) { + collect(pm.get_monomial(p, i)); + } + } + } + + void collect(literal l) { + bool_var b = l.var(); + atom * a = m_atoms[b]; + if (a == nullptr) + return; + if (a->is_ineq_atom()) { + unsigned sz = to_ineq_atom(a)->size(); + for (unsigned i = 0; i < sz; i++) { + collect(to_ineq_atom(a)->p(i)); + } + } + else { + collect(to_root_atom(a)->p()); + } + } + + void collect(clause const & c) { + unsigned sz = c.size(); + for (unsigned i = 0; i < sz; i++) + collect(c[i]); + } + + void collect(clause_vector const & cs) { + unsigned sz = cs.size(); + for (unsigned i = 0; i < sz; i++) + collect(*(cs[i])); + } + + + struct univariate_reorder_lt { + vos_var_info_collector::imp const *m_info; + univariate_reorder_lt(vos_var_info_collector::imp const *info):m_info(info) {} + bool operator()(var x, var y) const { + if (m_info->m_num_uni[x] != m_info->m_num_uni[y]) + return m_info->m_num_uni[x] > m_info->m_num_uni[y]; + return x < y; + } + }; + + struct feature_reorder_lt { + vos_var_info_collector::imp const *m_info; + feature_reorder_lt(vos_var_info_collector::imp const * info): m_info(info){} + bool operator()(var x, var y) const { + if (m_info->m_max_degree[x] != m_info->m_max_degree[y]) + return m_info->m_max_degree[x] > m_info->m_max_degree[y]; + if (m_info->m_max_terms_tdegree[x] != m_info->m_max_terms_tdegree[y]) + return m_info->m_max_terms_tdegree[x] > m_info->m_max_terms_tdegree[y]; + if (!m_info->pm.m().eq(m_info->m_coeffs[x], m_info->m_coeffs[y])) { + return m_info->pm.m().lt(m_info->m_coeffs[x], m_info->m_coeffs[y]); + } + return x < y; + } + }; + struct brown_reorder_lt { + vos_var_info_collector::imp const *m_info; + brown_reorder_lt(vos_var_info_collector::imp const *info):m_info(info) {} + bool operator()(var x, var y) const { + // if (a.max_degree != b.max_degree) + // return a.max_degree > b.max_degree; + // if (a.max_terms_tdegree != b.max_terms_tdegree) + // return a.max_terms_tdegree > b.max_terms_tdegree; + // return a.num_terms > b.num_terms; + if (m_info->m_max_degree[x] != m_info->m_max_degree[y]) + return m_info->m_max_degree[x] > m_info->m_max_degree[y]; + if (m_info->m_max_terms_tdegree[x] != m_info->m_max_terms_tdegree[y]) + return m_info->m_max_terms_tdegree[x] > m_info->m_max_terms_tdegree[y]; + if (m_info->m_num_terms[x] != m_info->m_num_terms[y]) + return m_info->m_num_terms[x] > m_info->m_num_terms[y]; + return x < y; + } + }; + struct triangular_reorder_lt { + const vos_var_info_collector::imp *m_info; + triangular_reorder_lt(vos_var_info_collector::imp const *info):m_info(info) {} + bool operator()(var x, var y) const { + // if (a.max_degree != b.max_degree) + // return a.max_degree > b.max_degree; + // if (a.max_lc_degree != b.max_lc_degree) + // return a.max_lc_degree > b.max_lc_degree; + // return a.sum_poly_degree > b.sum_poly_degree; + if (m_info->m_max_degree[x] != m_info->m_max_degree[y]) + return m_info->m_max_degree[x] > m_info->m_max_degree[y]; + if (m_info->m_max_lc_degree[x] != m_info->m_max_lc_degree[y]) + return m_info->m_max_lc_degree[x] > m_info->m_max_lc_degree[y]; + if (m_info->m_sum_poly_degree[x] != m_info->m_sum_poly_degree[y]) + return m_info->m_sum_poly_degree[x] > m_info->m_sum_poly_degree[y]; + return x < y; + } + }; + struct onlypoly_reorder_lt { + const vos_var_info_collector::imp *m_info; + onlypoly_reorder_lt(vos_var_info_collector::imp const *info):m_info(info) {} + bool operator()(var x, var y) const { + // high degree first + if (m_info->m_max_degree[x] != m_info->m_max_degree[y]) + return m_info->m_max_degree[x] > m_info->m_max_degree[y]; + // + if (m_info->m_sum_poly_degree[x] != m_info->m_sum_poly_degree[y]) + return m_info->m_sum_poly_degree[x] > m_info->m_sum_poly_degree[y]; + // more constrained first + if (m_info->m_num_polynomials[x] != m_info->m_num_polynomials[y]) + return m_info->m_num_polynomials[x] > m_info->m_num_polynomials[y]; + return x < y; + } + }; + bool check_invariant() const {return true;} // what is the invariant + void operator()(var_vector &perm) { + var_vector new_order; + for (var x = 0; x < num_vars; x++) { + new_order.push_back(x); + } + if (m_vos_type == BROWN) { + std::sort(new_order.begin(), new_order.end(), brown_reorder_lt(this)); + } + else if (m_vos_type == TRIANGULAR) { + std::sort(new_order.begin(), new_order.end(), triangular_reorder_lt(this)); + } + else if (m_vos_type == ONLYPOLY) { + std::sort(new_order.begin(), new_order.end(), onlypoly_reorder_lt(this)); + } + + else if(m_vos_type == UNIVARIATE){ + std::sort(new_order.begin(), new_order.end(), univariate_reorder_lt(this)); + } + else if(m_vos_type == FEATURE){ + std::sort(new_order.begin(), new_order.end(), feature_reorder_lt(this)); + } + + else { + UNREACHABLE(); + } + TRACE("reorder", + tout << "new order: "; + for (unsigned i = 0; i < num_vars; i++) + tout << new_order[i] << " "; + tout << "\n"; + ); + perm.resize(num_vars, 0); + for (var x = 0; x < num_vars; x++) { + perm[new_order[x]] = x; + } + + SASSERT(check_invariant()); + } + // std::ostream& display(std::ostream & out, display_var_proc const & proc) { + // unsigned sz = m_num_occs.size(); + // for (unsigned i = 0; i < sz; i++) { + // proc(out, i); out << " -> " << m_max_degree[i] << " : " << m_num_occs[i] << "\n"; + // } + // return out; + // } + + // std::ostream& display(std::ostream & out, display_var_proc const & proc) { + // for (unsigned i = 0; i < num_vars; ++i) { + // proc(out, i); out << " -> " << m_max_degree[i] << " : " << m_sum_poly_degree[i] << "\n"; + // } + // return out; + // } + }; + vos_var_info_collector::vos_var_info_collector(pmanager & _pm, atom_vector const & _atoms, unsigned _num_vars, unsigned _vos_type) { + m_imp = alloc(imp, _pm, _atoms, _num_vars, _vos_type); + } + vos_var_info_collector::~vos_var_info_collector() { + dealloc(m_imp); + } + void vos_var_info_collector::collect(clause_vector const & cs) { + m_imp->collect(cs); + } + void vos_var_info_collector::operator()(var_vector &perm) { + m_imp->operator()(perm); + } +} diff --git a/src/nlsat/nlsat_variable_ordering_strategy.h b/src/nlsat/nlsat_variable_ordering_strategy.h new file mode 100644 index 000000000..b29bece27 --- /dev/null +++ b/src/nlsat/nlsat_variable_ordering_strategy.h @@ -0,0 +1,44 @@ +/*++ +Copyright (c) 2024 Microsoft Corporation + +Module Name: + + nlsat_simple_checker.cpp + +Abstract: + + +Author: + + Mengyu Zhao (Linxi) and Shaowei Cai, ported from https://github.com/hybridSMT/hybridSMT.git + +Revision History: + +--*/ + +#pragma once +#include "nlsat/nlsat_clause.h" + + +#include "math/polynomial/algebraic_numbers.h" +#include "math/polynomial/polynomial.h" + + +namespace nlsat { + + typedef polynomial::manager::scoped_numeral scoped_numeral; + typedef polynomial::manager::numeral_vector numeral_vector; + + + enum Variable_Ordering_Strategy_Type {NONE = 0, BROWN, TRIANGULAR, ONLYPOLY, UNIVARIATE, FEATURE, ROOT}; + + class vos_var_info_collector { + struct imp; + imp * m_imp; + public: + vos_var_info_collector(pmanager & _pm, atom_vector const & atoms, unsigned _num_vars, unsigned _vos_type); + ~vos_var_info_collector(); + void operator()(var_vector &perm); + void collect(clause_vector const & cs); + }; +} \ No newline at end of file diff --git a/src/nlsat/tactic/nlsat_tactic.cpp b/src/nlsat/tactic/nlsat_tactic.cpp index 9426de78e..11c80de2a 100644 --- a/src/nlsat/tactic/nlsat_tactic.cpp +++ b/src/nlsat/tactic/nlsat_tactic.cpp @@ -262,6 +262,9 @@ public: void reset_statistics() override { m_stats.reset(); } + + void user_propagate_initialize_value(expr* var, expr* value) override { } + }; tactic * mk_nlsat_tactic(ast_manager & m, params_ref const & p) { diff --git a/src/opt/maxcore.cpp b/src/opt/maxcore.cpp index d29da86f7..84906cbaa 100644 --- a/src/opt/maxcore.cpp +++ b/src/opt/maxcore.cpp @@ -777,7 +777,7 @@ public: ptr_vector es; unsigned k = 0; rational weight; - bound_info() {} + bound_info() = default; bound_info(ptr_vector const& es, unsigned k, rational const& weight): es(es), k(k), weight(weight) {} bound_info(expr_ref_vector const& es, unsigned k, rational const& weight): diff --git a/src/opt/opt_context.cpp b/src/opt/opt_context.cpp index 865525024..81a2b80b5 100644 --- a/src/opt/opt_context.cpp +++ b/src/opt/opt_context.cpp @@ -53,13 +53,15 @@ namespace opt { void context::scoped_state::push() { m_asms_lim.push_back(m_asms.size()); m_hard_lim.push_back(m_hard.size()); + m_values_lim.push_back(m_values.size()); m_objectives_lim.push_back(m_objectives.size()); m_objectives_term_trail_lim.push_back(m_objectives_term_trail.size()); } void context::scoped_state::pop() { - m_hard.resize(m_hard_lim.back()); - m_asms.resize(m_asms_lim.back()); + m_hard.shrink(m_hard_lim.back()); + m_asms.shrink(m_asms_lim.back()); + m_values.shrink(m_values_lim.back()); unsigned k = m_objectives_term_trail_lim.back(); while (m_objectives_term_trail.size() > k) { unsigned idx = m_objectives_term_trail.back(); @@ -79,6 +81,7 @@ namespace opt { m_objectives_lim.pop_back(); m_hard_lim.pop_back(); m_asms_lim.pop_back(); + m_values_lim.pop_back(); } void context::scoped_state::add(expr* hard) { @@ -306,13 +309,12 @@ namespace opt { if (contains_quantifiers()) { warning_msg("optimization with quantified constraints is not supported"); } -#if 0 - if (is_qsat_opt()) { - return run_qsat_opt(); - } -#endif solver& s = get_solver(); s.assert_expr(m_hard_constraints); + if (m_model_converter) + m_model_converter->convert_initialize_value(m_scoped_state.m_values); + for (auto & [var, value] : m_scoped_state.m_values) + s.user_propagate_initialize_value(var, value); opt_params optp(m_params); symbol pri = optp.priority(); @@ -399,9 +401,24 @@ namespace opt { void context::set_model(model_ref& m) { m_model = m; opt_params optp(m_params); - if (optp.dump_models() && m) { + symbol prefix = optp.solution_prefix(); + bool model2console = optp.dump_models(); + bool model2file = prefix != symbol::null && prefix != symbol(""); + + if ((model2console || model2file) && m) { model_ref md = m->copy(); fix_model(md); + if (model2file) { + std::ostringstream buffer; + buffer << prefix << (m_model_counter++) << ".smt2"; + std::ofstream out(buffer.str()); + if (out) { + out << *md; + out.close(); + } + } + if (model2console) + std::cout << *md; } if (m_on_model_eh && m) { model_ref md = m->copy(); @@ -697,6 +714,11 @@ namespace opt { } } + void context::initialize_value(expr* var, expr* value) { + m_scoped_state.m_values.push_back({expr_ref(var, m), expr_ref(value, m)}); + } + + /** * Set the solver to the SAT core. * It requres: @@ -1161,20 +1183,6 @@ namespace opt { void context::model_updated(model* md) { model_ref mdl = md; set_model(mdl); -#if 0 - opt_params optp(m_params); - symbol prefix = optp.solution_prefix(); - if (prefix == symbol::null || prefix == symbol("")) return; - model_ref mdl = md->copy(); - fix_model(mdl); - std::ostringstream buffer; - buffer << prefix << (m_model_counter++) << ".smt2"; - std::ofstream out(buffer.str()); - if (out) { - out << *mdl; - out.close(); - } -#endif } rational context::adjust(unsigned id, rational const& v) { diff --git a/src/opt/opt_context.h b/src/opt/opt_context.h index 4e791531e..991fe16e6 100644 --- a/src/opt/opt_context.h +++ b/src/opt/opt_context.h @@ -140,12 +140,14 @@ namespace opt { unsigned_vector m_objectives_lim; unsigned_vector m_objectives_term_trail; unsigned_vector m_objectives_term_trail_lim; + unsigned_vector m_values_lim; map_id m_indices; public: expr_ref_vector m_hard; expr_ref_vector m_asms; vector m_objectives; + vector> m_values; scoped_state(ast_manager& m): m(m), @@ -275,6 +277,8 @@ namespace opt { void add_offset(unsigned id, rational const& o) override; + void initialize_value(expr* var, expr* value) override; + void register_on_model(on_model_t& ctx, std::function& on_model) { m_on_model_ctx = ctx; m_on_model_eh = on_model; diff --git a/src/opt/opt_cores.cpp b/src/opt/opt_cores.cpp index 124df63d7..44376e2f5 100644 --- a/src/opt/opt_cores.cpp +++ b/src/opt/opt_cores.cpp @@ -256,12 +256,11 @@ namespace opt { void cores::rotate_cores() { expr_ref_vector soft(m); soft.append(ctx.soft()); - unsigned num_sat = 0, num_unsat = 0, num_undef = 0; + unsigned num_sat = 0, num_undef = 0; lbool is_sat = l_false; while (m.inc() && m_cores.size() < m_max_num_cores) { switch (is_sat) { case l_false: { - ++num_unsat; auto core = unsat_core(); add_core(core); if (core.empty()) diff --git a/src/opt/opt_lns.cpp b/src/opt/opt_lns.cpp index ce76393f6..3a5195658 100644 --- a/src/opt/opt_lns.cpp +++ b/src/opt/opt_lns.cpp @@ -174,7 +174,6 @@ namespace opt { void lns::relax_cores() { if (!m_cores.empty() && m_cores_are_valid) { std::sort(m_cores.begin(), m_cores.end(), [&](expr_ref_vector const& a, expr_ref_vector const& b) { return a.size() < b.size(); }); - unsigned num_disjoint = 0; vector new_cores; for (auto const& c : m_cores) { bool in_core = false; @@ -185,7 +184,6 @@ namespace opt { for (auto* e : c) m_in_core.mark(e); new_cores.push_back(c); - ++num_disjoint; } IF_VERBOSE(2, verbose_stream() << "num cores: " << m_cores.size() << " new cores: " << new_cores.size() << "\n"); ctx.relax_cores(new_cores); diff --git a/src/opt/opt_parse.cpp b/src/opt/opt_parse.cpp index 29e8a604c..159246281 100644 --- a/src/opt/opt_parse.cpp +++ b/src/opt/opt_parse.cpp @@ -69,7 +69,7 @@ public: bool opt_stream_buffer::parse_token(char const* token) { skip_whitespace(); char const* t = token; - while (ch() == *t) { + while (*t && ch() && ch() == *t) { next(); ++t; } diff --git a/src/opt/opt_solver.cpp b/src/opt/opt_solver.cpp index aff1301e0..c05949439 100644 --- a/src/opt/opt_solver.cpp +++ b/src/opt/opt_solver.cpp @@ -58,9 +58,6 @@ namespace opt { } unsigned opt_solver::m_dump_count = 0; - - opt_solver::~opt_solver() { - } void opt_solver::updt_params(params_ref const & _p) { opt_params p(_p); diff --git a/src/opt/opt_solver.h b/src/opt/opt_solver.h index 2682fca09..e614a54fc 100644 --- a/src/opt/opt_solver.h +++ b/src/opt/opt_solver.h @@ -85,7 +85,6 @@ namespace opt { bool m_was_unknown; public: opt_solver(ast_manager & m, params_ref const & p, generic_model_converter& fm); - ~opt_solver() override; solver* translate(ast_manager& m, params_ref const& p) override; void updt_params(params_ref const& p) override; @@ -116,6 +115,7 @@ namespace opt { phase* get_phase() override { return m_context.get_phase(); } void set_phase(phase* p) override { m_context.set_phase(p); } void move_to_front(expr* e) override { m_context.move_to_front(e); } + void user_propagate_initialize_value(expr* var, expr* value) override { m_context.user_propagate_initialize_value(var, value); } void set_logic(symbol const& logic); diff --git a/src/opt/pb_sls.cpp b/src/opt/pb_sls.cpp index 82802819d..e7cdf9476 100644 --- a/src/opt/pb_sls.cpp +++ b/src/opt/pb_sls.cpp @@ -123,9 +123,6 @@ namespace smt { one = mpz(1); } - ~imp() { - } - void reset() { init_max_flips(); m_non_greedy_percent = 30; diff --git a/src/params/solver_params.pyg b/src/params/solver_params.pyg index 0912b4c7f..20e38b471 100644 --- a/src/params/solver_params.pyg +++ b/src/params/solver_params.pyg @@ -8,6 +8,7 @@ def_module_params('solver', ('lemmas2console', BOOL, False, 'print lemmas during search'), ('instantiations2console', BOOL, False, 'print quantifier instantiations to the console'), ('axioms2files', BOOL, False, 'print negated theory axioms to separate files during search'), + ('slice', BOOL, False, 'use slice solver that filters assertions to use symbols occuring in @query formulas'), ('proof.log', SYMBOL, '', 'log clause proof trail into a file'), ('proof.check', BOOL, True, 'check proof logs'), ('proof.check_rup', BOOL, True, 'check proof RUP inference in proof logs'), diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index 98323816a..afa361538 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -116,6 +116,7 @@ namespace smt2 { symbol m_match; symbol m_case; symbol m_underscore; + contains_vars m_has_free_vars; typedef std::pair named_expr; named_expr m_last_named_expr; @@ -942,7 +943,6 @@ namespace smt2 { } for (unsigned i = 0; i < sz; i++) { pdatatype_decl * d = new_dt_decls[i]; - symbol duplicated; check_duplicate(d, line, pos); if (!is_smt2_6) { // datatypes are inserted up front in SMT2.6 mode, so no need to re-insert them. @@ -1032,7 +1032,7 @@ namespace smt2 { void name_expr(expr * n, symbol const & s) { TRACE("name_expr", tout << "naming: " << s << " ->\n" << mk_pp(n, m()) << "\n";); - if (!is_ground(n) && has_free_vars(n)) + if (!is_ground(n) && m_has_free_vars(n)) throw parser_exception("invalid named expression, expression contains free variables"); m_ctx.insert(s, 0, nullptr, n); m_last_named_expr.first = s; diff --git a/src/parsers/util/simple_parser.cpp b/src/parsers/util/simple_parser.cpp index 6c3303e5c..c039fd9a1 100644 --- a/src/parsers/util/simple_parser.cpp +++ b/src/parsers/util/simple_parser.cpp @@ -28,9 +28,6 @@ simple_parser::simple_parser(ast_manager & m): m_exprs(m) { } -simple_parser::~simple_parser() { -} - void simple_parser::add_builtin_op(symbol const & s, family_id fid, decl_kind kind) { SASSERT(!m_builtin.contains(s)); SASSERT(!m_vars.contains(s)); diff --git a/src/parsers/util/simple_parser.h b/src/parsers/util/simple_parser.h index b40a0d983..c3cc0712e 100644 --- a/src/parsers/util/simple_parser.h +++ b/src/parsers/util/simple_parser.h @@ -45,7 +45,7 @@ protected: expr * parse_expr(scanner & s); public: simple_parser(ast_manager & m); - virtual ~simple_parser(); + virtual ~simple_parser() = default; void add_builtin_op(symbol const & s, family_id fid, decl_kind kind); void add_builtin_op(char const * str, family_id fid, decl_kind kind); void add_var(symbol const & s, var * v); diff --git a/src/qe/mbp/mbp_arith.cpp b/src/qe/mbp/mbp_arith.cpp index 255c4f814..8bbf3a002 100644 --- a/src/qe/mbp/mbp_arith.cpp +++ b/src/qe/mbp/mbp_arith.cpp @@ -43,8 +43,6 @@ namespace mbp { imp(ast_manager& m) : m(m), a(m) {} - ~imp() {} - void insert_mul(expr* x, rational const& v, obj_map& ts) { rational w; if (ts.find(x, w)) @@ -306,7 +304,7 @@ namespace mbp { return rational(b.is_pos() ? -1 : 1); } - bool operator()(model& model, app* v, app_ref_vector& vars, expr_ref_vector& lits) { + bool project1(model& model, app* v, app_ref_vector& vars, expr_ref_vector& lits) { app_ref_vector vs(m); vs.push_back(v); vector defs; @@ -712,8 +710,8 @@ namespace mbp { dealloc(m_imp); } - bool arith_project_plugin::operator()(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) { - return (*m_imp)(model, var, vars, lits); + bool arith_project_plugin::project1(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) { + return m_imp->project1(model, var, vars, lits); } bool arith_project_plugin::operator()(model& model, app_ref_vector& vars, expr_ref_vector& lits) { @@ -745,6 +743,6 @@ namespace mbp { ast_manager& m = lits.get_manager(); arith_project_plugin ap(m); app_ref_vector vars(m); - return ap(model, var, vars, lits); + return ap.project1(model, var, vars, lits); } } diff --git a/src/qe/mbp/mbp_arith.h b/src/qe/mbp/mbp_arith.h index ca4cccb74..666ffffc4 100644 --- a/src/qe/mbp/mbp_arith.h +++ b/src/qe/mbp/mbp_arith.h @@ -26,7 +26,7 @@ namespace mbp { arith_project_plugin(ast_manager& m); ~arith_project_plugin() override; - bool operator()(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) override; + bool project1(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) override; bool solve(model& model, app_ref_vector& vars, expr_ref_vector& lits) override { return false; } family_id get_family_id() override; bool operator()(model& model, app_ref_vector& vars, expr_ref_vector& lits) override; diff --git a/src/qe/mbp/mbp_arrays.cpp b/src/qe/mbp/mbp_arrays.cpp index bf3ad08ed..6e036a714 100644 --- a/src/qe/mbp/mbp_arrays.cpp +++ b/src/qe/mbp/mbp_arrays.cpp @@ -1058,7 +1058,6 @@ namespace mbp { scoped_ptr m_var; imp(ast_manager& m): m(m), a(m), m_stores(m) {} - ~imp() {} bool solve(model& model, app_ref_vector& vars, expr_ref_vector& lits) { return false; @@ -1445,7 +1444,7 @@ namespace mbp { dealloc(m_imp); } - bool array_project_plugin::operator()(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) { + bool array_project_plugin::project1(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) { ast_manager& m = vars.get_manager(); app_ref_vector vvars(m, 1, &var); expr_ref fml = mk_and(lits); diff --git a/src/qe/mbp/mbp_arrays.h b/src/qe/mbp/mbp_arrays.h index 7dd904108..ed06ba78b 100644 --- a/src/qe/mbp/mbp_arrays.h +++ b/src/qe/mbp/mbp_arrays.h @@ -31,7 +31,7 @@ namespace mbp { public: array_project_plugin(ast_manager& m); ~array_project_plugin() override; - bool operator()(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) override; + bool project1(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) override; bool solve(model& model, app_ref_vector& vars, expr_ref_vector& lits) override; void operator()(model& model, app_ref_vector& vars, expr_ref& fml, app_ref_vector& aux_vars, bool reduce_all_selects); family_id get_family_id() override; diff --git a/src/qe/mbp/mbp_arrays_tg.cpp b/src/qe/mbp/mbp_arrays_tg.cpp index c3d91ae64..da1bb1837 100644 --- a/src/qe/mbp/mbp_arrays_tg.cpp +++ b/src/qe/mbp/mbp_arrays_tg.cpp @@ -116,7 +116,7 @@ struct mbp_array_tg::impl { bool is_rd_wr(expr* t, expr*& wr_ind, expr*& rd_ind, expr*& b, expr*& v) { if (!is_rd_wr(t)) return false; - expr* a; + expr* a = nullptr; VERIFY(m_array_util.is_select1(t, a, rd_ind)); VERIFY(m_array_util.is_store1(a, b, wr_ind, v)); return true; @@ -185,7 +185,7 @@ struct mbp_array_tg::impl { // or &&_{i \in indices} j \neq i && // !(select(y, j) = elem) void elimwreq(peq p, bool is_neg) { - expr* a, *j, *elem; + expr* a = nullptr, *j = nullptr, *elem = nullptr; VERIFY(is_arr_write(p.lhs(), a, j, elem)); TRACE("mbp_tg", tout << "applying elimwreq on " << expr_ref(p.mk_peq(), m) << " is neg: " << is_neg;); @@ -279,7 +279,7 @@ struct mbp_array_tg::impl { // rewrite select(store(a, i, k), j) into either select(a, j) or k void elimrdwr(expr *term) { TRACE("mbp_tg", tout << "applying elimrdwr on " << expr_ref(term, m);); - expr* wr_ind, *rd_ind, *b, *v; + expr* wr_ind = nullptr, *rd_ind = nullptr, *b = nullptr, *v = nullptr; VERIFY(is_rd_wr(term, wr_ind, rd_ind, b, v)); if (m_mdl.are_equal(wr_ind, rd_ind)) m_tg.add_eq(wr_ind, rd_ind); diff --git a/src/qe/mbp/mbp_basic_tg.cpp b/src/qe/mbp/mbp_basic_tg.cpp index ce5e99eb1..693624871 100644 --- a/src/qe/mbp/mbp_basic_tg.cpp +++ b/src/qe/mbp/mbp_basic_tg.cpp @@ -101,7 +101,7 @@ struct mbp_basic_tg::impl { bool is_or = m.is_or(term); app *c = to_app(term); bool t = is_or ? any_of(*c, is_true) : all_of(*c, is_true); - bool f = is_or ? all_of(*c, is_false) : all_of(*c, is_false); + bool f = is_or ? all_of(*c, is_false) : any_of(*c, is_false); if (t || f) { mark_seen(term); progress = true; diff --git a/src/qe/mbp/mbp_datatypes.cpp b/src/qe/mbp/mbp_datatypes.cpp index 32e2b9f27..5a88016db 100644 --- a/src/qe/mbp/mbp_datatypes.cpp +++ b/src/qe/mbp/mbp_datatypes.cpp @@ -40,7 +40,7 @@ namespace mbp { return lift_foreign(vars, lits); } - bool operator()(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) { + bool project1(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) { expr_ref val = model(var); SASSERT(is_app(val)); TRACE("qe", tout << mk_pp(var, m) << " := " << val << "\n";); @@ -292,8 +292,8 @@ namespace mbp { dealloc(m_imp); } - bool datatype_project_plugin::operator()(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) { - return (*m_imp)(model, var, vars, lits); + bool datatype_project_plugin::project1(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) { + return m_imp->project1(model, var, vars, lits); } bool datatype_project_plugin::solve(model& model, app_ref_vector& vars, expr_ref_vector& lits) { diff --git a/src/qe/mbp/mbp_datatypes.h b/src/qe/mbp/mbp_datatypes.h index f30aaaa9f..28f93089d 100644 --- a/src/qe/mbp/mbp_datatypes.h +++ b/src/qe/mbp/mbp_datatypes.h @@ -31,7 +31,7 @@ namespace mbp { public: datatype_project_plugin(ast_manager& m); ~datatype_project_plugin() override; - bool operator()(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) override; + bool project1(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) override; bool solve(model& model, app_ref_vector& vars, expr_ref_vector& lits) override; family_id get_family_id() override; bool project(model& model, app_ref_vector& vars, expr_ref_vector& lits, vector& defs) override; diff --git a/src/qe/mbp/mbp_plugin.h b/src/qe/mbp/mbp_plugin.h index 4f73b92e6..c270489e8 100644 --- a/src/qe/mbp/mbp_plugin.h +++ b/src/qe/mbp/mbp_plugin.h @@ -60,7 +60,7 @@ namespace mbp { public: project_plugin(ast_manager& m) :m(m), m_cache(m), m_args(m), m_pure_eqs(m) {} virtual ~project_plugin() = default; - virtual bool operator()(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) { return false; } + virtual bool project1(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) { return false; } /** \brief partial solver. */ diff --git a/src/qe/mbp/mbp_term_graph.cpp b/src/qe/mbp/mbp_term_graph.cpp index e5e5309f3..6ecaa5de2 100644 --- a/src/qe/mbp/mbp_term_graph.cpp +++ b/src/qe/mbp/mbp_term_graph.cpp @@ -187,8 +187,6 @@ class term { m_is_peq = is_partial_eq(to_app(m_expr)); } - ~term() {} - class parents { term const &t; diff --git a/src/qe/nlqsat.cpp b/src/qe/nlqsat.cpp index 8a6f910bc..9fd1d4e0e 100644 --- a/src/qe/nlqsat.cpp +++ b/src/qe/nlqsat.cpp @@ -558,7 +558,6 @@ namespace qe { vector
m_divs; public: div_rewriter_cfg(nlqsat& s): m(s.m), a(s.m), m_zero(a.mk_real(0), m) {} - ~div_rewriter_cfg() {} br_status reduce_app(func_decl* f, unsigned sz, expr* const* args, expr_ref& result, proof_ref& pr) { rational r1, r(1); if (a.is_div(f) && sz == 2 && a.is_numeral(args[0], r1) && a.is_numeral(args[1], r) && !r.is_zero()) { @@ -849,6 +848,8 @@ namespace qe { void collect_param_descrs(param_descrs & r) override { } + void user_propagate_initialize_value(expr* var, expr* value) override { } + void operator()(/* in */ goal_ref const & in, /* out */ goal_ref_buffer & result) override { diff --git a/src/qe/qe.h b/src/qe/qe.h index 55729d0b5..05251a2e0 100644 --- a/src/qe/qe.h +++ b/src/qe/qe.h @@ -123,7 +123,6 @@ namespace qe { iterator(conj_enum& c, bool first) : m_super(&c), m_index(first?0:c.m_conjs.size()) {} expr* operator*() { return m_super->m_conjs[m_index].get(); } iterator& operator++() { m_index++; return *this; } - bool operator==(iterator const& it) const { return m_index == it.m_index; } bool operator!=(iterator const& it) const { return m_index != it.m_index; } }; diff --git a/src/qe/qe_mbp.cpp b/src/qe/qe_mbp.cpp index 97f12238d..96ae5e85a 100644 --- a/src/qe/qe_mbp.cpp +++ b/src/qe/qe_mbp.cpp @@ -45,84 +45,89 @@ using namespace qe; namespace { // rewrite select(store(a, i, k), j) into k if m \models i = j and select(a, j) if m \models i != j struct rd_over_wr_rewriter : public default_rewriter_cfg { - ast_manager &m; - array_util m_arr; - model_evaluator m_eval; - expr_ref_vector m_sc; - - rd_over_wr_rewriter(ast_manager& man, model& mdl): m(man), m_arr(m), m_eval(mdl), m_sc(m) { - m_eval.set_model_completion(false); - } - - br_status reduce_app(func_decl *f, unsigned num, expr *const *args, - expr_ref &result, proof_ref &result_pr) { - if (m_arr.is_select(f) && m_arr.is_store(args[0])) { - expr_ref ind1(m), ind2(m); - ind1 = m_eval(args[1]); - ind2 = m_eval(to_app(args[0])->get_arg(1)); - if (ind1 == ind2) { - result = to_app(args[0])->get_arg(2); - m_sc.push_back(m.mk_eq(args[1], to_app(args[0])->get_arg(1))); - return BR_DONE; - } - m_sc.push_back(m.mk_not(m.mk_eq(args[1], to_app(args[0])->get_arg(1)))); - expr_ref_vector new_args(m); - new_args.push_back(to_app(args[0])->get_arg(0)); - new_args.push_back(args[1]); - result = m_arr.mk_select(new_args); - return BR_REWRITE1; + ast_manager &m; + array_util m_arr; + model_evaluator m_eval; + expr_ref_vector m_sc; + + rd_over_wr_rewriter(ast_manager& man, model& mdl): m(man), m_arr(m), m_eval(mdl), m_sc(m) { + m_eval.set_model_completion(false); + } + + br_status reduce_app(func_decl *f, unsigned num, expr *const *args, + expr_ref &result, proof_ref &result_pr) { + if (m_arr.is_select(f) && m_arr.is_store(args[0])) { + expr_ref ind1(m), ind2(m); + ind1 = m_eval(args[1]); + ind2 = m_eval(to_app(args[0])->get_arg(1)); + if (ind1 == ind2) { + result = to_app(args[0])->get_arg(2); + m_sc.push_back(m.mk_eq(args[1], to_app(args[0])->get_arg(1))); + return BR_DONE; } - return BR_FAILED; + m_sc.push_back(m.mk_not(m.mk_eq(args[1], to_app(args[0])->get_arg(1)))); + expr_ref_vector new_args(m); + new_args.push_back(to_app(args[0])->get_arg(0)); + new_args.push_back(args[1]); + result = m_arr.mk_select(new_args); + return BR_REWRITE1; } + return BR_FAILED; + } }; // rewrite all occurrences of (as const arr c) to (as const arr v) where v = m_eval(c) struct app_const_arr_rewriter : public default_rewriter_cfg { - ast_manager &m; - array_util m_arr; - datatype_util m_dt_util; - model_evaluator m_eval; - expr_ref val; - - app_const_arr_rewriter(ast_manager& man, model& mdl): m(man), m_arr(m), m_dt_util(m), m_eval(mdl), val(m) { - m_eval.set_model_completion(false); + ast_manager &m; + array_util m_arr; + datatype_util m_dt_util; + model_evaluator m_eval; + expr_ref val; + + app_const_arr_rewriter(ast_manager& man, model& mdl): m(man), m_arr(m), m_dt_util(m), m_eval(mdl), val(m) { + m_eval.set_model_completion(false); + } + br_status reduce_app(func_decl *f, unsigned num, expr *const *args, + expr_ref &result, proof_ref &result_pr) { + if (m_arr.is_const(f) && !m.is_value(args[0])) { + val = m_eval(args[0]); + SASSERT(m.is_value(val)); + result = m_arr.mk_const_array(f->get_range(), val); + return BR_DONE; } - br_status reduce_app(func_decl *f, unsigned num, expr *const *args, - expr_ref &result, proof_ref &result_pr) { - if (m_arr.is_const(f) && !m.is_value(args[0])) { - val = m_eval(args[0]); - SASSERT(m.is_value(val)); - result = m_arr.mk_const_array(f->get_range(), val); - return BR_DONE; + if (m_dt_util.is_constructor(f)) { + // cons(head(x), tail(x)) --> x + ptr_vector const *accessors = + m_dt_util.get_constructor_accessors(f); + + SASSERT(num == accessors->size()); + // -- all accessors must have exactly one argument + if (any_of(*accessors, [&](const func_decl* acc) { return acc->get_arity() != 1; })) { + return BR_FAILED; } - if (m_dt_util.is_constructor(f)) { - // cons(head(x), tail(x)) --> x - ptr_vector const *accessors = - m_dt_util.get_constructor_accessors(f); - - SASSERT(num == accessors->size()); - // -- all accessors must have exactly one argument - if (any_of(*accessors, [&](const func_decl* acc) { return acc->get_arity() != 1; })) { - return BR_FAILED; + + if (num >= 1 && is_app(args[0]) && to_app(args[0])->get_decl() == accessors->get(0)) { + bool is_all = true; + expr* t = to_app(args[0])->get_arg(0); + for(unsigned i = 1; i < num && is_all; ++i) { + is_all &= (is_app(args[i]) && + to_app(args[i])->get_decl() == accessors->get(i) && + to_app(args[i])->get_arg(0) == t); } - - if (num >= 1 && is_app(args[0]) && to_app(args[0])->get_decl() == accessors->get(0)) { - bool is_all = true; - expr* t = to_app(args[0])->get_arg(0); - for(unsigned i = 1; i < num && is_all; ++i) { - is_all &= (is_app(args[i]) && - to_app(args[i])->get_decl() == accessors->get(i) && - to_app(args[i])->get_arg(0) == t); - } - if (is_all) { - result = t; - return BR_DONE; - } + if (is_all) { + result = t; + return BR_DONE; } } - return BR_FAILED; } + return BR_FAILED; + } }; } + +template class rewriter_tpl; +template class rewriter_tpl; + + void rewrite_as_const_arr(expr* in, model& mdl, expr_ref& out) { app_const_arr_rewriter cfg(out.m(), mdl); rewriter_tpl rw(out.m(), false, cfg); @@ -452,7 +457,7 @@ public: var = vars.back(); vars.pop_back(); mbp::project_plugin* p = get_plugin(var); - if (p && (*p)(model, var, vars, fmls)) { + if (p && p->project1(model, var, vars, fmls)) { progress = true; } else { @@ -675,6 +680,8 @@ public: vars.reset(); vars.append(other_vars); } + + }; mbproj::mbproj(ast_manager& m, params_ref const& p) { @@ -715,5 +722,4 @@ opt::inf_eps mbproj::maximize(expr_ref_vector const& fmls, model& mdl, app* t, e scoped_no_proof _sp(fmls.get_manager()); return m_impl->maximize(fmls, mdl, t, ge, gt); } -template class rewriter_tpl; -template class rewriter_tpl; + diff --git a/src/qe/qsat.cpp b/src/qe/qsat.cpp index dc0613c59..0ff054a89 100644 --- a/src/qe/qsat.cpp +++ b/src/qe/qsat.cpp @@ -1377,7 +1377,9 @@ namespace qe { tactic * translate(ast_manager & m) override { return alloc(qsat, m, m_params, m_mode); - } + } + + void user_propagate_initialize_value(expr* var, expr* value) override { } lbool maximize(expr_ref_vector const& fmls, app* t, model_ref& mdl, opt::inf_eps& value) { expr_ref_vector defs(m); diff --git a/src/sat/dimacs.h b/src/sat/dimacs.h index ca6aae07b..3ca8102ff 100644 --- a/src/sat/dimacs.h +++ b/src/sat/dimacs.h @@ -94,7 +94,6 @@ namespace dimacs { iterator(drat_parser& p, bool is_eof):p(p), m_eof(is_eof) { if (!m_eof) m_eof = !p.next(); } drat_record const& operator*() { return p.m_record; } iterator& operator++() { if (!p.next()) m_eof = true; return *this;} - bool operator==(iterator const& other) const { return m_eof == other.m_eof; } bool operator!=(iterator const& other) const { return m_eof != other.m_eof; } }; diff --git a/src/sat/sat_aig_cuts.cpp b/src/sat/sat_aig_cuts.cpp index 20f62cbdd..df736e4ba 100644 --- a/src/sat/sat_aig_cuts.cpp +++ b/src/sat/sat_aig_cuts.cpp @@ -534,7 +534,7 @@ namespace sat { } cut_val aig_cuts::eval(node const& n, cut_eval const& env) const { - uint64_t result; + uint64_t result = 0; switch (n.op()) { case var_op: UNREACHABLE(); diff --git a/src/sat/sat_clause.h b/src/sat/sat_clause.h index f1a44296e..0129febbf 100644 --- a/src/sat/sat_clause.h +++ b/src/sat/sat_clause.h @@ -188,7 +188,6 @@ namespace sat { iterator(clause_wrapper const& c, unsigned idx): m_idx(idx), m_cw(c) {} iterator& operator++() { ++m_idx; return *this; } literal operator*() { return m_cw[m_idx]; } - bool operator==(iterator const& other) const { SASSERT(&m_cw == &other.m_cw); return m_idx == other.m_idx; } bool operator!=(iterator const& other) const { SASSERT(&m_cw == &other.m_cw); return m_idx != other.m_idx; } }; iterator begin() const { return iterator(*this, 0); } diff --git a/src/sat/sat_clause_use_list.cpp b/src/sat/sat_clause_use_list.cpp index 7ca0aa2c6..347e49db9 100644 --- a/src/sat/sat_clause_use_list.cpp +++ b/src/sat/sat_clause_use_list.cpp @@ -25,13 +25,13 @@ namespace sat { unsigned sz = 0; for (clause* c : m_clauses) if (!c->was_removed()) - sz++; - SASSERT(sz == m_size); + sz++; + VERIFY(sz == m_size); unsigned redundant = 0; for (clause* c : m_clauses) if (c->is_learned()) redundant++; - SASSERT(redundant == m_num_redundant); + VERIFY(redundant == m_num_redundant); return true; } diff --git a/src/sat/sat_local_search.cpp b/src/sat/sat_local_search.cpp index 72f0fabd9..5cb983baa 100644 --- a/src/sat/sat_local_search.cpp +++ b/src/sat/sat_local_search.cpp @@ -353,9 +353,6 @@ namespace sat { DEBUG_CODE(verify_unsat_stack();); } - local_search::local_search() { - } - void local_search::reinit(solver& s, bool_vector const& phase) { import(s, true); for (unsigned i = phase.size(); i-- > 0; ) @@ -419,10 +416,6 @@ namespace sat { if (_init) init(); } - - local_search::~local_search() { - } - lbool local_search::check() { return check(0, nullptr, nullptr); diff --git a/src/sat/sat_local_search.h b/src/sat/sat_local_search.h index b62234522..e8959478e 100644 --- a/src/sat/sat_local_search.h +++ b/src/sat/sat_local_search.h @@ -227,10 +227,6 @@ namespace sat { unsigned num_vars() const { return m_vars.size() - 1; } // var index from 1 to num_vars public: - - local_search(); - - ~local_search() override; reslimit& rlimit() override { return m_limit; } diff --git a/src/sat/sat_lookahead.cpp b/src/sat/sat_lookahead.cpp index 2f3fc91b2..3fef08559 100644 --- a/src/sat/sat_lookahead.cpp +++ b/src/sat/sat_lookahead.cpp @@ -1392,7 +1392,6 @@ namespace sat { void lookahead::propagate_clauses_searching(literal l) { // clauses where l is negative unsigned sz = m_nary_count[(~l).index()]; - literal lit; SASSERT(m_search_mode == lookahead_mode::searching); for (nary* n : m_nary[(~l).index()]) { if (sz-- == 0) break; diff --git a/src/sat/sat_model_converter.cpp b/src/sat/sat_model_converter.cpp index ddb277e9b..fa5720ede 100644 --- a/src/sat/sat_model_converter.cpp +++ b/src/sat/sat_model_converter.cpp @@ -23,13 +23,6 @@ Revision History: namespace sat { - model_converter::model_converter(): m_exposed_lim(0), m_solver(nullptr) { - } - - model_converter::~model_converter() { - } - - model_converter& model_converter::operator=(model_converter const& other) { copy(other); return *this; diff --git a/src/sat/sat_model_converter.h b/src/sat/sat_model_converter.h index a331bef8e..170886aa6 100644 --- a/src/sat/sat_model_converter.h +++ b/src/sat/sat_model_converter.h @@ -58,7 +58,6 @@ namespace sat { m_stack(std::move(stack)) { m_counter = ++counter; } - ~elim_stack() { } void inc_ref() { ++m_refcount; } void dec_ref() { if (0 == --m_refcount) { dealloc(this); } } elim_stackv const& stack() const { return m_stack; } @@ -80,9 +79,9 @@ namespace sat { }; private: vector m_entries; // entries accumulated during SAT search - unsigned m_exposed_lim; // last entry that was exposed to model converter. + unsigned m_exposed_lim = 0; // last entry that was exposed to model converter. bool_vector m_mark; // literals that are used in asserted clauses. - solver const* m_solver; + solver const* m_solver = nullptr; elim_stackv m_elim_stack; void process_stack(model & m, literal_vector const& clause, elim_stackv const& stack) const; @@ -96,8 +95,6 @@ namespace sat { void add_elim_stack(entry & e); public: - model_converter(); - ~model_converter(); void set_solver(solver const* s) { m_solver = s; } void operator()(model & m) const; model_converter& operator=(model_converter const& other); diff --git a/src/sat/sat_mus.cpp b/src/sat/sat_mus.cpp index cbbf01b20..5b7542cb2 100644 --- a/src/sat/sat_mus.cpp +++ b/src/sat/sat_mus.cpp @@ -24,8 +24,6 @@ Notes: namespace sat { mus::mus(solver& s):s(s), m_is_active(false), m_max_num_restarts(UINT_MAX) {} - - mus::~mus() {} void mus::reset() { m_core.reset(); diff --git a/src/sat/sat_mus.h b/src/sat/sat_mus.h index 5f67f6acd..672e90185 100644 --- a/src/sat/sat_mus.h +++ b/src/sat/sat_mus.h @@ -30,7 +30,6 @@ namespace sat { public: mus(solver& s); - ~mus(); lbool operator()(); bool is_active() const { return m_is_active; } model const& get_model() const { return m_model; } diff --git a/src/sat/sat_solver.cpp b/src/sat/sat_solver.cpp index 0dcdee53c..ed312a76c 100644 --- a/src/sat/sat_solver.cpp +++ b/src/sat/sat_solver.cpp @@ -1012,7 +1012,7 @@ namespace sat { } bool solver::propagate_literal(literal l, bool update) { - literal l1, l2; + literal l1; bool keep; unsigned curr_level = lvl(l); @@ -4733,7 +4733,7 @@ namespace sat { num_lits += c.size(); } } - unsigned total_cls = num_cls + num_ter + num_bin; + unsigned total_cls = num_cls + num_ter + num_bin + num_ext; double mem = static_cast(memory::get_allocation_size())/static_cast(1024*1024); out << "(sat-status\n"; out << " :inconsistent " << (m_inconsistent ? "true" : "false") << "\n"; diff --git a/src/sat/sat_solver/inc_sat_solver.cpp b/src/sat/sat_solver/inc_sat_solver.cpp index 7de9fa458..9b77b6482 100644 --- a/src/sat/sat_solver/inc_sat_solver.cpp +++ b/src/sat/sat_solver/inc_sat_solver.cpp @@ -78,6 +78,7 @@ class inc_sat_solver : public solver { // this allows to access the internal state of the SAT solver and carry on partial results. bool m_internalized_converted; // have internalized formulas been converted back expr_ref_vector m_internalized_fmls; // formulas in internalized format + vector> m_var2value; typedef obj_map dep2asm_t; @@ -175,9 +176,23 @@ public: (m.is_not(e, e) && is_uninterp_const(e)); } + void initialize_values() { + if (m_mcs.back()) + m_mcs.back()->convert_initialize_value(m_var2value); + + for (auto & [var, value] : m_var2value) { + sat::bool_var b = m_map.to_bool_var(var); + if (b != sat::null_bool_var) + m_solver.set_phase(sat::literal(b, m.is_false(value))); + else if (get_euf()) + ensure_euf()->user_propagate_initialize_value(var, value); + } + } + lbool check_sat_core(unsigned sz, expr * const * assumptions) override { m_solver.pop_to_base_level(); m_core.reset(); + if (m_solver.inconsistent()) return l_false; expr_ref_vector _assumptions(m); obj_map asm2fml; @@ -202,6 +217,8 @@ public: r = internalize_assumptions(sz, _assumptions.data()); if (r != l_true) return r; + initialize_values(); + init_reason_unknown(); m_internalized_converted = false; bool reason_set = false; @@ -702,6 +719,10 @@ public: ensure_euf()->user_propagate_register_decide(r); } + void user_propagate_initialize_value(expr* var, expr* value) override { + m_var2value.push_back({expr_ref(var, m), expr_ref(value, m) }); + } + private: diff --git a/src/sat/sat_solver/sat_smt_solver.cpp b/src/sat/sat_solver/sat_smt_solver.cpp index ce5324aa8..e21b0996f 100644 --- a/src/sat/sat_solver/sat_smt_solver.cpp +++ b/src/sat/sat_solver/sat_smt_solver.cpp @@ -577,6 +577,11 @@ public: ensure_euf()->user_propagate_register_decide(r); } + void user_propagate_initialize_value(expr* var, expr* value) override { + ensure_euf()->user_propagate_initialize_value(var, value); + } + + private: void add_assumption(expr* a) { diff --git a/src/sat/smt/arith_axioms.cpp b/src/sat/smt/arith_axioms.cpp index 7270e7080..59529658b 100644 --- a/src/sat/smt/arith_axioms.cpp +++ b/src/sat/smt/arith_axioms.cpp @@ -206,8 +206,8 @@ namespace arith { } bool solver::check_bv_term(app* n) { - unsigned sz; - expr* _x, * _y; + unsigned sz = 0; + expr* _x = nullptr, * _y = nullptr; if (!ctx.is_relevant(expr2enode(n))) return true; expr_ref vx(m), vy(m),vn(m); @@ -324,8 +324,8 @@ namespace arith { void solver::mk_bv_axiom(app* n) { - unsigned sz; - expr* _x, * _y; + unsigned sz = 0; + expr* _x = nullptr, * _y = nullptr; VERIFY(a.is_band(n, sz, _x, _y) || a.is_shl(n, sz, _x, _y) || a.is_ashr(n, sz, _x, _y) || a.is_lshr(n, sz, _x, _y)); rational N = rational::power_of_two(sz); expr_ref x(a.mk_mod(_x, a.mk_int(N)), m); diff --git a/src/sat/smt/arith_internalize.cpp b/src/sat/smt/arith_internalize.cpp index a389d13b8..9c4e5c9be 100644 --- a/src/sat/smt/arith_internalize.cpp +++ b/src/sat/smt/arith_internalize.cpp @@ -51,6 +51,16 @@ namespace arith { } } + void solver::initialize_value(expr* var, expr* value) { + rational r; + if (!a.is_numeral(value, r)) { + IF_VERBOSE(5, verbose_stream() << "numeric constant expected in initialization " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); + return; + } + lp().move_lpvar_to_value(get_lpvar(mk_evar(var)), r); + } + + lpvar solver::get_one(bool is_int) { return add_const(1, is_int ? m_one_var : m_rone_var, is_int); } diff --git a/src/sat/smt/arith_solver.h b/src/sat/smt/arith_solver.h index 770e1cf5d..dd58d6651 100644 --- a/src/sat/smt/arith_solver.h +++ b/src/sat/smt/arith_solver.h @@ -424,19 +424,11 @@ namespace arith { * Facility to put a small box around integer variables used in branch and bounds. */ - struct bound_info { - rational m_offset; - unsigned m_range; - bound_info() {} - bound_info(rational const& o, unsigned r) :m_offset(o), m_range(r) {} - }; unsigned m_bounded_range_idx; // current size of bounded range. literal m_bounded_range_lit; // current bounded range literal expr_ref_vector m_bound_terms; // predicates used for bounds expr_ref m_bound_predicate; - obj_map m_predicate2term; - obj_map m_term2bound_info; bool m_model_is_initialized = false; unsigned small_lemma_size() const { return get_config().m_arith_small_lemma_size; } @@ -481,6 +473,8 @@ namespace arith { bool validate_conflict(); + + public: solver(euf::solver& ctx, theory_id id); ~solver() override; @@ -508,6 +502,7 @@ namespace arith { void internalize(expr* e) override; void eq_internalized(euf::enode* n) override; void apply_sort_cnstr(euf::enode* n, sort* s) override {} + void initialize_value(expr* var, expr* value) override; bool is_shared(theory_var v) const override; lbool get_phase(bool_var v) override; bool include_func_interp(func_decl* f) const override; diff --git a/src/sat/smt/array_internalize.cpp b/src/sat/smt/array_internalize.cpp index d5a1dd2c5..9e41be3bb 100644 --- a/src/sat/smt/array_internalize.cpp +++ b/src/sat/smt/array_internalize.cpp @@ -128,7 +128,7 @@ namespace array { internalize_lambda_eh(n); break; case OP_SET_SUBSET: { - expr* x, *y; + expr* x = nullptr, *y = nullptr; VERIFY(a.is_subset(n->get_expr(), x, y)); expr_ref diff(a.mk_setminus(x, y), m); expr_ref emp(a.mk_empty_set(x->get_sort()), m); diff --git a/src/sat/smt/array_solver.cpp b/src/sat/smt/array_solver.cpp index 7a8f31f1e..1343577d9 100644 --- a/src/sat/smt/array_solver.cpp +++ b/src/sat/smt/array_solver.cpp @@ -88,8 +88,6 @@ namespace array { m_constraint->initialize(m_constraint.get(), this); } - solver::~solver() {} - sat::check_result solver::check() { force_push(); // flet _is_redundant(m_is_redundant, true); diff --git a/src/sat/smt/array_solver.h b/src/sat/smt/array_solver.h index 8dc6e4e84..0a7c854fd 100644 --- a/src/sat/smt/array_solver.h +++ b/src/sat/smt/array_solver.h @@ -268,7 +268,6 @@ namespace array { void validate_extensionality(euf::enode* s, euf::enode* t) const; public: solver(euf::solver& ctx, theory_id id); - ~solver() override; bool is_external(bool_var v) override { return false; } void get_antecedents(literal l, sat::ext_justification_idx idx, literal_vector& r, bool probing) override {} void asserted(literal l) override {} diff --git a/src/sat/smt/euf_proof_checker.cpp b/src/sat/smt/euf_proof_checker.cpp index 098c3a753..4351f6581 100644 --- a/src/sat/smt/euf_proof_checker.cpp +++ b/src/sat/smt/euf_proof_checker.cpp @@ -296,9 +296,6 @@ namespace euf { add_plugin(alloc(bv::theory_checker, m)); } - theory_checker::~theory_checker() { - } - void theory_checker::add_plugin(theory_checker_plugin* p) { m_plugins.push_back(p); p->register_plugins(*this); diff --git a/src/sat/smt/euf_proof_checker.h b/src/sat/smt/euf_proof_checker.h index d84e4d19f..0da57ee9e 100644 --- a/src/sat/smt/euf_proof_checker.h +++ b/src/sat/smt/euf_proof_checker.h @@ -45,7 +45,6 @@ namespace euf { void add_plugin(theory_checker_plugin* p); public: theory_checker(ast_manager& m); - ~theory_checker(); void register_plugin(symbol const& rule, theory_checker_plugin*); bool check(expr* jst); expr_ref_vector clause(expr* jst); diff --git a/src/sat/smt/euf_solver.cpp b/src/sat/smt/euf_solver.cpp index b91051b39..fbb1025b7 100644 --- a/src/sat/smt/euf_solver.cpp +++ b/src/sat/smt/euf_solver.cpp @@ -194,6 +194,30 @@ namespace euf { m_reason_unknown.clear(); for (auto* s : m_solvers) s->init_search(); + + for (auto const& [var, value] : m_initial_values) { + if (m.is_bool(var)) { + auto lit = expr2literal(var); + if (lit == sat::null_literal) { + IF_VERBOSE(5, verbose_stream() << "no literal associated with " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); + continue; + } + if (m.is_true(value)) + s().set_phase(lit); + else if (m.is_false(value)) + s().set_phase(~lit); + else + IF_VERBOSE(5, verbose_stream() << "malformed value " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); + continue; + } + auto* th = m_id2solver.get(var->get_sort()->get_family_id(), nullptr); + if (!th) { + IF_VERBOSE(5, verbose_stream() << "no default initialization associated with " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); + continue; + } + th->initialize_value(var, value); + } + } bool solver::is_external(bool_var v) { @@ -1255,6 +1279,14 @@ namespace euf { add_solver(m_user_propagator); } + void solver::user_propagate_initialize_value(expr* var, expr* value) { + + m_initial_values.push_back({expr_ref(var, m), expr_ref(value, m)}); + push(push_back_vector(m_initial_values)); + + } + + bool solver::watches_fixed(enode* n) const { return m_user_propagator && m_user_propagator->has_fixed() && n->get_th_var(m_user_propagator->get_id()) != null_theory_var; } diff --git a/src/sat/smt/euf_solver.h b/src/sat/smt/euf_solver.h index 16d4e22ec..06ee45df0 100644 --- a/src/sat/smt/euf_solver.h +++ b/src/sat/smt/euf_solver.h @@ -179,6 +179,8 @@ namespace euf { euf::enode* mk_true(); euf::enode* mk_false(); + vector> m_initial_values; + // replay typedef std::tuple reinit_t; vector m_reinit; @@ -227,8 +229,6 @@ namespace euf { eq_proof_hint* mk_hint(symbol const& th, literal lit); - - void init_proof(); void on_clause(unsigned n, literal const* lits, sat::status st) override; void on_lemma(unsigned n, literal const* lits, sat::status st); @@ -557,6 +557,8 @@ namespace euf { m_user_propagator->add_expr(e); } + void user_propagate_initialize_value(expr* var, expr* value); + // solver factory ::solver* mk_solver() { return m_mk_solver(); } void set_mk_solver(std::function<::solver*(void)>& mk) { m_mk_solver = mk; } diff --git a/src/sat/smt/intblast_solver.cpp b/src/sat/smt/intblast_solver.cpp index f91113d59..d6dfe57d7 100644 --- a/src/sat/smt/intblast_solver.cpp +++ b/src/sat/smt/intblast_solver.cpp @@ -91,7 +91,7 @@ namespace intblast { void solver::eq_internalized(euf::enode* n) { expr* e = n->get_expr(); - expr* x, * y; + expr* x = nullptr, * y = nullptr; VERIFY(m.is_eq(n->get_expr(), x, y)); SASSERT(bv.is_bv(x)); if (!is_translated(e)) { @@ -482,7 +482,7 @@ namespace intblast { return r >= 0; if (is_bounded(e, N)) return true; - expr* x, * y; + expr* x = nullptr, * y = nullptr; if (a.is_mul(e, x, y)) return is_non_negative(bv_expr, x) && is_non_negative(bv_expr, y); if (a.is_add(e, x, y)) @@ -544,7 +544,7 @@ namespace intblast { */ expr* solver::amod(expr* bv_expr, expr* x, rational const& N) { rational v; - expr* r, *c, * t, * e; + expr* r = nullptr, *c = nullptr, * t = nullptr, * e = nullptr; if (m.is_ite(x, c, t, e)) r = m.mk_ite(c, amod(bv_expr, t, N), amod(bv_expr, e, N)); else if (a.is_idiv(x, t, e) && a.is_numeral(t, v) && 0 <= v && v < N && is_non_negative(bv_expr, e)) @@ -880,7 +880,7 @@ namespace intblast { r = umod(bv_expr, 0); SASSERT(bv.get_bv_size(e) >= bv.get_bv_size(bv_expr)); unsigned arg_sz = bv.get_bv_size(bv_expr); - unsigned sz = bv.get_bv_size(e); + //unsigned sz = bv.get_bv_size(e); // rational N = rational::power_of_two(sz); rational M = rational::power_of_two(arg_sz); expr* signbit = a.mk_ge(r, a.mk_int(M / 2)); diff --git a/src/sat/smt/intblast_solver.h b/src/sat/smt/intblast_solver.h index 34f876be6..ee8d6fb19 100644 --- a/src/sat/smt/intblast_solver.h +++ b/src/sat/smt/intblast_solver.h @@ -103,8 +103,6 @@ namespace intblast { public: solver(euf::solver& ctx); - - ~solver() override {} lbool check_axiom(sat::literal_vector const& lits); lbool check_core(sat::literal_vector const& lits, euf::enode_pair_vector const& eqs); diff --git a/src/sat/smt/pb_constraint.h b/src/sat/smt/pb_constraint.h index 26c5f8b08..4c6f69e07 100644 --- a/src/sat/smt/pb_constraint.h +++ b/src/sat/smt/pb_constraint.h @@ -125,7 +125,6 @@ namespace pb { iterator(constraint const& c, unsigned idx) : c(c), idx(idx) {} literal operator*() { return c.get_lit(idx); } iterator& operator++() { ++idx; return *this; } - bool operator==(iterator const& other) const { SASSERT(&c == &other.c); return idx == other.idx; } bool operator!=(iterator const& other) const { SASSERT(&c == &other.c); return idx != other.idx; } }; diff --git a/src/sat/smt/q_mam.cpp b/src/sat/smt/q_mam.cpp index 1c356f9f2..0fa35cfd4 100644 --- a/src/sat/smt/q_mam.cpp +++ b/src/sat/smt/q_mam.cpp @@ -2000,9 +2000,6 @@ namespace q { m_args.resize(INIT_ARGS_SIZE); } - ~interpreter() { - } - void init(code_tree * t) { TRACE("mam_bug", tout << "preparing to match tree:\n" << *t << "\n";); m_registers.reserve(t->get_num_regs(), nullptr); diff --git a/src/sat/smt/q_mam.h b/src/sat/smt/q_mam.h index 9fc6d18f1..e642f9e44 100644 --- a/src/sat/smt/q_mam.h +++ b/src/sat/smt/q_mam.h @@ -39,7 +39,7 @@ namespace q { class mam { friend class mam_impl; - mam() {} + mam() = default; public: diff --git a/src/sat/smt/sat_th.h b/src/sat/smt/sat_th.h index cc437173e..8228f1ce4 100644 --- a/src/sat/smt/sat_th.h +++ b/src/sat/smt/sat_th.h @@ -147,6 +147,8 @@ namespace euf { virtual void finalize() {} + virtual void initialize_value(expr* v, expr* value) { IF_VERBOSE(5, verbose_stream() << "value initialzation is not supported for theory\n"); } + }; class th_proof_hint : public sat::proof_hint { diff --git a/src/sat/smt/specrel_solver.cpp b/src/sat/smt/specrel_solver.cpp index d59029e6b..064e19904 100644 --- a/src/sat/smt/specrel_solver.cpp +++ b/src/sat/smt/specrel_solver.cpp @@ -32,9 +32,6 @@ namespace specrel { ctx.get_egraph().add_plugin(alloc(euf::specrel_plugin, ctx.get_egraph())); } - solver::~solver() { - } - void solver::asserted(sat::literal l) { } diff --git a/src/sat/smt/specrel_solver.h b/src/sat/smt/specrel_solver.h index 9ebb76916..51e383bad 100644 --- a/src/sat/smt/specrel_solver.h +++ b/src/sat/smt/specrel_solver.h @@ -39,7 +39,6 @@ namespace specrel { public: solver(euf::solver& ctx, theory_id id); - ~solver() override; bool is_external(bool_var v) override { return false; } void get_antecedents(literal l, sat::ext_justification_idx idx, literal_vector& r, bool probing) override {} diff --git a/src/sat/tactic/sat_tactic.cpp b/src/sat/tactic/sat_tactic.cpp index dabda88d7..d43442ed9 100644 --- a/src/sat/tactic/sat_tactic.cpp +++ b/src/sat/tactic/sat_tactic.cpp @@ -33,13 +33,27 @@ class sat_tactic : public tactic { sat2goal m_sat2goal; scoped_ptr m_solver; params_ref m_params; + vector>& m_var2value; - imp(ast_manager & _m, params_ref const & p): + imp(ast_manager & _m, params_ref const & p, vector>& var2value): m(_m), m_solver(alloc(sat::solver, p, m.limit())), - m_params(p) { + m_params(p), + m_var2value(var2value) { updt_params(p); } + + void initialize_values(goal_ref const& g, atom2bool_var& map) { + if (g->mc()) + g->mc()->convert_initialize_value(m_var2value); + for (auto & [var, value] : m_var2value) { + if (!m.is_bool(var)) + continue; + sat::bool_var b = map.to_bool_var(var); + if (b != sat::null_bool_var) + m_solver->set_phase(sat::literal(b, m.is_false(value))); + } + } void operator()(goal_ref const & g, goal_ref_buffer & result) { @@ -67,6 +81,8 @@ class sat_tactic : public tactic { g->reset(); g->m().compact_memory(); + initialize_values(g, map); + CASSERT("sat_solver", m_solver->check_invariant()); IF_VERBOSE(TACTIC_VERBOSITY_LVL, m_solver->display_status(verbose_stream());); TRACE("sat_dimacs", m_solver->display_dimacs(tout);); @@ -185,11 +201,14 @@ class sat_tactic : public tactic { imp * m_imp; params_ref m_params; statistics m_stats; + ast_manager& m; + vector> m_var2value; public: sat_tactic(ast_manager & m, params_ref const & p): m_imp(nullptr), - m_params(p) { + m_params(p), + m(m) { sat_params p1(p); } @@ -216,7 +235,7 @@ public: void operator()(goal_ref const & g, goal_ref_buffer & result) override { - imp proc(g->m(), m_params); + imp proc(g->m(), m_params, m_var2value); scoped_set_imp set(this, &proc); try { proc(g, result); @@ -247,6 +266,11 @@ public: m_stats.reset(); } + void user_propagate_initialize_value(expr* var, expr* value) override { + m_var2value.push_back({ expr_ref(var, m), expr_ref(value, m) }); + } + + protected: }; diff --git a/src/smt/arith_eq_adapter.cpp b/src/smt/arith_eq_adapter.cpp index f251d01ae..b77a38927 100644 --- a/src/smt/arith_eq_adapter.cpp +++ b/src/smt/arith_eq_adapter.cpp @@ -67,8 +67,6 @@ namespace smt { m_ge(ge) { } - ~arith_eq_relevancy_eh() override {} - void operator()(relevancy_propagator & rp) override { if (!rp.is_relevant(m_n1)) return; diff --git a/src/smt/diff_logic.h b/src/smt/diff_logic.h index ee1dbd63a..4628721ab 100644 --- a/src/smt/diff_logic.h +++ b/src/smt/diff_logic.h @@ -569,6 +569,7 @@ public: void traverse_neg_cycle2(bool try_relax, Functor & f) { static unsigned num_conflicts = 0; ++num_conflicts; + (void)num_conflicts; SASSERT(!is_feasible(m_edges[m_last_enabled_edge])); vector potentials; svector edges; @@ -1871,13 +1872,11 @@ public: // found path. reset_marks(); m_heap.reset(); - unsigned length = 0; do { inc_activity(m_parent[w]); edge const& ee = m_edges[m_parent[w]]; f(ee.get_explanation()); w = ee.get_source(); - ++length; } while (w != src2); return; diff --git a/src/smt/dyn_ack.cpp b/src/smt/dyn_ack.cpp index 978f1fbe3..66a2c2d5d 100644 --- a/src/smt/dyn_ack.cpp +++ b/src/smt/dyn_ack.cpp @@ -294,7 +294,6 @@ namespace smt { void dyn_ack_manager::gc() { TRACE("dyn_ack", tout << "dyn_ack GC\n";); - unsigned num_deleted = 0; m_to_instantiate.reset(); m_qhead = 0; svector::iterator it = m_app_pairs.begin(); @@ -318,7 +317,6 @@ namespace smt { // SASSERT(num_occs > 0); num_occs = static_cast(num_occs * m_params.m_dack_gc_inv_decay); if (num_occs <= 1) { - num_deleted++; TRACE("dyn_ack", tout << "2) erasing:\n" << mk_pp(p.first, m) << "\n" << mk_pp(p.second, m) << "\n";); m_app_pair2num_occs.erase(p.first, p.second); m.dec_ref(p.first); @@ -337,7 +335,6 @@ namespace smt { // app_pair_lt is not a total order on pairs of expressions. // So, we should use stable_sort to avoid different behavior in different platforms. std::stable_sort(m_to_instantiate.begin(), m_to_instantiate.end(), f); - // IF_VERBOSE(10, if (num_deleted > 0) verbose_stream() << "dynamic ackermann GC: " << num_deleted << "\n";); } class dyn_ack_clause_del_eh : public clause_del_eh { @@ -519,7 +516,6 @@ namespace smt { void dyn_ack_manager::gc_triples() { TRACE("dyn_ack", tout << "dyn_ack GC\n";); - unsigned num_deleted = 0; m_triple.m_to_instantiate.reset(); m_triple.m_qhead = 0; svector::iterator it = m_triple.m_apps.begin(); @@ -544,7 +540,6 @@ namespace smt { // SASSERT(num_occs > 0); num_occs = static_cast(num_occs * m_params.m_dack_gc_inv_decay); if (num_occs <= 1) { - num_deleted++; TRACE("dyn_ack", tout << "2) erasing:\n" << mk_pp(p.first, m) << "\n" << mk_pp(p.second, m) << "\n";); m_triple.m_app2num_occs.erase(p.first, p.second, p.third); m.dec_ref(p.first); @@ -563,7 +558,6 @@ namespace smt { app_triple_lt f(m_triple.m_app2num_occs); // app_triple_lt is not a total order std::stable_sort(m_triple.m_to_instantiate.begin(), m_triple.m_to_instantiate.end(), f); - // IF_VERBOSE(10, if (num_deleted > 0) verbose_stream() << "dynamic ackermann GC: " << num_deleted << "\n";); } diff --git a/src/smt/fingerprints.cpp b/src/smt/fingerprints.cpp index 447c2b2a1..ac13999d0 100644 --- a/src/smt/fingerprints.cpp +++ b/src/smt/fingerprints.cpp @@ -63,6 +63,26 @@ namespace smt { fingerprint * fingerprint_set::insert(void * data, unsigned data_hash, unsigned num_args, enode * const * args, expr* def) { + + struct arg_data { + unsigned data_hash; + enode* const* args; + }; + struct khash { + unsigned operator()(arg_data const& d) const { + return d.data_hash; + } + }; + struct arghash { + unsigned operator()(arg_data const& d, unsigned i) const { + return d.args[i]->hash(); + } + }; + arg_data arg_data({ data_hash, args }); + khash kh; + arghash ah; + data_hash = get_composite_hash(arg_data, num_args, kh, ah); + fingerprint * d = mk_dummy(data, data_hash, num_args, args); if (m_set.contains(d)) return nullptr; @@ -107,8 +127,12 @@ namespace smt { unsigned new_lvl = lvl - num_scopes; unsigned old_size = m_scopes[new_lvl]; unsigned size = m_fingerprints.size(); - for (unsigned i = old_size; i < size; i++) - m_set.erase(m_fingerprints[i]); + if (old_size == 0 && size > 0) + m_set.reset(); + else { + for (unsigned i = old_size; i < size; i++) + m_set.erase(m_fingerprints[i]); + } m_fingerprints.shrink(old_size); m_defs.shrink(old_size); m_scopes.shrink(new_lvl); diff --git a/src/smt/fingerprints.h b/src/smt/fingerprints.h index b1904a4ee..6a0bc1ccd 100644 --- a/src/smt/fingerprints.h +++ b/src/smt/fingerprints.h @@ -32,7 +32,7 @@ namespace smt { enode** m_args = nullptr; friend class fingerprint_set; - fingerprint() {} + fingerprint() = default; public: fingerprint(region & r, void * d, unsigned d_hash, expr* def, unsigned n, enode * const * args); void * get_data() const { return m_data; } @@ -48,15 +48,9 @@ namespace smt { class fingerprint_set { - struct fingerprint_khasher { - unsigned operator()(fingerprint const * f) const { return f->get_data_hash(); } - }; - struct fingerprint_chasher { - unsigned operator()(fingerprint const * f, unsigned idx) const { return f->get_arg(idx)->hash(); } - }; struct fingerprint_hash_proc { unsigned operator()(fingerprint const * f) const { - return get_composite_hash(const_cast(f), f->get_num_args()); + return f->get_data_hash(); } }; struct fingerprint_eq_proc { bool operator()(fingerprint const * f1, fingerprint const * f2) const; }; diff --git a/src/smt/mam.cpp b/src/smt/mam.cpp index b9ac45039..48d243771 100644 --- a/src/smt/mam.cpp +++ b/src/smt/mam.cpp @@ -906,9 +906,9 @@ namespace { void linearise_core() { m_aux.reset(); app * first_app = nullptr; - unsigned first_app_reg; - unsigned first_app_sz; - unsigned first_app_num_unbound_vars; + unsigned first_app_reg = 0; + unsigned first_app_sz = 0; + unsigned first_app_num_unbound_vars = 0; // generate first the non-BIND operations for (unsigned reg : m_todo) { expr * p = m_registers[reg]; @@ -1995,9 +1995,6 @@ namespace { m_args.resize(INIT_ARGS_SIZE); } - ~interpreter() { - } - void init(code_tree * t) { TRACE("mam_bug", tout << "preparing to match tree:\n" << *t << "\n";); m_registers.reserve(t->get_num_regs(), nullptr); @@ -3943,9 +3940,11 @@ namespace { } return; } - for (unsigned i = 0; i < num_bindings; i++) { - SASSERT(bindings[i]->get_generation() <= max_generation); - } + DEBUG_CODE( + for (unsigned i = 0; i < num_bindings; i++) { + SASSERT(bindings[i]->get_generation() <= max_generation); + }); + #endif unsigned min_gen = 0, max_gen = 0; m_interpreter.get_min_max_top_generation(min_gen, max_gen); diff --git a/src/smt/params/smt_params.cpp b/src/smt/params/smt_params.cpp index 02919b287..71587b5cc 100644 --- a/src/smt/params/smt_params.cpp +++ b/src/smt/params/smt_params.cpp @@ -331,7 +331,7 @@ void smt_params::setup_QF_BV() { } void smt_params::setup_QF_AUFBV() { - m_array_mode = AR_SIMPLE; + m_array_mode = AR_FULL; m_relevancy_lvl = 0; m_bv_cc = false; m_bb_ext_gates = true; diff --git a/src/smt/params/theory_array_params.h b/src/smt/params/theory_array_params.h index b6da32ba5..8c56093a8 100644 --- a/src/smt/params/theory_array_params.h +++ b/src/smt/params/theory_array_params.h @@ -41,8 +41,6 @@ struct theory_array_params { unsigned m_array_lazy_ieq_delay = 10; bool m_array_fake_support = false; // fake support for all array operations to pretend they are satisfiable. - theory_array_params() {} - void updt_params(params_ref const & _p); void display(std::ostream & out) const; diff --git a/src/smt/qi_queue.cpp b/src/smt/qi_queue.cpp index 52399abb6..81d41eeee 100644 --- a/src/smt/qi_queue.cpp +++ b/src/smt/qi_queue.cpp @@ -43,9 +43,6 @@ namespace smt { m_vals.resize(15, 0.0f); } - qi_queue::~qi_queue() { - } - void qi_queue::setup() { TRACE("qi_cost", tout << "qi_cost: " << m_params.m_qi_cost << "\n";); if (!m_parser.parse_string(m_params.m_qi_cost.c_str(), m_cost_function)) { diff --git a/src/smt/qi_queue.h b/src/smt/qi_queue.h index bdf4bd50e..961dd73e0 100644 --- a/src/smt/qi_queue.h +++ b/src/smt/qi_queue.h @@ -80,7 +80,6 @@ namespace smt { public: qi_queue(quantifier_manager & qm, context & ctx, qi_params & params); - ~qi_queue(); void setup(); /** \brief Insert a new quantifier in the queue, f contains the quantifier and bindings. diff --git a/src/smt/smt_conflict_resolution.cpp b/src/smt/smt_conflict_resolution.cpp index 793243473..90877a963 100644 --- a/src/smt/smt_conflict_resolution.cpp +++ b/src/smt/smt_conflict_resolution.cpp @@ -52,9 +52,6 @@ namespace smt { { } - conflict_resolution::~conflict_resolution() { - } - /** \brief Mark all enodes in a 'proof' tree branch starting at n n -> ... -> root diff --git a/src/smt/smt_conflict_resolution.h b/src/smt/smt_conflict_resolution.h index cf707bd31..87ad19771 100644 --- a/src/smt/smt_conflict_resolution.h +++ b/src/smt/smt_conflict_resolution.h @@ -208,7 +208,7 @@ namespace smt { vector & watches ); - virtual ~conflict_resolution(); + virtual ~conflict_resolution() = default; virtual bool resolve(b_justification conflict, literal not_l); diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index 62c7c8ddd..9ceee136f 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -71,7 +71,6 @@ namespace smt { m_l_internalized_stack(m), m_final_check_idx(0), m_cg_table(m), - m_units_to_reassert(m), m_conflict(null_b_justification), m_not_l(null_literal), m_conflict_resolution(mk_conflict_resolution(m, *this, m_dyn_ack_manager, p, m_assigned_literals, m_watches)), @@ -99,13 +98,15 @@ namespace smt { m_model_generator->set_context(this); } - /** \brief retrieve flag for when cancelation is possible. */ bool context::get_cancel_flag() { - return !m.limit().inc(); + if (m.limit().inc()) + return false; + m_last_search_failure = CANCELED; + return true; } void context::updt_params(params_ref const& p) { @@ -1117,6 +1118,8 @@ namespace smt { */ bool context::is_diseq(enode * n1, enode * n2) const { SASSERT(n1->get_sort() == n2->get_sort()); + if (m.are_distinct(n1->get_root()->get_expr(), n2->get_root()->get_expr())) + return true; context * _this = const_cast(this); if (!m_is_diseq_tmp) { app * eq = m.mk_eq(n1->get_expr(), n2->get_expr()); @@ -1856,8 +1859,10 @@ namespace smt { lbool phase = l_undef; m_case_split_queue->next_case_split(var, phase); used_queue = true; - if (var == null_bool_var) + if (var == null_bool_var) { + push_trail(value_trail(m_has_case_split, false)); return false; + } TRACE_CODE({ static unsigned counter = 0; @@ -2180,7 +2185,7 @@ namespace smt { unsigned i = s.m_units_to_reassert_lim; unsigned sz = m_units_to_reassert.size(); for (; i < sz; i++) { - expr * unit = m_units_to_reassert.get(i); + expr* unit = m_units_to_reassert[i].m_unit.get(); cache_generation(unit, new_scope_lvl); } } @@ -2371,19 +2376,18 @@ namespace smt { unsigned i = units_to_reassert_lim; unsigned sz = m_units_to_reassert.size(); for (; i < sz; i++) { - expr * unit = m_units_to_reassert.get(i); + auto& [unit, sign, is_relevant] = m_units_to_reassert[i]; bool gate_ctx = true; internalize(unit, gate_ctx); bool_var v = get_bool_var(unit); - bool sign = m_units_to_reassert_sign[i] != 0; literal l(v, sign); assign(l, b_justification::mk_axiom()); + if (is_relevant) + mark_as_relevant(l); TRACE("reassert_units", tout << "reasserting #" << unit->get_id() << " " << sign << " @ " << m_scope_lvl << "\n";); } - if (at_base_level()) { - m_units_to_reassert.reset(); - m_units_to_reassert_sign.reset(); - } + if (at_base_level()) + m_units_to_reassert.reset(); } /** @@ -2908,6 +2912,43 @@ namespace smt { register_plugin(m_user_propagator); } + void context::user_propagate_initialize_value(expr* var, expr* value) { + m_values.push_back({expr_ref(var, m), expr_ref(value, m)}); + push_trail(push_back_vector(m_values)); + } + + void context::initialize_value(expr* var, expr* value) { + IF_VERBOSE(10, verbose_stream() << "initialize " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); + sort* s = var->get_sort(); + ensure_internalized(var); + + if (m.is_bool(s)) { + auto v = get_bool_var_of_id_option(var->get_id()); + if (v == null_bool_var) { + IF_VERBOSE(5, verbose_stream() << "Boolean variable has no literal " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); + return; + } + m_bdata[v].m_phase_available = true; + if (m.is_true(value)) + m_bdata[v].m_phase = true; + else if (m.is_false(value)) + m_bdata[v].m_phase = false; + else + IF_VERBOSE(5, verbose_stream() << "Boolean value is not constant " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); + return; + } + + if (!e_internalized(var)) + return; + theory* th = m_theories.get_plugin(s->get_family_id()); + if (!th) { + IF_VERBOSE(5, verbose_stream() << "No theory is attached to variable " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); + return; + } + th->initialize_value(var, value); + + } + bool context::watches_fixed(enode* n) const { return m_user_propagator && m_user_propagator->has_fixed() && n->get_th_var(m_user_propagator->get_family_id()) != null_theory_var; } @@ -3741,14 +3782,18 @@ namespace smt { VERIFY(!resolve_conflict()); return l_false; } - if (get_cancel_flag()) + if (get_cancel_flag()) return l_undef; + timeit tt(get_verbosity_level() >= 100, "smt.stats"); reset_model(); SASSERT(at_search_level()); TRACE("search", display(tout); display_enodes_lbls(tout);); TRACE("search_detail", m_asserted_formulas.display(tout);); init_search(); + for (auto const& [var, value] : m_values) + initialize_value(var, value); + flet l(m_searching, true); TRACE("after_init_search", display(tout);); IF_VERBOSE(2, verbose_stream() << "(smt.searching)\n";); @@ -3955,10 +4000,8 @@ namespace smt { if (m_last_search_failure != OK) return true; - if (get_cancel_flag()) { - m_last_search_failure = CANCELED; - return true; - } + if (get_cancel_flag()) + return true; if (m_progress_callback) { m_progress_callback->fast_progress_sample(); @@ -3969,10 +4012,8 @@ namespace smt { } } - if (get_cancel_flag()) { - m_last_search_failure = CANCELED; - return true; - } + if (get_cancel_flag()) + return true; if (memory::above_high_watermark()) { m_last_search_failure = MEMOUT; @@ -4267,8 +4308,7 @@ namespace smt { bool unit_sign = lits[0].sign(); while (m.is_not(unit, unit)) unit_sign = !unit_sign; - m_units_to_reassert.push_back(unit); - m_units_to_reassert_sign.push_back(unit_sign); + m_units_to_reassert.push_back({ expr_ref(unit, m), unit_sign, is_relevant(unit) }); TRACE("reassert_units", tout << "asserting " << mk_pp(unit, m) << " #" << unit->get_id() << " " << unit_sign << " @ " << m_scope_lvl << "\n";); } @@ -4640,6 +4680,9 @@ namespace smt { } bool context::has_case_splits() { + if (!m_has_case_split) + return false; + for (unsigned i = get_num_b_internalized(); i-- > 0; ) { if (is_relevant(i) && get_assignment(i) == l_undef) return true; diff --git a/src/smt/smt_context.h b/src/smt/smt_context.h index 4feeae1b5..715b28f23 100644 --- a/src/smt/smt_context.h +++ b/src/smt/smt_context.h @@ -71,6 +71,12 @@ namespace smt { enode_pp(enode* n, context const& ctx): ctx(ctx), n(n) {} }; + struct replay_unit { + expr_ref m_unit; + bool m_sign; + bool m_relevant; + }; + class context { friend class model_generator; friend class lookahead; @@ -123,6 +129,7 @@ namespace smt { unsigned m_par_index = 0; bool m_internalizing_assertions = false; + // ----------------------------------- // // Equality & Uninterpreted functions @@ -182,8 +189,7 @@ namespace smt { clause_vector m_aux_clauses; clause_vector m_lemmas; vector m_clauses_to_reinit; - expr_ref_vector m_units_to_reassert; - svector m_units_to_reassert_sign; + vector m_units_to_reassert; literal_vector m_assigned_literals; typedef std::pair tmp_clause; vector m_tmp_clauses; @@ -246,6 +252,16 @@ namespace smt { vector m_th_case_split_sets; u_map< vector > m_literal2casesplitsets; // returns the case split literal sets that a literal participates in + + // ---------------------------------- + // + // Value initialization + // + // ---------------------------------- + vector> m_values; + void initialize_value(expr* var, expr* value); + + // ----------------------------------- // // Accessors @@ -1155,6 +1171,7 @@ namespace smt { bool guess(bool_var var, lbool phase); protected: + bool m_has_case_split = true; bool decide(); void update_phase_cache_counter(); @@ -1776,6 +1793,8 @@ namespace smt { m_user_propagator->register_decide(r); } + void user_propagate_initialize_value(expr* var, expr* value); + bool watches_fixed(enode* n) const; bool has_split_candidate(bool_var& var, bool& is_pos); diff --git a/src/smt/smt_enode.h b/src/smt/smt_enode.h index 92902ea0b..3f488a3b7 100644 --- a/src/smt/smt_enode.h +++ b/src/smt/smt_enode.h @@ -360,8 +360,7 @@ namespace smt { enode* operator*() { return m_first; } iterator& operator++() { if (!m_last) m_last = m_first; m_first = m_first->m_next; return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } - bool operator==(iterator const& other) const { return m_last == other.m_last && m_first == other.m_first; } - bool operator!=(iterator const& other) const { return !(*this == other); } + bool operator!=(iterator const& other) const { return m_last != other.m_last || m_first != other.m_first; } }; iterator begin() { return iterator(this, nullptr); } diff --git a/src/smt/smt_kernel.cpp b/src/smt/smt_kernel.cpp index 74f0bded6..2d6c29532 100644 --- a/src/smt/smt_kernel.cpp +++ b/src/smt/smt_kernel.cpp @@ -305,5 +305,9 @@ namespace smt { void kernel::user_propagate_register_decide(user_propagator::decide_eh_t& r) { m_imp->m_kernel.user_propagate_register_decide(r); } + + void kernel::user_propagate_initialize_value(expr* var, expr* value) { + m_imp->m_kernel.user_propagate_initialize_value(var, value); + } }; diff --git a/src/smt/smt_kernel.h b/src/smt/smt_kernel.h index eec74f8b1..539a32750 100644 --- a/src/smt/smt_kernel.h +++ b/src/smt/smt_kernel.h @@ -322,6 +322,8 @@ namespace smt { void user_propagate_register_decide(user_propagator::decide_eh_t& r); + void user_propagate_initialize_value(expr* var, expr* value); + /** \brief Return a reference to smt::context. This breaks abstractions. diff --git a/src/smt/smt_lookahead.cpp b/src/smt/smt_lookahead.cpp index 8de3f2f34..221c2d0ea 100644 --- a/src/smt/smt_lookahead.cpp +++ b/src/smt/smt_lookahead.cpp @@ -79,7 +79,7 @@ namespace smt { compare comp(ctx); std::sort(vars.begin(), vars.end(), comp); - unsigned nf = 0, nc = 0, ns = 0, n = 0; + unsigned ns = 0, n = 0; for (bool_var v : vars) { if (!ctx.bool_var2expr(v)) continue; @@ -98,7 +98,6 @@ namespace smt { if (inconsistent) { ctx.assign(~lit, b_justification::mk_axiom(), false); ctx.propagate(); - ++nf; continue; } @@ -114,7 +113,6 @@ namespace smt { if (inconsistent) { ctx.assign(lit, b_justification::mk_axiom(), false); ctx.propagate(); - ++nf; continue; } double score = score1 + score2 + 1024*score1*score2; @@ -132,7 +130,6 @@ namespace smt { best_v = v; ns = 0; } - ++nc; ++ns; if (ns > budget) { break; diff --git a/src/smt/smt_model_finder.cpp b/src/smt/smt_model_finder.cpp index 4139b3109..7a567d5a9 100644 --- a/src/smt/smt_model_finder.cpp +++ b/src/smt/smt_model_finder.cpp @@ -223,8 +223,6 @@ namespace smt { m_sort(s) { } - ~node() {} - unsigned get_id() const { return m_id; } sort* get_sort() const { return m_sort; } diff --git a/src/smt/smt_model_generator.cpp b/src/smt/smt_model_generator.cpp index 6537e638d..8f408d5cf 100644 --- a/src/smt/smt_model_generator.cpp +++ b/src/smt/smt_model_generator.cpp @@ -99,7 +99,6 @@ namespace smt { if (m.is_bool(s)) { CTRACE("model", m_context->get_assignment(r) == l_undef, tout << mk_pp(r->get_expr(), m) << "\n";); - SASSERT(m_context->get_assignment(r) != l_undef); if (m_context->get_assignment(r) == l_true) proc = alloc(expr_wrapper_proc, m.mk_true()); else diff --git a/src/smt/smt_relevancy.h b/src/smt/smt_relevancy.h index f6e3c4659..8dea2842f 100644 --- a/src/smt/smt_relevancy.h +++ b/src/smt/smt_relevancy.h @@ -48,7 +48,6 @@ namespace smt { expr * m_target; public: simple_relevancy_eh(expr * t):m_target(t) {} - ~simple_relevancy_eh() override {} void operator()(relevancy_propagator & rp) override; }; @@ -61,7 +60,6 @@ namespace smt { expr * m_target; public: pair_relevancy_eh(expr * s1, expr * s2, expr * t):m_source1(s1), m_source2(s2), m_target(t) {} - ~pair_relevancy_eh() override {} void operator()(relevancy_propagator & rp) override; }; diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp index f91a31111..7b9d416f3 100644 --- a/src/smt/smt_solver.cpp +++ b/src/smt/smt_solver.cpp @@ -252,6 +252,10 @@ namespace { m_context.user_propagate_register_decide(c); } + void user_propagate_initialize_value(expr* var, expr* value) override { + m_context.user_propagate_initialize_value(var, value); + } + struct scoped_minimize_core { smt_solver& s; expr_ref_vector m_assumptions; diff --git a/src/smt/smt_theory.cpp b/src/smt/smt_theory.cpp index 0c876e8bc..86f1c1141 100644 --- a/src/smt/smt_theory.cpp +++ b/src/smt/smt_theory.cpp @@ -177,9 +177,6 @@ namespace smt { m_lazy(true) { } - theory::~theory() { - } - smt_params const& theory::get_fparams() const { return ctx.get_fparams(); } diff --git a/src/smt/smt_theory.h b/src/smt/smt_theory.h index d0e73cc92..74dfe8aa2 100644 --- a/src/smt/smt_theory.h +++ b/src/smt/smt_theory.h @@ -388,7 +388,7 @@ namespace smt { public: theory(context& ctx, family_id fid); - virtual ~theory(); + virtual ~theory() = default; virtual void setup() {} @@ -549,6 +549,10 @@ namespace smt { return get_manager().mk_eq(lhs, rhs); } + virtual void initialize_value(expr* var, expr* value) { + IF_VERBOSE(5, verbose_stream() << "no default initialization associated with " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); + } + literal mk_eq(expr * a, expr * b, bool gate_ctx); literal mk_preferred_eq(expr* a, expr* b); diff --git a/src/smt/tactic/smt_tactic_core.cpp b/src/smt/tactic/smt_tactic_core.cpp index 2be2ace58..89b2b7135 100644 --- a/src/smt/tactic/smt_tactic_core.cpp +++ b/src/smt/tactic/smt_tactic_core.cpp @@ -41,6 +41,7 @@ class smt_tactic : public tactic { smt_params m_params; params_ref m_params_ref; expr_ref_vector m_vars; + vector> m_values; statistics m_stats; smt::kernel* m_ctx = nullptr; symbol m_logic; @@ -344,6 +345,8 @@ public: for (expr* v : m_vars) m_ctx->user_propagate_register_expr(v); + for (auto& [var, value] : m_values) + m_ctx->user_propagate_initialize_value(var, value); } void user_propagate_clear() override { @@ -403,6 +406,10 @@ public: void user_propagate_register_decide(user_propagator::decide_eh_t& decide_eh) override { m_decide_eh = decide_eh; } + + void user_propagate_initialize_value(expr* var, expr* value) override { + m_values.push_back({expr_ref(var, m), expr_ref(value, m)}); + } }; static tactic * mk_seq_smt_tactic(ast_manager& m, params_ref const & p) { diff --git a/src/smt/theory_arith.h b/src/smt/theory_arith.h index 86c05aec6..e2bc5e7a4 100644 --- a/src/smt/theory_arith.h +++ b/src/smt/theory_arith.h @@ -662,6 +662,7 @@ namespace smt { void restart_eh() override; void init_search_eh() override; + void initialize_value(expr* var, expr* value) override; /** \brief True if the assignment may be changed during final check. assume_eqs, check_int_feasibility, @@ -1053,7 +1054,6 @@ namespace smt { // ----------------------------------- public: theory_arith(context& ctx); - ~theory_arith() override; theory * mk_fresh(context * new_ctx) override; diff --git a/src/smt/theory_arith_aux.h b/src/smt/theory_arith_aux.h index 8141377c4..e624f84b5 100644 --- a/src/smt/theory_arith_aux.h +++ b/src/smt/theory_arith_aux.h @@ -1554,6 +1554,7 @@ namespace smt { min_gain.reset(); ++round; + (void)round; TRACE("opt", tout << "round: " << round << ", max: " << max << "\n"; display_row(tout, r, true); tout << "state:\n"; display(tout);); typename vector::const_iterator it = r.begin_entries(); typename vector::const_iterator end = r.end_entries(); @@ -2249,6 +2250,21 @@ namespace smt { return false; } + template + void theory_arith::initialize_value(expr* var, expr* value) { + theory_var v = expr2var(var); + rational r; + if (!m_util.is_numeral(value, r)) { + IF_VERBOSE(5, verbose_stream() << "numeric constant expected in initialization " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); + return; + } + if (v == null_theory_var) + return; + if (is_base(v)) + return; + update_value(v, inf_numeral(r)); + } + #if 0 /** diff --git a/src/smt/theory_arith_core.h b/src/smt/theory_arith_core.h index 4e4464a52..e4f788f60 100644 --- a/src/smt/theory_arith_core.h +++ b/src/smt/theory_arith_core.h @@ -1737,10 +1737,6 @@ namespace smt { m_bound_watch(null_bool_var) { } - template - theory_arith::~theory_arith() { - } - template theory* theory_arith::mk_fresh(context* new_ctx) { return alloc(theory_arith, *new_ctx); @@ -3030,7 +3026,7 @@ namespace smt { template void theory_arith::propagate_bounds() { TRACE("propagate_bounds_detail", display(tout);); - unsigned num_prop = 0, count = 0; + unsigned count = 0; for (unsigned r_idx : m_to_check) { row & r = m_rows[r_idx]; if (r.get_base_var() != null_theory_var) { @@ -3039,34 +3035,19 @@ namespace smt { int upper_idx; is_row_useful_for_bound_prop(r, lower_idx, upper_idx); - ++num_prop; if (lower_idx >= 0) count += imply_bound_for_monomial(r, lower_idx, true); else if (lower_idx == -1) count += imply_bound_for_all_monomials(r, true); - else - --num_prop; - ++num_prop; if (upper_idx >= 0) count += imply_bound_for_monomial(r, upper_idx, false); else if (upper_idx == -1) count += imply_bound_for_all_monomials(r, false); - else - --num_prop; // sneaking cheap eq detection in this loop propagate_cheap_eq(r_idx); } - -#if 0 - theory_var v = r.get_base_var(); - if (!is_int(v) || get_value(v).is_int()) { - // If an integer value is not assigned to an integer value, then - // bound propagation can diverge. - m_in_to_check.remove(v); - } -#endif } } diff --git a/src/smt/theory_arith_int.h b/src/smt/theory_arith_int.h index 75c8785a7..905f67704 100644 --- a/src/smt/theory_arith_int.h +++ b/src/smt/theory_arith_int.h @@ -360,7 +360,7 @@ namespace smt { for (unsigned i = 1; i < unsat_row.size(); ++i) { numeral c(unsat_row[i]); if (!c.is_zero()) { - theory_var var; + theory_var var = null_theory_var; if (!index2var.find(i, var)) { UNREACHABLE(); } diff --git a/src/smt/theory_bv.cpp b/src/smt/theory_bv.cpp index 55d3a1d62..b1fe47b65 100644 --- a/src/smt/theory_bv.cpp +++ b/src/smt/theory_bv.cpp @@ -1493,9 +1493,6 @@ namespace smt { m_bb.set_flat_and_or(false); } - theory_bv::~theory_bv() { - } - theory* theory_bv::mk_fresh(context* new_ctx) { return alloc(theory_bv, *new_ctx); } @@ -1789,6 +1786,27 @@ namespace smt { return false; } + void theory_bv::initialize_value(expr* var, expr* value) { + rational val; + unsigned sz; + TRACE("bv", tout << "initializing " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); + if (!m_util.is_numeral(value, val, sz)) { + IF_VERBOSE(5, verbose_stream() << "value should be a bit-vector " << mk_pp(value, m) << "\n"); + return; + } + if (!is_app(var)) + return; + enode* n = mk_enode(to_app(var)); + auto v = get_var(n); + unsigned idx = 0; + for (auto lit : m_bits[v]) { + auto & b = ctx.get_bdata(lit.var()); + b.m_phase_available = true; + b.m_phase = val.get_bit(idx); + ++idx; + } + } + void theory_bv::init_model(model_generator & mg) { m_factory = alloc(bv_factory, m); mg.register_factory(m_factory); @@ -1967,6 +1985,7 @@ namespace smt { while (curr != v); zero_one_bits const & _bits = m_zero_one_bits[v]; + (void)num_bits; SASSERT(_bits.size() == num_bits); bool_vector already_found; already_found.resize(bv_sz, false); diff --git a/src/smt/theory_bv.h b/src/smt/theory_bv.h index 10cf005e3..0a7d4bbb2 100644 --- a/src/smt/theory_bv.h +++ b/src/smt/theory_bv.h @@ -251,6 +251,7 @@ namespace smt { bool merge_zero_one_bits(theory_var r1, theory_var r2); bool can_propagate() override { return m_prop_diseqs_qhead < m_prop_diseqs.size(); } void propagate() override; + void initialize_value(expr* var, expr* value) override; // ----------------------------------- // @@ -267,7 +268,6 @@ namespace smt { typedef std::pair var_enode_pos; theory_bv(context& ctx); - ~theory_bv() override; theory * mk_fresh(context * new_ctx) override; diff --git a/src/smt/theory_datatype.cpp b/src/smt/theory_datatype.cpp index b794a44b5..3302199a2 100644 --- a/src/smt/theory_datatype.cpp +++ b/src/smt/theory_datatype.cpp @@ -762,8 +762,7 @@ namespace smt { m_util(m), m_autil(m), m_sutil(m), - m_find(*this), - m_trail_stack() { + m_find(*this) { } theory_datatype::~theory_datatype() { diff --git a/src/smt/theory_lra.cpp b/src/smt/theory_lra.cpp index f0a96ddd1..5a3cbbd1a 100644 --- a/src/smt/theory_lra.cpp +++ b/src/smt/theory_lra.cpp @@ -991,6 +991,15 @@ public: return lp().compare_values(vi, k, b->get_value()) ? l_true : l_false; } + void initialize_value(expr* var, expr* value) { + rational r; + if (!a.is_numeral(value, r)) { + IF_VERBOSE(5, verbose_stream() << "numeric constant expected in initialization " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); + return; + } + lp().move_lpvar_to_value(get_lpvar(var), r); + } + void new_eq_eh(theory_var v1, theory_var v2) { TRACE("arith", tout << "eq " << v1 << " == " << v2 << "\n";); if (!is_int(v1) && !is_real(v1)) @@ -1563,7 +1572,7 @@ public: } final_check_status eval_power(expr* e) { - expr* x, * y; + expr* x = nullptr, * y = nullptr; rational r; VERIFY(a.is_power(e, x, y)); if (a.is_numeral(x, r) && r == 0 && a.is_numeral(y, r) && r == 0) @@ -3486,10 +3495,8 @@ public: bool validate_eq(enode* x, enode* y) { static bool s_validating = false; - static unsigned s_count = 0; if (s_validating) return true; - ++s_count; flet _svalid(s_validating, true); context nctx(m, ctx().get_fparams(), ctx().get_params()); add_background(nctx); @@ -3797,19 +3804,10 @@ public: * Facility to put a small box around integer variables used in branch and bounds. */ - struct bound_info { - rational m_offset; - unsigned m_range; - bound_info() {} - bound_info(rational const& o, unsigned r):m_offset(o), m_range(r) {} - }; unsigned m_bounded_range_idx; // current size of bounded range. literal m_bounded_range_lit; // current bounded range literal expr_ref_vector m_bound_terms; // predicates used for bounds expr_ref m_bound_predicate; - - obj_map m_predicate2term; - obj_map m_term2bound_info; unsigned init_range() const { return 5; } unsigned max_range() const { return 20; } @@ -3819,8 +3817,6 @@ public: m_bounded_range_lit = null_literal; m_bound_terms.reset(); m_bound_predicate = nullptr; - m_predicate2term.reset(); - m_term2bound_info.reset(); } @@ -3878,6 +3874,9 @@ void theory_lra::assign_eh(bool_var v, bool is_true) { lbool theory_lra::get_phase(bool_var v) { return m_imp->get_phase(v); } +void theory_lra::initialize_value(expr* var, expr* value) { + m_imp->initialize_value(var, value); +} void theory_lra::new_eq_eh(theory_var v1, theory_var v2) { m_imp->new_eq_eh(v1, v2); } @@ -3912,7 +3911,7 @@ final_check_status theory_lra::final_check_eh() { } bool theory_lra::is_shared(theory_var v) const { return m_imp->is_shared(v); -} +} bool theory_lra::can_propagate() { return m_imp->can_propagate(); } diff --git a/src/smt/theory_lra.h b/src/smt/theory_lra.h index 4c2351c85..96988f957 100644 --- a/src/smt/theory_lra.h +++ b/src/smt/theory_lra.h @@ -80,6 +80,8 @@ namespace smt { void apply_sort_cnstr(enode * n, sort * s) override; void init_model(model_generator & m) override; + + void initialize_value(expr* var, expr* value) override; model_value_proc * mk_value(enode * n, model_generator & mg) override; void validate_model(proto_model& mdl) override; diff --git a/src/smt/theory_pb.cpp b/src/smt/theory_pb.cpp index 25c8e7195..ed3ff0942 100644 --- a/src/smt/theory_pb.cpp +++ b/src/smt/theory_pb.cpp @@ -2127,9 +2127,9 @@ namespace smt { tout << "sum: " << sum << " " << maxsum << " "; tout << ctx.get_assignment(c.lit()) << "\n";); - SASSERT(sum <= maxsum); - SASSERT((sum >= c.k()) == (ctx.get_assignment(c.lit()) == l_true)); - SASSERT((maxsum < c.k()) == (ctx.get_assignment(c.lit()) == l_false)); + VERIFY(sum <= maxsum); + VERIFY((sum >= c.k()) == (ctx.get_assignment(c.lit()) == l_true)); + VERIFY((maxsum < c.k()) == (ctx.get_assignment(c.lit()) == l_false)); } void theory_pb::validate_final_check(ineq& c) { diff --git a/src/smt/theory_seq.h b/src/smt/theory_seq.h index 6ed4fc41f..d469097d8 100644 --- a/src/smt/theory_seq.h +++ b/src/smt/theory_seq.h @@ -134,7 +134,6 @@ namespace smt { unsigned_vector m_limit; public: exclusion_table(ast_manager& m): m(m), m_lhs(m), m_rhs(m) {} - ~exclusion_table() { } bool empty() const { return m_table.empty(); } void update(expr* e, expr* r); bool contains(expr* e, expr* r) const; diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 1e12f8bd3..f88887feb 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -1089,7 +1089,7 @@ namespace smt { void theory_str::instantiate_axiom_CharAt(enode * e) { ast_manager & m = get_manager(); - expr* arg0, *arg1; + expr* arg0 = nullptr, *arg1 = nullptr; app * expr = e->get_expr(); if (axiomatized_terms.contains(expr)) { TRACE("str", tout << "already set up CharAt axiom for " << mk_pp(expr, m) << std::endl;); @@ -4089,6 +4089,7 @@ namespace smt { expr_ref_vector arrangement_disjunction(mgr); int pos = 1; + (void)pos; for (unsigned int i = 0; i <= strValue.length(); i++) { zstring part1Str = strValue.extract(0, i); zstring part2Str = strValue.extract(i, strValue.length() - i); @@ -4522,6 +4523,7 @@ namespace smt { expr_ref_vector arrangement_disjunction(mgr); int pos = 1; + (void)pos; if (!avoidLoopCut || !has_self_cut(m, y)) { expr_ref_vector and_item(mgr); diff --git a/src/solver/CMakeLists.txt b/src/solver/CMakeLists.txt index 088f2cbb2..4c5f8b428 100644 --- a/src/solver/CMakeLists.txt +++ b/src/solver/CMakeLists.txt @@ -6,6 +6,7 @@ z3_add_component(solver mus.cpp parallel_tactical.cpp simplifier_solver.cpp + slice_solver.cpp smt_logics.cpp solver.cpp solver_na2as.cpp diff --git a/src/solver/assertions/asserted_formulas.cpp b/src/solver/assertions/asserted_formulas.cpp index ee94ac355..94a5edc59 100644 --- a/src/solver/assertions/asserted_formulas.cpp +++ b/src/solver/assertions/asserted_formulas.cpp @@ -89,10 +89,6 @@ void asserted_formulas::setup() { m_smt_params.m_relevancy_lemma = false; } - -asserted_formulas::~asserted_formulas() { -} - void asserted_formulas::push_assertion(expr * e, proof * pr, vector& result) { if (inconsistent()) { return; diff --git a/src/solver/assertions/asserted_formulas.h b/src/solver/assertions/asserted_formulas.h index 481af58b7..643cbc046 100644 --- a/src/solver/assertions/asserted_formulas.h +++ b/src/solver/assertions/asserted_formulas.h @@ -254,7 +254,6 @@ class asserted_formulas { public: asserted_formulas(ast_manager & m, smt_params & smtp, params_ref const& p); - ~asserted_formulas(); void finalize(); void updt_params(params_ref const& p); diff --git a/src/solver/check_sat_result.cpp b/src/solver/check_sat_result.cpp index fd7939d95..944f717b9 100644 --- a/src/solver/check_sat_result.cpp +++ b/src/solver/check_sat_result.cpp @@ -58,9 +58,6 @@ simple_check_sat_result::simple_check_sat_result(ast_manager & m): m_proof(m) { } -simple_check_sat_result::~simple_check_sat_result() { -} - void simple_check_sat_result::collect_statistics(statistics & st) const { st.copy(m_stats); } diff --git a/src/solver/check_sat_result.h b/src/solver/check_sat_result.h index 2269a1444..b992d260d 100644 --- a/src/solver/check_sat_result.h +++ b/src/solver/check_sat_result.h @@ -98,7 +98,6 @@ struct simple_check_sat_result : public check_sat_result { std::string m_unknown; simple_check_sat_result(ast_manager & m); - ~simple_check_sat_result() override; ast_manager& get_manager() const override { return m_proof.get_manager(); } void collect_statistics(statistics & st) const override; void get_unsat_core(expr_ref_vector & r) override; diff --git a/src/solver/combined_solver.cpp b/src/solver/combined_solver.cpp index 53aa56753..34d31ec84 100644 --- a/src/solver/combined_solver.cpp +++ b/src/solver/combined_solver.cpp @@ -394,6 +394,12 @@ public: void user_propagate_clear() override { m_solver2->user_propagate_clear(); } + + void user_propagate_initialize_value(expr* var, expr* value) override { + m_solver1->user_propagate_initialize_value(var, value); + m_solver2->user_propagate_initialize_value(var, value); + } + }; diff --git a/src/solver/simplifier_solver.cpp b/src/solver/simplifier_solver.cpp index ed645dae0..ae1d6b8a2 100644 --- a/src/solver/simplifier_solver.cpp +++ b/src/solver/simplifier_solver.cpp @@ -38,7 +38,6 @@ class simplifier_solver : public solver { model_reconstruction_trail m_reconstruction_trail; bool m_updated = false; dep_expr_state(simplifier_solver& s) :dependent_expr_state(s.m), s(s), m_reconstruction_trail(s.m, m_trail) {} - ~dep_expr_state() override {} unsigned qtail() const override { return s.m_fmls.size(); } dependent_expr const& operator[](unsigned i) override { return s.m_fmls[i]; } void update(unsigned i, dependent_expr const& j) override { @@ -391,6 +390,8 @@ public: void user_propagate_register_expr(expr* e) override { m_preprocess_state.freeze(e); s->user_propagate_register_expr(e); } void user_propagate_register_created(user_propagator::created_eh_t& r) override { s->user_propagate_register_created(r); } void user_propagate_register_decide(user_propagator::decide_eh_t& r) override { s->user_propagate_register_decide(r); } + void user_propagate_initialize_value(expr* var, expr* value) override { m_preprocess_state.freeze(var); s->user_propagate_initialize_value(var, value); } + }; diff --git a/src/solver/slice_solver.cpp b/src/solver/slice_solver.cpp new file mode 100644 index 000000000..7c4e1fb82 --- /dev/null +++ b/src/solver/slice_solver.cpp @@ -0,0 +1,431 @@ +/*++ +Copyright (c) 2023 Microsoft Corporation + +Module Name: + + slice_solver.cpp + +Abstract: + + Implements a solver that slices assertions based on the query. + +Author: + + Nikolaj Bjorner (nbjorner) 2024-10-07 + +--*/ + +#include "solver/solver.h" +#include "solver/slice_solver.h" +#include "ast/for_each_ast.h" +#include "ast/ast_pp.h" +#include "params/solver_params.hpp" + +class slice_solver : public solver { + + struct fml_t { + expr_ref formula; + expr_ref assumption; + bool active; + unsigned level; + }; + ast_manager& m; + solver_ref s; + vector m_assertions; + unsigned_vector m_assertions_lim; + obj_map m_occurs; + ptr_vector m_occurs_trail; + unsigned_vector m_occurs_lim; + obj_hashtable m_used_funs; + ptr_vector m_used_funs_trail; + unsigned_vector m_used_funs_lim; + bool m_has_query = false; + + ast_mark m_mark; + + void add_occurs(unsigned i, expr* e) { + struct visit { + slice_solver& s; + unsigned i; + visit(slice_solver& s, unsigned i):s(s), i(i) {} + + void operator()(func_decl* f) { + if (is_uninterp(f)) { + s.m_occurs.insert_if_not_there(f, unsigned_vector()).push_back(i); + s.m_occurs_trail.push_back(f); + } + } + + void operator()(ast* a) {} + }; + m_mark.reset(); + visit visitor(*this, i); + ptr_buffer args; + + if (m.is_and(e)) + args.append(to_app(e)->get_num_args(), to_app(e)->get_args()); + else + args.push_back(e); + bool has_quantifier = any_of(args, [&](expr* arg) { return is_quantifier(arg); }); + for (expr* arg : args) { + if (is_quantifier(arg)) { + auto q = to_quantifier(arg); + // all symbols in pattern must be present for quantifier to be considered relevant. + for (unsigned j = 0; j < q->get_num_patterns(); ++j) + for_each_ast(visitor, m_mark, q->get_pattern(j)); + } + else if (!has_quantifier) + for_each_ast(visitor, m_mark, arg); + } + } + + void flush() { + for (unsigned idx = 0; idx < m_assertions.size(); ++idx) { + auto& f = m_assertions[idx]; + if (!f.active) { + f.active = true; + m_new_idx.push_back(idx); + } + } + activate_indices(); + m_new_idx.reset(); + } + + unsigned_vector m_new_idx; + void activate(unsigned idx, expr* e) { + struct visit { + slice_solver& s; + visit(slice_solver& s): s(s) {} + void operator()(func_decl* f) { + if (!s.m_used_funs.contains(f)) { + s.m_used_funs_trail.push_back(f); + s.m_used_funs.insert(f); + } + } + void operator()(ast* a) {} + }; + SASSERT(m_new_idx.empty()); + visit visitor(*this); + m_mark.reset(); + for_each_ast(visitor, m_mark, e); + consume_used_funs(); + for (unsigned i = 0; m.inc() && i < m_new_idx.size(); ++i) { + auto& f = m_assertions[m_new_idx[i]]; + expr* e = f.formula; + ptr_buffer args; + if (m.is_and(e)) + args.append(to_app(e)->get_num_args(), to_app(e)->get_args()); + else + args.push_back(e); + + for (expr* arg : args) { + if (is_quantifier(arg)) { + for_each_ast(visitor, m_mark, arg); + consume_used_funs(); + } + } + } + std::sort(m_new_idx.begin(), m_new_idx.end()); + activate_indices(); + m_new_idx.reset(); + + IF_VERBOSE(2, log_active(verbose_stream());); + } + + void log_active(std::ostream& out) { + unsigned num_passive = 0, num_active = 0; + for (auto const& f : m_assertions) + if (f.active) + ++num_active; + else + ++num_passive; + out << "passive " << num_passive << " active " << num_active << "\n"; + } + + unsigned m_qhead = 0; + void consume_used_funs() { + for (; m_qhead < m_used_funs_trail.size(); ++m_qhead) { + func_decl* f = m_used_funs_trail[m_qhead]; + auto* e = m_occurs.find_core(f); + if (!e) + continue; + for (unsigned idx : e->get_data().m_value) { + if (!should_activate(idx)) + continue; + m_new_idx.push_back(idx); + m_assertions[idx].active = true; + } + } + } + + bool should_activate(unsigned idx) { + auto& f = m_assertions[idx]; + return !f.active && should_activate(f.formula.get()); + } + + bool should_activate(expr* f) { + if (is_ground(f)) + return true; + + if (m.is_and(f)) + for (expr* arg : *to_app(f)) + if (is_forall(arg) && should_activate(arg)) + return true; + + if (!is_forall(f)) + return true; + + auto q = to_quantifier(f); + return should_activiate_quantifier(q); + } + + bool should_activiate_quantifier(quantifier* q) { + struct visit { + slice_solver& s; + bool m_all_visited = true; + visit(slice_solver& s) : s(s) {} + void operator()(func_decl* f) { + if (is_uninterp(f)) + m_all_visited &= s.m_used_funs.contains(f); + } + void operator()(ast* a) {} + }; + m_mark.reset(); + visit visitor(*this); + for (unsigned i = 0; i < q->get_num_patterns(); ++i) + for_each_ast(visitor, m_mark, q->get_pattern(i)); + return visitor.m_all_visited; + } + + void assert_expr(fml_t const & f) { + if (f.assumption) + s->assert_expr(f.formula, f.assumption); + else + s->assert_expr(f.formula); + } + + void activate_indices() { + if (m_new_idx.empty()) + return; + unsigned idx = m_new_idx[0]; + auto const& f0 = m_assertions[idx]; + if (f0.level < s->get_scope_level()) { + + // pop to f.level + // add m_new_idx within f.level + // replay push and assertions above f.level + s->pop(s->get_scope_level() - f0.level); + unsigned last_idx = idx; + for (unsigned idx : m_new_idx) { + // add only new assertions within lowest scope level. + auto const& f = m_assertions[idx]; + if (s->get_scope_level() != f.level) + break; + last_idx = idx; + assert_expr(f); + } + for (unsigned i = last_idx + 1; i < m_assertions.size(); ++i) { + // add all active assertions within other scope levels. + auto const& f = m_assertions[i]; + if (f0.level == f.level) + continue; + while (f.level > s->get_scope_level()) + s->push(); + + if (f.active) + assert_expr(f); + } + } + else { + for (unsigned idx : m_new_idx) { + auto const& f = m_assertions[idx]; + while (f.level > s->get_scope_level()) + s->push(); + assert_expr(f); + } + } + } + + bool is_query(expr* a) { + return is_uninterp_const(a) && to_app(a)->get_decl()->get_name() == "@query"; + } + +public: + + slice_solver(solver* s) : + solver(s->get_manager()), + m(s->get_manager()), + s(s) { + } + + void assert_expr_core2(expr* t, expr* a) override { + if (!a) + assert_expr_core(t); + else { + unsigned i = m_assertions.size(); + m_assertions.push_back({expr_ref(t, m), expr_ref(a, m), false, m_assertions_lim.size()}); + add_occurs(i, t); + add_occurs(i, a); + if (is_query(a)) { + activate(i, t); + m_has_query = true; + } + } + } + + void assert_expr_core(expr* t) override { + unsigned i = m_assertions.size(); + m_assertions.push_back({expr_ref(t, m), expr_ref(nullptr, m), false, m_assertions_lim.size()}); + add_occurs(i, t); + } + + void push() override { + m_assertions_lim.push_back(m_assertions.size()); + m_occurs_lim.push_back(m_occurs_trail.size()); + m_used_funs_lim.push_back(m_used_funs_trail.size()); + } + + void pop(unsigned n) override { + unsigned old_sz = m_assertions_lim[m_assertions_lim.size() - n]; + for (unsigned i = m_assertions.size(); i-- > old_sz; ) { + auto const& f = m_assertions[i]; + if (f.level < s->get_scope_level()) + s->pop(s->get_scope_level() - f.level); + } + m_assertions_lim.shrink(m_assertions_lim.size() - n); + m_assertions.shrink(old_sz); + old_sz = m_occurs_lim[m_occurs_lim.size() - n]; + for (unsigned i = m_occurs_trail.size(); i-- > old_sz; ) { + auto f = m_occurs_trail[i]; + m_occurs[f].pop_back(); + } + m_occurs_lim.shrink(m_occurs_lim.size() - n); + m_occurs_trail.shrink(old_sz); + + old_sz = m_used_funs_lim[m_used_funs_lim.size() - n]; + for (unsigned i = m_used_funs_trail.size(); i-- > old_sz; ) { + auto f = m_used_funs_trail[i]; + m_used_funs.erase(f); + } + m_used_funs_lim.shrink(m_used_funs_lim.size() - n); + m_used_funs_trail.shrink(old_sz); + m_qhead = 0; + m_has_query = false; + } + + lbool check_sat_core(unsigned num_assumptions, expr* const* assumptions) override { + if (!m_has_query || num_assumptions > 0) + flush(); + return s->check_sat_core(num_assumptions, assumptions); + } + + void collect_statistics(statistics& st) const override { s->collect_statistics(st); } + + void get_model_core(model_ref& mdl) override { s->get_model_core(mdl); } + + proof* get_proof_core() override { return s->get_proof(); } + + solver* translate(ast_manager& m, params_ref const& p) override { + solver* new_s = s->translate(m, p); + solver* new_slice = alloc(slice_solver, new_s); + unsigned level = 0; + ast_translation tr(get_manager(), m); + for (auto & f : m_assertions) { + while (f.level > level) { + new_slice->push(); + ++level; + } + new_slice->assert_expr(tr(f.formula.get()), tr(f.assumption.get())); + } + return new_slice; + } + + void updt_params(params_ref const& p) override { s->updt_params(p); } + + model_converter_ref get_model_converter() const override { return s->get_model_converter(); } + + unsigned get_num_assertions() const override { return s->get_num_assertions(); } + expr* get_assertion(unsigned idx) const override { return s->get_assertion(idx); } + std::string reason_unknown() const override { return s->reason_unknown(); } + void set_reason_unknown(char const* msg) override { s->set_reason_unknown(msg); } + void get_labels(svector& r) override { s->get_labels(r); } + void get_unsat_core(expr_ref_vector& r) override { s->get_unsat_core(r); } + ast_manager& get_manager() const override { return s->get_manager(); } + void reset_params(params_ref const& p) override { s->reset_params(p); } + params_ref const& get_params() const override { return s->get_params(); } + void collect_param_descrs(param_descrs& r) override { s->collect_param_descrs(r); } + void push_params() override { s->push_params(); } + void pop_params() override { s->pop_params(); } + void set_produce_models(bool f) override { s->set_produce_models(f); } + void set_phase(expr* e) override { s->set_phase(e); } + void move_to_front(expr* e) override { s->move_to_front(e); } + phase* get_phase() override { return s->get_phase(); } + void set_phase(phase* p) override { s->set_phase(p); } + unsigned get_num_assumptions() const override { return s->get_num_assumptions(); } + expr* get_assumption(unsigned idx) const override { return s->get_assumption(idx); } + unsigned get_scope_level() const override { return s->get_scope_level(); } + void set_progress_callback(progress_callback* callback) override { s->set_progress_callback(callback); } + + lbool get_consequences(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences) override { + flush(); + return s->get_consequences(asms, vars, consequences); + } + + lbool check_sat_cc(expr_ref_vector const& cube, vector const& clauses) override { + flush(); + return check_sat_cc(cube, clauses); + } + + lbool find_mutexes(expr_ref_vector const& vars, vector& mutexes) override { + flush(); + return s->find_mutexes(vars, mutexes); + } + + lbool preferred_sat(expr_ref_vector const& asms, vector& cores) override { + flush(); + return s->preferred_sat(asms, cores); + } + + expr_ref_vector cube(expr_ref_vector& vars, unsigned backtrack_level) override { + flush(); + return s->cube(vars, backtrack_level); + } + + expr* congruence_root(expr* e) override { return s->congruence_root(e); } + expr* congruence_next(expr* e) override { return s->congruence_next(e); } + std::ostream& display(std::ostream& out, unsigned n, expr* const* assumptions) const override { + return s->display(out, n, assumptions); + } + void get_units_core(expr_ref_vector& units) override { s->get_units_core(units); } + expr_ref_vector get_trail(unsigned max_level) override { return s->get_trail(max_level); } + void get_levels(ptr_vector const& vars, unsigned_vector& depth) override { s->get_levels(vars, depth); } + + void register_on_clause(void* ctx, user_propagator::on_clause_eh_t& on_clause) override { + s->register_on_clause(ctx, on_clause); + } + + void user_propagate_init( + void* ctx, + user_propagator::push_eh_t& push_eh, + user_propagator::pop_eh_t& pop_eh, + user_propagator::fresh_eh_t& fresh_eh) override { + s->user_propagate_init(ctx, push_eh, pop_eh, fresh_eh); + } + void user_propagate_register_fixed(user_propagator::fixed_eh_t& fixed_eh) override { s->user_propagate_register_fixed(fixed_eh); } + void user_propagate_register_final(user_propagator::final_eh_t& final_eh) override { s->user_propagate_register_final(final_eh); } + void user_propagate_register_eq(user_propagator::eq_eh_t& eq_eh) override { s->user_propagate_register_eq(eq_eh); } + void user_propagate_register_diseq(user_propagator::eq_eh_t& diseq_eh) override { s->user_propagate_register_diseq(diseq_eh); } + void user_propagate_register_expr(expr* e) override { s->user_propagate_register_expr(e); } + void user_propagate_register_created(user_propagator::created_eh_t& r) override { s->user_propagate_register_created(r); } + void user_propagate_register_decide(user_propagator::decide_eh_t& r) override { s->user_propagate_register_decide(r); } + void user_propagate_initialize_value(expr* var, expr* value) override { s->user_propagate_initialize_value(var, value); } +}; + +solver * mk_slice_solver(solver * s) { + solver_params sp(s->get_params()); + if (sp.slice()) + return alloc(slice_solver, s); + else + return s; +} + diff --git a/src/solver/slice_solver.h b/src/solver/slice_solver.h new file mode 100644 index 000000000..78386ce15 --- /dev/null +++ b/src/solver/slice_solver.h @@ -0,0 +1,25 @@ +/*++ +Copyright (c) 2023 Microsoft Corporation + +Module Name: + + slice_solver.h + +Abstract: + + Implements a solver that slices assertions based on the query. + +Author: + + Nikolaj Bjorner (nbjorner) 2024-10-07 + +--*/ +#pragma once + +#include "util/params.h" + +class solver; +class solver_factory; + +solver * mk_slice_solver(solver * s); + diff --git a/src/solver/solver2tactic.cpp b/src/solver/solver2tactic.cpp index b8e3dd37a..add55c628 100644 --- a/src/solver/solver2tactic.cpp +++ b/src/solver/solver2tactic.cpp @@ -189,6 +189,11 @@ public: } char const* name() const override { return "solver2tactic"; } + + + void user_propagate_initialize_value(expr* var, expr* value) override { + m_solver->user_propagate_initialize_value(var, value); + } }; tactic* mk_solver2tactic(solver* s) { return alloc(solver2tactic, s); } diff --git a/src/solver/solver_na2as.cpp b/src/solver/solver_na2as.cpp index 605a32ae1..31c4ad9f3 100644 --- a/src/solver/solver_na2as.cpp +++ b/src/solver/solver_na2as.cpp @@ -28,8 +28,6 @@ solver_na2as::solver_na2as(ast_manager & m): m_assumptions(m) { } -solver_na2as::~solver_na2as() {} - void solver_na2as::assert_expr_core2(expr * t, expr * a) { if (a == nullptr) { assert_expr_core(t); diff --git a/src/solver/solver_na2as.h b/src/solver/solver_na2as.h index 81a58fb39..fd0a7dc5e 100644 --- a/src/solver/solver_na2as.h +++ b/src/solver/solver_na2as.h @@ -30,7 +30,6 @@ class solver_na2as : public solver { void restore_assumptions(unsigned old_sz); public: solver_na2as(ast_manager & m); - ~solver_na2as() override; void assert_expr_core2(expr * t, expr * a) override; diff --git a/src/solver/tactic2solver.cpp b/src/solver/tactic2solver.cpp index 861a83185..cdabecb27 100644 --- a/src/solver/tactic2solver.cpp +++ b/src/solver/tactic2solver.cpp @@ -119,6 +119,10 @@ public: void user_propagate_register_expr(expr* e) override { m_tactic->user_propagate_register_expr(e); } + + void user_propagate_initialize_value(expr* var, expr* value) override { + m_tactic->user_propagate_initialize_value(var, value); + } void user_propagate_register_created(user_propagator::created_eh_t& created_eh) override { m_tactic->user_propagate_register_created(created_eh); diff --git a/src/tactic/aig/aig.cpp b/src/tactic/aig/aig.cpp index 433120b48..e59982969 100644 --- a/src/tactic/aig/aig.cpp +++ b/src/tactic/aig/aig.cpp @@ -50,7 +50,6 @@ struct aig { unsigned m_ref_count; aig_lit m_children[2]; unsigned m_mark:1; - aig() {} }; #if Z3DEBUG diff --git a/src/tactic/arith/fix_dl_var_tactic.cpp b/src/tactic/arith/fix_dl_var_tactic.cpp index 13479e1bf..c96ca749b 100644 --- a/src/tactic/arith/fix_dl_var_tactic.cpp +++ b/src/tactic/arith/fix_dl_var_tactic.cpp @@ -35,7 +35,7 @@ class fix_dl_var_tactic : public tactic { struct failed {}; ast_manager & m; arith_util & m_util; - expr_fast_mark1 * m_visited; + expr_fast_mark1 * m_visited = nullptr; ptr_vector m_todo; obj_map m_occs; obj_map m_non_nested_occs; @@ -215,7 +215,7 @@ class fix_dl_var_tactic : public tactic { app * operator()(goal const & g) { try { expr_fast_mark1 visited; - m_visited = &visited; + flet _visited(m_visited, &visited); unsigned sz = g.size(); for (unsigned i = 0; i < sz; i++) { process(g.form(i)); diff --git a/src/tactic/arith/nla2bv_tactic.cpp b/src/tactic/arith/nla2bv_tactic.cpp index c791841ec..31ca836ac 100644 --- a/src/tactic/arith/nla2bv_tactic.cpp +++ b/src/tactic/arith/nla2bv_tactic.cpp @@ -79,8 +79,6 @@ class nla2bv_tactic : public tactic { m_default_bv_size = m_num_bits = p.get_uint("nla2bv_bv_size", 4); } - ~imp() {} - void updt_params(params_ref const& p) {} void operator()(goal & g, model_converter_ref & mc) { diff --git a/src/tactic/bv/bit_blaster_model_converter.cpp b/src/tactic/bv/bit_blaster_model_converter.cpp index 5958a9d38..ee48f48a1 100644 --- a/src/tactic/bv/bit_blaster_model_converter.cpp +++ b/src/tactic/bv/bit_blaster_model_converter.cpp @@ -222,6 +222,34 @@ struct bit_blaster_model_converter : public model_converter { // no-op } + void convert_initialize_value(vector>& var2value) override { + if (m_vars.empty() || var2value.empty()) + return; + rational r; + bv_util util(m()); + for (unsigned j = 0; j < var2value.size(); ++j) { + auto& [var, value] = var2value[j]; + if (!is_uninterp_const(var)) + continue; + if (!util.is_numeral(value, r)) + continue; + unsigned sz = m_vars.size(); + for (unsigned i = 0; i < sz; i++) { + if (m_vars.get(i) != to_app(var)->get_decl()) + continue; + unsigned k = 0; + expr_ref bit_k(m()); + for (auto arg : *to_app(m_bits.get(i))) { + bit_k = m().mk_bool_val(r.get_bit(k)); + var2value.push_back({ expr_ref(arg, m()), bit_k }); + ++k; + } + var2value[i] = var2value.back(); + var2value.pop_back(); + } + } + } + protected: bit_blaster_model_converter(ast_manager & m):m_vars(m), m_bits(m), m_newbits(m) { } public: diff --git a/src/tactic/bv/bv_bound_chk_tactic.cpp b/src/tactic/bv/bv_bound_chk_tactic.cpp index f6db3c30e..93491f7b2 100644 --- a/src/tactic/bv/bv_bound_chk_tactic.cpp +++ b/src/tactic/bv/bv_bound_chk_tactic.cpp @@ -41,8 +41,6 @@ struct bv_bound_chk_rewriter_cfg : public default_rewriter_cfg { bv_bound_chk_rewriter_cfg(ast_manager & m, bv_bound_chk_stats& stats) : m_m(m), m_b_rw(m), m_stats(stats) {} - ~bv_bound_chk_rewriter_cfg() {} - void updt_params(params_ref const & _p) { rewriter_params p(_p); m_bv_ineq_consistency_test_max = p.bv_ineq_consistency_test_max(); @@ -146,8 +144,6 @@ public: imp(ast_manager & m, params_ref const & p, bv_bound_chk_stats& stats) : m_rw(m, p, stats) { } - virtual ~imp() = default; - ast_manager& m() { return m_rw.m(); } void operator()(goal_ref const & g) { @@ -164,7 +160,7 @@ public: m_rw.m_cfg.cleanup(); } - virtual void updt_params(params_ref const & p) { + void updt_params(params_ref const & p) { m_rw.updt_params(p); } diff --git a/src/tactic/bv/bv_bounds_tactic.cpp b/src/tactic/bv/bv_bounds_tactic.cpp index 5f856800e..6ddc49c7f 100644 --- a/src/tactic/bv/bv_bounds_tactic.cpp +++ b/src/tactic/bv/bv_bounds_tactic.cpp @@ -48,8 +48,6 @@ namespace { r.insert("propagate-eq", CPK_BOOL, "propagate equalities from inequalities", "false"); } - ~bv_bounds_simplifier() override {} - bool assert_expr(expr * t, bool sign) override { return assert_expr_core(t, sign); } diff --git a/src/tactic/core/ctx_simplify_tactic.cpp b/src/tactic/core/ctx_simplify_tactic.cpp index aa4358e9c..e3cd7893a 100644 --- a/src/tactic/core/ctx_simplify_tactic.cpp +++ b/src/tactic/core/ctx_simplify_tactic.cpp @@ -144,9 +144,8 @@ struct ctx_simplify_tactic::imp { }; struct cache_cell { - expr * m_from; - cached_result * m_result; - cache_cell():m_from(nullptr), m_result(nullptr) {} + expr * m_from = nullptr; + cached_result * m_result = nullptr; }; ast_manager & m; diff --git a/src/tactic/core/injectivity_tactic.cpp b/src/tactic/core/injectivity_tactic.cpp index e4071628c..640c41277 100644 --- a/src/tactic/core/injectivity_tactic.cpp +++ b/src/tactic/core/injectivity_tactic.cpp @@ -162,9 +162,6 @@ class injectivity_tactic : public tactic { rewriter_eq_cfg(ast_manager & m, InjHelper & map, params_ref const & p) : m_manager(m), inj_map(map) { } - ~rewriter_eq_cfg() { - } - void cleanup_buffers() { } diff --git a/src/tactic/core/pb_preprocess_tactic.cpp b/src/tactic/core/pb_preprocess_tactic.cpp index 05ed6eee9..2d82a12a1 100644 --- a/src/tactic/core/pb_preprocess_tactic.cpp +++ b/src/tactic/core/pb_preprocess_tactic.cpp @@ -25,7 +25,7 @@ Author: #include "ast/ast_pp.h" class pb_preprocess_tactic : public tactic { - struct rec { unsigned_vector pos, neg; rec() { } }; + struct rec { unsigned_vector pos, neg; }; typedef obj_map var_map; ast_manager& m; expr_ref_vector m_trail; diff --git a/src/tactic/core/simplify_tactic.cpp b/src/tactic/core/simplify_tactic.cpp index f05b4c4fc..6e2068e26 100644 --- a/src/tactic/core/simplify_tactic.cpp +++ b/src/tactic/core/simplify_tactic.cpp @@ -31,9 +31,6 @@ struct simplify_tactic::imp { m_num_steps(0) { } - ~imp() { - } - ast_manager & m() const { return m_manager; } @@ -98,6 +95,7 @@ void simplify_tactic::operator()(goal_ref const & in, (*m_imp)(*(in.get())); in->inc_depth(); result.push_back(in.get()); + m_clean = false; } catch (rewriter_exception & ex) { throw tactic_exception(ex.msg()); @@ -106,10 +104,13 @@ void simplify_tactic::operator()(goal_ref const & in, void simplify_tactic::cleanup() { + if (m_clean) + return; ast_manager & m = m_imp->m(); params_ref p = std::move(m_params); m_imp->~imp(); new (m_imp) imp(m, p); + m_clean = true; } void simplify_tactic::collect_statistics(statistics& st) const { diff --git a/src/tactic/core/simplify_tactic.h b/src/tactic/core/simplify_tactic.h index 7baabb8d6..af0806162 100644 --- a/src/tactic/core/simplify_tactic.h +++ b/src/tactic/core/simplify_tactic.h @@ -69,6 +69,7 @@ There are several options to control its behavior. #include "tactic/tactical.h" class simplify_tactic : public tactic { + bool m_clean = true; struct imp; imp * m_imp; params_ref m_params; diff --git a/src/tactic/core/symmetry_reduce_tactic.cpp b/src/tactic/core/symmetry_reduce_tactic.cpp index 9ad12d504..c5cba0b9a 100644 --- a/src/tactic/core/symmetry_reduce_tactic.cpp +++ b/src/tactic/core/symmetry_reduce_tactic.cpp @@ -117,8 +117,6 @@ public: m_replace = mk_default_expr_replacer(m, false); } - ~imp() {} - void operator()(goal & g) { if (g.inconsistent()) return; @@ -202,10 +200,10 @@ private: // a |-> c1, b |-> c2 |-> c // struct u_pair { - unsigned m_first; - unsigned m_second; + unsigned m_first = 0; + unsigned m_second = 0; u_pair(unsigned f, unsigned s) : m_first(f), m_second(s) {} - u_pair(): m_first(0), m_second(0) {} + u_pair() = default; struct hash { unsigned operator()(u_pair const& p) const { @@ -324,8 +322,6 @@ private: class parents { app_parents m_use_funs; public: - parents() {} - app_parents const& get_parents() { return m_use_funs; } void operator()(app* n) { diff --git a/src/tactic/fd_solver/bounded_int2bv_solver.cpp b/src/tactic/fd_solver/bounded_int2bv_solver.cpp index 317286e1e..45b444fe9 100644 --- a/src/tactic/fd_solver/bounded_int2bv_solver.cpp +++ b/src/tactic/fd_solver/bounded_int2bv_solver.cpp @@ -375,6 +375,9 @@ private: return m_assertions.get(idx); } } + + void user_propagate_initialize_value(expr* var, expr* value) override { + } }; solver * mk_bounded_int2bv_solver(ast_manager & m, params_ref const & p, solver* s) { diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index 7f145b614..fc69b45ae 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -35,20 +35,21 @@ Notes: tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), - cond(mk_and(mk_is_propositional_probe(), mk_not(mk_produce_proofs_probe())), mk_fd_tactic(m, p), - cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), - cond(mk_is_qfaufbv_probe(), mk_qfaufbv_tactic(m), - cond(mk_is_qflia_probe(), mk_qflia_tactic(m), - cond(mk_is_qfauflia_probe(), mk_qfauflia_tactic(m), - cond(mk_is_qflra_probe(), mk_qflra_tactic(m), - cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m), - cond(mk_is_qfnia_probe(), mk_qfnia_tactic(m), - cond(mk_is_lira_probe(), mk_lira_tactic(m, p), - cond(mk_is_nra_probe(), mk_nra_tactic(m), - cond(mk_is_qffp_probe(), mk_qffp_tactic(m, p), - cond(mk_is_qffplra_probe(), mk_qffplra_tactic(m, p), + cond(mk_and(mk_is_propositional_probe(), mk_not(mk_produce_proofs_probe())), + mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_fd_tactic(m, p); }), + cond(mk_is_qfbv_probe(), mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_qfbv_tactic(m); }), + cond(mk_is_qfaufbv_probe(), mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_qfaufbv_tactic(m); }), + cond(mk_is_qflia_probe(), mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_qflia_tactic(m); }), + cond(mk_is_qfauflia_probe(), mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_qfauflia_tactic(m); }), + cond(mk_is_qflra_probe(), mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_qflra_tactic(m); }), + cond(mk_is_qfnra_probe(), mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_qfnra_tactic(m); }), + cond(mk_is_qfnia_probe(), mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_qfnia_tactic(m); }), + cond(mk_is_lira_probe(), mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_lira_tactic(m, p); }), + cond(mk_is_nra_probe(), mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_nra_tactic(m); }), + cond(mk_is_qffp_probe(), mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_qffp_tactic(m, p); }), + cond(mk_is_qffplra_probe(), mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_qffplra_tactic(m, p); }), //cond(mk_is_qfufnra_probe(), mk_qfufnra_tactic(m, p), - and_then(mk_preamble_tactic(m), mk_smt_tactic(m))))))))))))))), + and_then(mk_preamble_tactic(m), mk_lazy_tactic(m, p, [&](auto& m, auto const& p) { return mk_smt_tactic(m);}))))))))))))))), p); return st; } diff --git a/src/tactic/probe.h b/src/tactic/probe.h index 4d1af66a8..452f2cb70 100644 --- a/src/tactic/probe.h +++ b/src/tactic/probe.h @@ -40,10 +40,9 @@ public: }; private: - unsigned m_ref_count; + unsigned m_ref_count = 0; public: - probe():m_ref_count(0) {} virtual ~probe() = default; void inc_ref() { ++m_ref_count; } diff --git a/src/tactic/smtlogics/qfnia_tactic.cpp b/src/tactic/smtlogics/qfnia_tactic.cpp index 0dad56a19..25dc34d9c 100644 --- a/src/tactic/smtlogics/qfnia_tactic.cpp +++ b/src/tactic/smtlogics/qfnia_tactic.cpp @@ -45,6 +45,7 @@ static tactic * mk_qfnia_bv_solver(ast_manager & m, params_ref const & p_ref) { params_ref mem_p = p; mem_p.set_uint("max_memory", 100); + mem_p.set_uint("max_conflicts", 500); tactic * r = using_params(and_then(mk_simplify_tactic(m), @@ -52,7 +53,7 @@ static tactic * mk_qfnia_bv_solver(ast_manager & m, params_ref const & p_ref) { using_params(mk_simplify_tactic(m), simp2_p), mk_max_bv_sharing_tactic(m), using_params(mk_bit_blaster_tactic(m), mem_p), - mk_sat_tactic(m)), + mk_sat_tactic(m, mem_p)), p); return r; } diff --git a/src/tactic/smtlogics/qfnra_tactic.cpp b/src/tactic/smtlogics/qfnra_tactic.cpp index b9fec4366..79e0a4b39 100644 --- a/src/tactic/smtlogics/qfnra_tactic.cpp +++ b/src/tactic/smtlogics/qfnra_tactic.cpp @@ -23,33 +23,307 @@ Notes: #include "nlsat/tactic/qfnra_nlsat_tactic.h" #include "tactic/smtlogics/smt_tactic.h" -static tactic * mk_qfnra_sat_solver(ast_manager& m, params_ref const& p, unsigned bv_size) { - params_ref nra2sat_p = p; - nra2sat_p.set_uint("nla2bv_max_bv_size", p.get_uint("nla2bv_max_bv_size", bv_size)); - - return and_then(mk_nla2bv_tactic(m, nra2sat_p), - mk_smt_tactic(m), - mk_fail_if_undecided_tactic()); +#include "tactic/smtlogics/qflra_tactic.h" + + +tactic * mk_multilinear_ls_tactic(ast_manager & m, params_ref const & p, unsigned ls_time = 60) { + params_ref p_mls = p; + p_mls.set_bool("use_ls", true); + p_mls.set_uint("ls_time",ls_time); + return using_params(mk_smt_tactic(m), p_mls); +} + +tactic * mk_qfnra_very_small_solver(ast_manager& m, params_ref const& p) { + ptr_vector ts; + { + params_ref p_sc = p; + p_sc.set_bool("simple_check", true); + // p_sc.set_uint("seed", 997); + ts.push_back(try_for(and_then(mk_qfnra_nlsat_tactic(m, p_sc), mk_fail_if_undecided_tactic()), 10 * 1000)); + } + { + params_ref p_heuristic = p; + // p_heuristic.set_uint("seed", 233); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_heuristic), 4 * 1000)); + + params_ref p_order_4 = p; + p_order_4.set_uint("variable_ordering_strategy", 4); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_4), 4 * 1000)); + + params_ref p_order_3 = p; + p_order_3.set_uint("variable_ordering_strategy", 3); + // p_order_3.set_uint("seed", 17); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_3), 6 * 1000)); + + params_ref p_order_1 = p; + p_order_1.set_uint("variable_ordering_strategy", 1); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_1), 8 * 1000)); + + params_ref p_order_5 = p; + p_order_5.set_uint("variable_ordering_strategy", 5); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_5), 8 * 1000)); + + params_ref p_order_2 = p; + p_order_2.set_uint("variable_ordering_strategy", 2); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_2), 10 * 1000)); + } + { + ts.push_back(mk_multilinear_ls_tactic(m, p, 60)); + } + { + params_ref p_l = p; + p_l.set_bool("arith.greatest_error_pivot", true); + ts.push_back(and_then(try_for(using_params(mk_smt_tactic(m), p_l), 300 * 1000), mk_fail_if_undecided_tactic())); + } + for (unsigned i = 0; i < 200; ++i) { // 3s * 200 = 600s + params_ref p_i = p; + p_i.set_uint("seed", i); + p_i.set_bool("shuffle_vars", true); + // if ((i & 1) == 0) + // p_i.set_bool("randomize", false); + ts.push_back(mk_lazy_tactic(m, p_i, [&](ast_manager& m, params_ref const& p) { return try_for(mk_qfnra_nlsat_tactic(m, p), 3 * 1000); })); + } + { + ts.push_back(mk_qfnra_nlsat_tactic(m, p)); + } + return or_else(ts.size(), ts.data()); +} + +tactic * mk_qfnra_small_solver(ast_manager& m, params_ref const& p) { + ptr_vector ts; + { + params_ref p_sc = p; + p_sc.set_bool("simple_check", true); + // p_sc.set_uint("seed", 997); + ts.push_back(try_for(and_then(mk_qfnra_nlsat_tactic(m, p_sc), mk_fail_if_undecided_tactic()), 20 * 1000)); + } + { + params_ref p_heuristic = p; + // p_heuristic.set_uint("seed", 233); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_heuristic), 5 * 1000)); + + params_ref p_order_4 = p; + p_order_4.set_uint("variable_ordering_strategy", 4); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_4), 5 * 1000)); + + params_ref p_order_3 = p; + p_order_3.set_uint("variable_ordering_strategy", 3); + // p_order_3.set_uint("seed", 17); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_3), 10 * 1000)); + + params_ref p_order_1 = p; + p_order_1.set_uint("variable_ordering_strategy", 1); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_1), 15 * 1000)); + + + params_ref p_order_5 = p; + p_order_5.set_uint("variable_ordering_strategy", 5); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_5), 15 * 1000)); + + + params_ref p_order_2 = p; + p_order_2.set_uint("variable_ordering_strategy", 2); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_2), 20 * 1000)); + } + { + ts.push_back(mk_multilinear_ls_tactic(m, p, 70)); + } + { + params_ref p_l = p; + p_l.set_bool("arith.greatest_error_pivot", true); + ts.push_back(and_then(try_for(using_params(mk_smt_tactic(m), p_l), 350 * 1000), mk_fail_if_undecided_tactic())); + } + for (unsigned i = 0; i < 100; ++i) { // 5s * 100 = 500s + params_ref p_i = p; + p_i.set_uint("seed", i); + p_i.set_bool("shuffle_vars", true); + // if ((i & 1) == 0) + // p_i.set_bool("randomize", false); + ts.push_back(mk_lazy_tactic(m, p_i, [&](ast_manager& m, params_ref const& p) { return try_for(mk_qfnra_nlsat_tactic(m, p), 5 * 1000); })); + } + { + ts.push_back(mk_qfnra_nlsat_tactic(m, p)); + } + return or_else(ts.size(), ts.data()); +} + +tactic * mk_qfnra_middle_solver(ast_manager& m, params_ref const& p) { + ptr_vector ts; + { + params_ref p_sc = p; + p_sc.set_bool("simple_check", true); + ts.push_back(try_for(and_then(mk_qfnra_nlsat_tactic(m, p_sc), mk_fail_if_undecided_tactic()), 30 * 1000)); + } + { + params_ref p_heuristic = p; + // p_heuristic.set_uint("seed", 233); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_heuristic), 10 * 1000)); + + + params_ref p_order_4 = p; + p_order_4.set_uint("variable_ordering_strategy", 4); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_4), 15 * 1000)); + + + params_ref p_order_3 = p; + p_order_3.set_uint("variable_ordering_strategy", 3); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_3), 15 * 1000)); + + params_ref p_order_1 = p; + p_order_1.set_uint("variable_ordering_strategy", 1); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_1), 20 * 1000)); + + + params_ref p_order_5 = p; + p_order_5.set_uint("variable_ordering_strategy", 5); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_5), 20 * 1000)); + + + params_ref p_order_2 = p; + p_order_2.set_uint("variable_ordering_strategy", 2); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_2), 25 * 1000)); + } + { + ts.push_back(mk_multilinear_ls_tactic(m, p, 80)); + } + { + params_ref p_l = p; + p_l.set_bool("arith.greatest_error_pivot", true); + ts.push_back(and_then(try_for(using_params(mk_smt_tactic(m), p_l), 375 * 1000), mk_fail_if_undecided_tactic())); + } + for (unsigned i = 0; i < 40; ++i) { // 10s * 40 = 400s + params_ref p_i = p; + p_i.set_uint("seed", i); + p_i.set_bool("shuffle_vars", true); + // if ((i & 1) == 0) + // p_i.set_bool("randomize", false); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_i), 10 * 1000)); + } + { + ts.push_back(mk_qfnra_nlsat_tactic(m, p)); + } + return or_else(ts.size(), ts.data()); +} + +tactic * mk_qfnra_large_solver(ast_manager& m, params_ref const& p) { + ptr_vector ts; + { + params_ref p_sc = p; + p_sc.set_bool("simple_check", true); + ts.push_back(try_for(and_then(mk_qfnra_nlsat_tactic(m, p_sc), mk_fail_if_undecided_tactic()), 50 * 1000)); + } + { + + params_ref p_order_4 = p; + p_order_4.set_uint("variable_ordering_strategy", 4); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_4), 15 * 1000)); + + + params_ref p_order_3 = p; + p_order_3.set_uint("variable_ordering_strategy", 3); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_3), 30 * 1000)); + + params_ref p_order_1 = p; + p_order_1.set_uint("variable_ordering_strategy", 1); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_1), 40 * 1000)); + + + params_ref p_order_5 = p; + p_order_5.set_uint("variable_ordering_strategy", 5); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_5), 40 * 1000)); + + + params_ref p_order_2 = p; + p_order_2.set_uint("variable_ordering_strategy", 2); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_2), 50 * 1000)); + } + { + ts.push_back(mk_multilinear_ls_tactic(m, p, 90)); + } + { + params_ref p_l = p; + p_l.set_bool("arith.greatest_error_pivot", true); + ts.push_back(and_then(try_for(using_params(mk_smt_tactic(m), p_l), 400 * 1000), mk_fail_if_undecided_tactic())); + } + for (unsigned i = 0; i < 10; ++i) { // 20s * 10 = 200s + params_ref p_i = p; + p_i.set_uint("seed", i); + p_i.set_bool("shuffle_vars", true); + // if ((i & 1) == 0) + // p_i.set_bool("randomize", false); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_i), 20 * 1000)); + } + { + ts.push_back(mk_qfnra_nlsat_tactic(m, p)); + } + return or_else(ts.size(), ts.data()); +} + +tactic * mk_qfnra_very_large_solver(ast_manager& m, params_ref const& p) { + ptr_vector ts; + { + params_ref p_sc = p; + p_sc.set_bool("simple_check", true); + ts.push_back(try_for(and_then(mk_qfnra_nlsat_tactic(m, p_sc), mk_fail_if_undecided_tactic()), 100 * 1000)); + } + { + params_ref p_order_1 = p; + p_order_1.set_uint("variable_ordering_strategy", 1); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_1), 80 * 1000)); + + + params_ref p_order_5 = p; + p_order_5.set_uint("variable_ordering_strategy", 5); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_5), 80 * 1000)); + + + params_ref p_order_2 = p; + p_order_2.set_uint("variable_ordering_strategy", 2); + ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_2), 100 * 1000)); + } + { + ts.push_back(mk_multilinear_ls_tactic(m, p, 100)); + } + { + params_ref p_l = p; + p_l.set_bool("arith.greatest_error_pivot", true); + ts.push_back(and_then(try_for(using_params(mk_smt_tactic(m), p_l), 425 * 1000), mk_fail_if_undecided_tactic())); + } + { + ts.push_back(mk_qfnra_nlsat_tactic(m, p)); + } + return or_else(ts.size(), ts.data()); +} + +const double VERY_SMALL_THRESHOLD = 30.0; +const double SMALL_THRESHOLD = 80.0; +const double MIDDLE_THRESHOLD = 300.0; +const double LARGE_THRESHOLD = 600.0; +tactic * mk_qfnra_mixed_solver(ast_manager& m, params_ref const& p) { + auto very_small_t = mk_lazy_tactic(m, p, [&](ast_manager& m, params_ref const& p) {return mk_qfnra_very_small_solver(m, p); }); + auto small_t = mk_lazy_tactic(m, p, [&](ast_manager& m, params_ref const& p) {return mk_qfnra_small_solver(m, p); }); + auto middle_t = mk_lazy_tactic(m, p, [&](ast_manager& m, params_ref const& p) {return mk_qfnra_middle_solver(m, p); }); + auto large_t = mk_lazy_tactic(m, p, [&](ast_manager& m, params_ref const& p) {return mk_qfnra_large_solver(m, p); }); + auto very_large_t = mk_lazy_tactic(m, p, [&](ast_manager& m, params_ref const& p) {return mk_qfnra_very_large_solver(m, p); }); + return cond(mk_lt(mk_memory_probe(), mk_const_probe(VERY_SMALL_THRESHOLD)), + very_small_t, + cond(mk_lt(mk_memory_probe(), mk_const_probe(SMALL_THRESHOLD)), + small_t, + cond(mk_lt(mk_memory_probe(), mk_const_probe(MIDDLE_THRESHOLD)), + middle_t, + cond(mk_lt(mk_memory_probe(), mk_const_probe(LARGE_THRESHOLD)), + large_t, + very_large_t + ) + ) + ) + ); } tactic * mk_qfnra_tactic(ast_manager & m, params_ref const& p) { - params_ref p0 = p; - p0.set_bool("inline_vars", true); - params_ref p1 = p; - p1.set_uint("seed", 11); - p1.set_bool("factor", false); - params_ref p2 = p; - p2.set_uint("seed", 13); - p2.set_bool("factor", false); return and_then(mk_simplify_tactic(m, p), mk_propagate_values_tactic(m, p), - or_else(try_for(mk_qfnra_nlsat_tactic(m, p0), 5000), - try_for(mk_qfnra_nlsat_tactic(m, p1), 10000), - mk_qfnra_sat_solver(m, p, 4), - and_then(try_for(mk_smt_tactic(m), 5000), mk_fail_if_undecided_tactic()), - mk_qfnra_sat_solver(m, p, 6), - mk_qfnra_nlsat_tactic(m, p2))); + mk_qfnra_mixed_solver(m, p) + ); } - - diff --git a/src/tactic/smtlogics/qfnra_tactic.h b/src/tactic/smtlogics/qfnra_tactic.h index 09a5d0480..344ea3f36 100644 --- a/src/tactic/smtlogics/qfnra_tactic.h +++ b/src/tactic/smtlogics/qfnra_tactic.h @@ -12,7 +12,7 @@ Abstract: Author: Leonardo (leonardo) 2012-02-28 - + Mengyu Zhao (Linxi) and Shaowei Cai, ported from https://github.com/hybridSMT/hybridSMT.git Notes: --*/ diff --git a/src/tactic/tactic.cpp b/src/tactic/tactic.cpp index 179a42ab8..36dc5d4d0 100644 --- a/src/tactic/tactic.cpp +++ b/src/tactic/tactic.cpp @@ -95,6 +95,37 @@ tactic * mk_skip_tactic() { return alloc(skip_tactic); } +class lazy_tactic : public tactic { + ast_manager& m; + params_ref p; + std::function m_mk_tactic; + tactic* m_tactic = nullptr; + void ensure_tactic() { if (!m_tactic) m_tactic = m_mk_tactic(m, p); } +public: + lazy_tactic(ast_manager& m, params_ref const& p, std::function mk_tactic) : m(m), p(p), m_mk_tactic(mk_tactic) {} + ~lazy_tactic() override { dealloc(m_tactic); } + void operator()(goal_ref const& in, goal_ref_buffer& result) override { + ensure_tactic(); + (*m_tactic)(in, result); + } + void cleanup() override { if (m_tactic) m_tactic->cleanup(); } + char const* name() const override { return "lazy tactic"; } + void collect_statistics(statistics& st) const override { if (m_tactic) m_tactic->collect_statistics(st); } + void user_propagate_initialize_value(expr* var, expr* value) override { if (m_tactic) m_tactic->user_propagate_initialize_value(var, value); } + tactic* translate(ast_manager& m) override { ensure_tactic(); return m_tactic->translate(m); } + void reset() override { if (m_tactic) m_tactic->reset(); } + void reset_statistics() override { if (m_tactic) m_tactic->reset_statistics(); } + void register_on_clause(void* ctx, user_propagator::on_clause_eh_t& on_clause) override { + ensure_tactic(); + m_tactic->register_on_clause(ctx, on_clause); + } +}; + + +tactic* mk_lazy_tactic(ast_manager& m, params_ref const& p, std::function mkt) { + return alloc(lazy_tactic, m, p, mkt); +} + class fail_tactic : public tactic { public: void operator()(goal_ref const & in, goal_ref_buffer & result) override { @@ -146,13 +177,12 @@ tactic * mk_trace_tactic(char const * tag) { class fail_if_undecided_tactic : public skip_tactic { public: - fail_if_undecided_tactic() {} - void operator()(goal_ref const & in, goal_ref_buffer& result) override { if (!in->is_decided()) throw tactic_exception("undecided"); skip_tactic::operator()(in, result); } + void user_propagate_initialize_value(expr* var, expr* value) override { } }; tactic * mk_fail_if_undecided_tactic() { diff --git a/src/tactic/tactic.h b/src/tactic/tactic.h index 652bf8130..698146c0d 100644 --- a/src/tactic/tactic.h +++ b/src/tactic/tactic.h @@ -32,10 +32,8 @@ class progress_callback; typedef ptr_buffer goal_buffer; class tactic : public user_propagator::core { - unsigned m_ref_count; + unsigned m_ref_count = 0; public: - tactic():m_ref_count(0) {} - void inc_ref() { m_ref_count++; } void dec_ref() { SASSERT(m_ref_count > 0); m_ref_count--; if (m_ref_count == 0) dealloc(this); } @@ -131,11 +129,13 @@ public: tactic * translate(ast_manager & m) override { return this; } char const* name() const override { return "skip"; } void collect_statistics(statistics& st) const override {} + void user_propagate_initialize_value(expr* var, expr* value) override { } }; tactic * mk_skip_tactic(); tactic * mk_fail_tactic(); tactic * mk_fail_if_undecided_tactic(); +tactic* mk_lazy_tactic(ast_manager& m, params_ref const& p, std::function); /* ADD_TACTIC("skip", "do nothing tactic.", "mk_skip_tactic()") diff --git a/src/tactic/tactical.cpp b/src/tactic/tactical.cpp index 0b8189e8d..78e15aef7 100644 --- a/src/tactic/tactical.cpp +++ b/src/tactic/tactical.cpp @@ -30,6 +30,7 @@ class binary_tactical : public tactic { protected: tactic_ref m_t1; tactic_ref m_t2; + bool m_clean = true; public: @@ -61,8 +62,11 @@ public: } void cleanup() override { + if (m_clean) + return; m_t1->cleanup(); m_t2->cleanup(); + m_clean = true; } void reset() override { @@ -103,7 +107,8 @@ public: char const* name() const override { return "and_then"; } - void operator()(goal_ref const & in, goal_ref_buffer& result) override { + void operator()(goal_ref const & in, goal_ref_buffer& result) override { + m_clean = false; bool proofs_enabled = in->proofs_enabled(); bool cores_enabled = in->unsat_core_enabled(); @@ -213,6 +218,10 @@ public: m_t2->user_propagate_register_decide(decide_eh); } + void user_propagate_initialize_value(expr* var, expr* value) override { + m_t2->user_propagate_initialize_value(var, value); + } + }; tactic * and_then(tactic * t1, tactic * t2) { @@ -378,6 +387,12 @@ public: } tactic * translate(ast_manager & m) override { return translate_core(m); } + + void user_propagate_initialize_value(expr* var, expr* value) override { + for (auto t : m_ts) + t->user_propagate_initialize_value(var, value); + } + }; tactic * or_else(unsigned num, tactic * const * ts) { @@ -862,6 +877,7 @@ tactic * par_and_then(unsigned num, tactic * const * ts) { class unary_tactical : public tactic { protected: tactic_ref m_t; + bool m_clean = true; public: @@ -870,11 +886,12 @@ public: SASSERT(t); } - void operator()(goal_ref const & in, goal_ref_buffer& result) override { + void operator()(goal_ref const & in, goal_ref_buffer& result) override { + m_clean = false; m_t->operator()(in, result); } - void cleanup(void) override { m_t->cleanup(); } + void cleanup(void) override { if (!m_clean) m_t->cleanup(); m_clean = true; } void collect_statistics(statistics & st) const override { m_t->collect_statistics(st); } void reset_statistics() override { m_t->reset_statistics(); } void updt_params(params_ref const & p) override { m_t->updt_params(p); } @@ -884,6 +901,7 @@ public: void set_progress_callback(progress_callback * callback) override { m_t->set_progress_callback(callback); } void user_propagate_register_expr(expr* e) override { m_t->user_propagate_register_expr(e); } void user_propagate_clear() override { m_t->user_propagate_clear(); } + void user_propagate_initialize_value(expr* var, expr* value) override { m_t->user_propagate_initialize_value(var, value); } protected: @@ -1147,6 +1165,7 @@ public: char const* name() const override { return "cond"; } void operator()(goal_ref const & in, goal_ref_buffer & result) override { + m_clean = false; if (m_p->operator()(*(in.get())).is_true()) m_t1->operator()(in, result); else @@ -1158,6 +1177,11 @@ public: tactic * new_t2 = m_t2->translate(m); return alloc(cond_tactical, m_p.get(), new_t1, new_t2); } + + void user_propagate_initialize_value(expr* var, expr* value) override { + m_t1->user_propagate_initialize_value(var, value); + m_t2->user_propagate_initialize_value(var, value); + } }; tactic * cond(probe * p, tactic * t1, tactic * t2) { diff --git a/src/tactic/user_propagator_base.h b/src/tactic/user_propagator_base.h index 58904a12d..968196f63 100644 --- a/src/tactic/user_propagator_base.h +++ b/src/tactic/user_propagator_base.h @@ -99,6 +99,10 @@ namespace user_propagator { throw default_exception("clause logging is only supported on the SMT solver"); } + virtual void user_propagate_initialize_value(expr* var, expr* value) { + throw default_exception("value initialization is only supported on the SMT solver"); + } + }; diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 4ddc1b8cb..658647ea6 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -36,7 +36,8 @@ add_executable(test-z3 dl_relation.cpp dl_table.cpp dl_util.cpp - doc.cpp + doc.cpp + dlist.cpp egraph.cpp escaped.cpp euf_bv_plugin.cpp @@ -105,6 +106,7 @@ add_executable(test-z3 sat_lookahead.cpp sat_user_scope.cpp scoped_timer.cpp + scoped_vector.cpp simple_parser.cpp simplex.cpp simplifier.cpp diff --git a/src/test/cnf_backbones.cpp b/src/test/cnf_backbones.cpp index 32a8149bd..a764ed9cf 100644 --- a/src/test/cnf_backbones.cpp +++ b/src/test/cnf_backbones.cpp @@ -86,7 +86,6 @@ static void track_clauses(sat::solver const& src, dst.mk_var(false, true); } sat::literal_vector lits; - sat::literal lit; sat::clause * const * it = src.begin_clauses(); sat::clause * const * end = src.end_clauses(); svector bin_clauses; diff --git a/src/test/dlist.cpp b/src/test/dlist.cpp new file mode 100644 index 000000000..9ad04d6b2 --- /dev/null +++ b/src/test/dlist.cpp @@ -0,0 +1,184 @@ +/*++ +Copyright (c) 2024 Microsoft Corporation + +Module Name: + + tst_dlist.cpp + +Abstract: + + Test dlist module + +Author: + + Chuyue Sun 2024-07-18. + +--*/ + +#include +#include +#include "util/dlist.h" + +class TestNode : public dll_base { +public: + int value; + TestNode(int val) : value(val) { + init(this); + } +}; + +// Test the prev() method +void test_prev() { + TestNode node(1); + SASSERT(node.prev() == &node); + std::cout << "test_prev passed." << std::endl; +} + +// Test the next() method +static void test_next() { + TestNode node(1); + SASSERT(node.next() == &node); + std::cout << "test_next passed." << std::endl; +} + +// Test the const prev() method +static void test_const_prev() { + const TestNode node(1); + SASSERT(node.prev() == &node); + std::cout << "test_const_prev passed." << std::endl; +} + +// Test the const next() method +static void test_const_next() { + const TestNode node(1); + SASSERT(node.next() == &node); + std::cout << "test_const_next passed." << std::endl; +} + +// Test the init() method +static void test_init() { + TestNode node(1); + node.init(&node); + SASSERT(node.next() == &node); + SASSERT(node.prev() == &node); + SASSERT(node.invariant()); + std::cout << "test_init passed." << std::endl; +} + +// Test the pop() method +static void test_pop() { + TestNode* list = nullptr; + TestNode node1(1); + TestNode::push_to_front(list, &node1); + TestNode* popped = TestNode::pop(list); + SASSERT(popped == &node1); + SASSERT(list == nullptr); + SASSERT(popped->next() == popped); + SASSERT(popped->prev() == popped); + std::cout << "test_pop passed." << std::endl; +} + +// Test the insert_after() method +static void test_insert_after() { + TestNode node1(1); + TestNode node2(2); + node1.insert_after(&node2); + SASSERT(node1.next() == &node2); + SASSERT(node2.prev() == &node1); + SASSERT(node1.prev() == &node2); + SASSERT(node2.next() == &node1); + SASSERT(node1.invariant()); + SASSERT(node2.invariant()); + std::cout << "test_insert_after passed." << std::endl; +} + +// Test the insert_before() method +static void test_insert_before() { + TestNode node1(1); + TestNode node2(2); + node1.insert_before(&node2); + SASSERT(node1.prev() == &node2); + SASSERT(node2.next() == &node1); + SASSERT(node1.next() == &node2); + SASSERT(node2.prev() == &node1); + SASSERT(node1.invariant()); + SASSERT(node2.invariant()); + std::cout << "test_insert_before passed." << std::endl; +} + +// Test the remove_from() method +static void test_remove_from() { + TestNode* list = nullptr; + TestNode node1(1); + TestNode node2(2); + TestNode::push_to_front(list, &node1); + TestNode::push_to_front(list, &node2); + TestNode::remove_from(list, &node1); + SASSERT(list == &node2); + SASSERT(node2.next() == &node2); + SASSERT(node2.prev() == &node2); + std::cout << "test_remove_from passed." << std::endl; +} + +// Test the push_to_front() method +static void test_push_to_front() { + TestNode* list = nullptr; + TestNode node1(1); + TestNode::push_to_front(list, &node1); + SASSERT(list == &node1); + SASSERT(node1.next() == &node1); + SASSERT(node1.prev() == &node1); + std::cout << "test_push_to_front passed." << std::endl; +} + +// Test the detach() method +static void test_detach() { + TestNode node(1); + TestNode::detach(&node); + SASSERT(node.next() == &node); + SASSERT(node.prev() == &node); + SASSERT(node.invariant()); + std::cout << "test_detach passed." << std::endl; +} + +// Test the invariant() method +static void test_invariant() { + TestNode node1(1); + SASSERT(node1.invariant()); + TestNode node2(2); + node1.insert_after(&node2); + SASSERT(node1.invariant()); + SASSERT(node2.invariant()); + std::cout << "test_invariant passed." << std::endl; +} + +// Test the contains() method +static void test_contains() { + TestNode* list = nullptr; + TestNode node1(1); + TestNode node2(2); + TestNode::push_to_front(list, &node1); + TestNode::push_to_front(list, &node2); + SASSERT(TestNode::contains(list, &node1)); + SASSERT(TestNode::contains(list, &node2)); + TestNode node3(3); + SASSERT(!TestNode::contains(list, &node3)); + std::cout << "test_contains passed." << std::endl; +} + +void tst_dlist() { + test_prev(); + test_next(); + test_const_prev(); + test_const_next(); + test_init(); + test_pop(); + test_insert_after(); + test_insert_before(); + test_push_to_front(); + test_detach(); + test_invariant(); + test_contains(); + (void)test_remove_from; + std::cout << "All tests passed." << std::endl; +} diff --git a/src/test/hashtable.cpp b/src/test/hashtable.cpp index fb8042dc7..e26fbd5d8 100644 --- a/src/test/hashtable.cpp +++ b/src/test/hashtable.cpp @@ -12,6 +12,7 @@ Abstract: Author: Leonardo de Moura (leonardo) 2006-09-12. + Chuyue Sun (liviasun) 2024-07-18. Revision History: @@ -20,7 +21,6 @@ Revision History: #include #include #include - #include "util/hashtable.h" @@ -119,11 +119,126 @@ static void tst3() { ENSURE(h2.size() == 2); } +// Custom hash and equality functions for testing +struct my_hash { + unsigned operator()(int x) const { return x; } +}; + +struct my_eq { + bool operator()(int x, int y) const { return x == y; } +}; + +void test_hashtable_constructors() { + hashtable ht; + VERIFY(ht.empty()); + VERIFY(ht.size() == 0); + VERIFY(ht.capacity() == DEFAULT_HASHTABLE_INITIAL_CAPACITY); + + // Copy constructor + hashtable ht_copy(ht); + VERIFY(ht_copy.empty()); + VERIFY(ht_copy.size() == 0); + VERIFY(ht_copy.capacity() == ht.capacity()); + + // Move constructor + hashtable ht_move(std::move(ht)); + VERIFY(ht_move.empty()); + VERIFY(ht_move.size() == 0); + VERIFY(ht_move.capacity() == ht_copy.capacity()); +} + +void test_hashtable_insert() { + hashtable ht; + ht.insert(1); + VERIFY(!ht.empty()); + VERIFY(ht.size() == 1); + int value; + VERIFY(ht.find(1, value) && value == 1); +} + +void test_hashtable_remove() { + hashtable ht; + ht.insert(1); + ht.remove(1); + VERIFY(ht.empty()); + VERIFY(ht.size() == 0); +} + +void test_hashtable_find() { + hashtable ht; + ht.insert(1); + int value; + VERIFY(ht.find(1, value) && value == 1); + VERIFY(!ht.find(2, value)); +} + +void test_hashtable_contains() { + hashtable ht; + ht.insert(1); + VERIFY(ht.contains(1)); + VERIFY(!ht.contains(2)); +} + +void test_hashtable_reset() { + hashtable ht; + ht.insert(1); + ht.reset(); + VERIFY(ht.empty()); + VERIFY(ht.size() == 0); +} + +void test_hashtable_finalize() { + hashtable ht; + ht.insert(1); + ht.finalize(); + VERIFY(ht.empty()); + VERIFY(ht.size() == 0); +} + +void test_hashtable_iterators() { + hashtable ht; + ht.insert(1); + ht.insert(2); + ht.insert(3); + + int count = 0; + for(auto it = ht.begin(); it != ht.end(); ++it) { + ++count; + } + VERIFY(count == 3); +} + +void test_hashtable_operators() { + hashtable ht1; + hashtable ht2; + + ht1.insert(1); + ht2.insert(2); + + ht1 |= ht2; + VERIFY(ht1.contains(1)); + VERIFY(ht1.contains(2)); + + ht1 &= ht2; + VERIFY(!ht1.contains(1)); + VERIFY(ht1.contains(2)); +} + void tst_hashtable() { tst3(); for (int i = 0; i < 100; i++) tst2(); tst1(); + test_hashtable_constructors(); + test_hashtable_insert(); + test_hashtable_remove(); + test_hashtable_find(); + test_hashtable_contains(); + test_hashtable_reset(); + test_hashtable_finalize(); + test_hashtable_iterators(); + test_hashtable_operators(); + std::cout << "All tests passed!" << std::endl; } #else void tst_hashtable() { diff --git a/src/test/heap.cpp b/src/test/heap.cpp index 6a5bc7b9f..25a509dc8 100644 --- a/src/test/heap.cpp +++ b/src/test/heap.cpp @@ -27,7 +27,7 @@ struct lt_proc { bool operator()(int v1, int v2) const { return v1 < v2; } }; //struct int_hash_proc { unsigned operator()(int v) const { std::cout << "hash " << v << "\n"; VERIFY(v >= 0); return v; }}; //typedef int_hashtable > int_set; typedef heap int_heap; -#define N 10000 +#define N 100 static random_gen heap_rand(1); @@ -146,4 +146,3 @@ void tst_heap() { tst2(); } } - diff --git a/src/test/main.cpp b/src/test/main.cpp index 0c3d0e01a..f028d6ceb 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -188,6 +188,7 @@ int main(int argc, char ** argv) { TST(total_order); TST(dl_table); TST(dl_context); + TST(dlist); TST(dl_util); TST(dl_product_relation); TST(dl_relation); @@ -268,4 +269,5 @@ int main(int argc, char ** argv) { TST(euf_bv_plugin); TST(euf_arith_plugin); TST(sls_test); + TST(scoped_vector); } diff --git a/src/test/permutation.cpp b/src/test/permutation.cpp index 74b97a365..aeaa5a235 100644 --- a/src/test/permutation.cpp +++ b/src/test/permutation.cpp @@ -1,24 +1,47 @@ -/*++ -Copyright (c) 2012 Microsoft Corporation - -Module Name: - - permutation.cpp - -Abstract: - - Simple abstraction for managing permutations. - -Author: - - Leonardo de Moura (leonardo) 2012-01-04 - -Revision History: - ---*/ +#include +#include #include "util/permutation.h" #include "util/util.h" -#include "util/vector.h" +#include "util/debug.h" + + void swap(unsigned m1, unsigned m2) noexcept { std::swap(m1, m2); } + +static void test_constructor() { + permutation p(5); + for (unsigned i = 0; i < 5; ++i) { + SASSERT(p(i) == i); + SASSERT(p.inv(i) == i); + } +} + +static void test_reset() { + permutation p(3); + p.swap(0, 2); + p.reset(3); + for (unsigned i = 0; i < 3; ++i) { + SASSERT(p(i) == i); + SASSERT(p.inv(i) == i); + } +} + +static void test_swap() { + permutation p(4); + p.swap(1, 3); + SASSERT(p(1) == 3); + SASSERT(p(3) == 1); + SASSERT(p.inv(1) == 3); + SASSERT(p.inv(3) == 1); +} + +static void test_move_after() { + permutation p(5); + p.move_after(1, 3); + SASSERT(p(0) == 0); + SASSERT(p(1) == 2); + SASSERT(p(2) == 3); + SASSERT(p(3) == 1); + SASSERT(p(4) == 4); +} void apply_permutation_copy(unsigned sz, unsigned const * src, unsigned const * p, unsigned * target) { for (unsigned i = 0; i < sz; i++) { @@ -26,8 +49,7 @@ void apply_permutation_copy(unsigned sz, unsigned const * src, unsigned const * } } -static void tst1(unsigned sz, unsigned num_tries, unsigned max = UINT_MAX) { -#if 0 +static void test_apply_permutation(unsigned sz, unsigned num_tries, unsigned max = UINT_MAX) { unsigned_vector data; unsigned_vector p; unsigned_vector new_data; @@ -41,44 +63,53 @@ static void tst1(unsigned sz, unsigned num_tries, unsigned max = UINT_MAX) { for (unsigned i = 0; i < sz; i++) data[i] = g() % max; for (unsigned k = 0; k < num_tries; k ++) { - shuffle(p.size(), p.c_ptr(), g); - // std::cout << "p: "; display(std::cout, p.begin(), p.end()); std::cout << "\n"; - // std::cout << "data: "; display(std::cout, data.begin(), data.end()); std::cout << "\n"; - apply_permutation_copy(sz, data.c_ptr(), p.c_ptr(), new_data.c_ptr()); - apply_permutation(sz, data.c_ptr(), p.c_ptr()); - // std::cout << "data: "; display(std::cout, data.begin(), data.end()); std::cout << "\n"; + shuffle(p.size(), p.data(), g); + apply_permutation_copy(sz, data.data(), p.data(), new_data.data()); + apply_permutation(sz, data.data(), p.data()); for (unsigned i = 0; i < 0; i++) ENSURE(data[i] == new_data[i]); } -#endif +} + + +static void test_check_invariant() { + permutation p(4); + SASSERT(p.check_invariant()); + p.swap(0, 2); + SASSERT(p.check_invariant()); + p.move_after(1, 3); + SASSERT(p.check_invariant()); +} + +static void test_display() { + permutation p(4); + std::ostringstream out; + p.display(out); + SASSERT(out.str() == "0:0 1:1 2:2 3:3"); } void tst_permutation() { - tst1(10, 1000, 5); - tst1(10, 1000, 1000); - tst1(10, 1000, UINT_MAX); - tst1(100, 1000, 33); - tst1(100, 1000, 1000); - tst1(100, 1000, UINT_MAX); - tst1(1000, 1000, 121); - tst1(1000, 1000, 1000); - tst1(1000, 1000, UINT_MAX); - tst1(33, 1000, 121); - tst1(33, 1000, 1000); - tst1(33, 1000, UINT_MAX); - tst1(121, 1000, 121); - tst1(121, 1000, 1000); - tst1(121, 1000, UINT_MAX); - for (unsigned i = 0; i < 1000; i++) { - tst1(1000, 2, 333); - tst1(1000, 2, 10000); - tst1(1000, 2, UINT_MAX); - } - random_gen g; - for (unsigned i = 0; i < 100000; i++) { - unsigned sz = (g() % 131) + 1; - tst1(sz, 1, sz*2); - tst1(sz, 1, UINT_MAX); - tst1(sz, 1, sz/2 + 1); - } + test_constructor(); + test_reset(); + test_swap(); + test_move_after(); + test_check_invariant(); + test_display(); + test_apply_permutation(10, 1000, 5); + test_apply_permutation(10, 1000, 1000); + test_apply_permutation(10, 1000, UINT_MAX); + test_apply_permutation(100, 1000, 33); + test_apply_permutation(100, 1000, 1000); + test_apply_permutation(100, 1000, UINT_MAX); + test_apply_permutation(1000, 1000, 121); + test_apply_permutation(1000, 1000, 1000); + test_apply_permutation(1000, 1000, UINT_MAX); + test_apply_permutation(33, 1000, 121); + test_apply_permutation(33, 1000, 1000); + test_apply_permutation(33, 1000, UINT_MAX); + test_apply_permutation(121, 1000, 121); + test_apply_permutation(121, 1000, 1000); + test_apply_permutation(121, 1000, UINT_MAX); + + std::cout << "All tests passed!" << std::endl; } diff --git a/src/test/scoped_vector.cpp b/src/test/scoped_vector.cpp new file mode 100644 index 000000000..05d98fcf1 --- /dev/null +++ b/src/test/scoped_vector.cpp @@ -0,0 +1,99 @@ +#include +#include "util/scoped_vector.h" + +void test_push_back_and_access() { + scoped_vector sv; + sv.push_back(10); + + sv.push_back(20); + + SASSERT(sv.size() == 2); + SASSERT(sv[0] == 10); + SASSERT(sv[1] == 20); + + std::cout << "test_push_back_and_access passed." << std::endl; +} + +void test_scopes() { + scoped_vector sv; + sv.push_back(10); + sv.push_back(20); + + sv.push_scope(); + sv.push_back(30); + sv.push_back(40); + + SASSERT(sv.size() == 4); + SASSERT(sv[2] == 30); + SASSERT(sv[3] == 40); + + sv.pop_scope(1); + + std::cout << "test_scopes passed." << std::endl; + SASSERT(sv.size() == 2); + SASSERT(sv[0] == 10); + SASSERT(sv[1] == 20); + + std::cout << "test_scopes passed." << std::endl; +} + +void test_set() { + scoped_vector sv; + sv.push_back(10); + sv.push_back(20); + + sv.set(0, 30); + sv.set(1, 40); + + SASSERT(sv.size() == 2); + SASSERT(sv[0] == 30); + SASSERT(sv[1] == 40); + + sv.push_scope(); + sv.set(0, 50); + SASSERT(sv[0] == 50); + sv.pop_scope(1); + SASSERT(sv[0] == 30); + + std::cout << "test_set passed." << std::endl; +} + +void test_pop_back() { + scoped_vector sv; + sv.push_back(10); + sv.push_back(20); + + SASSERT(sv.size() == 2); + sv.pop_back(); + SASSERT(sv.size() == 1); + SASSERT(sv[0] == 10); + sv.pop_back(); + SASSERT(sv.size() == 0); + + std::cout << "test_pop_back passed." << std::endl; +} + +void test_erase_and_swap() { + scoped_vector sv; + sv.push_back(10); + sv.push_back(20); + sv.push_back(30); + + sv.erase_and_swap(1); + + SASSERT(sv.size() == 2); + SASSERT(sv[0] == 10); + SASSERT(sv[1] == 30); + + std::cout << "test_erase_and_swap passed." << std::endl; +} + +void tst_scoped_vector() { + test_push_back_and_access(); + test_scopes(); + test_set(); + test_pop_back(); + test_erase_and_swap(); + + std::cout << "All tests passed." << std::endl; +} diff --git a/src/util/approx_set.h b/src/util/approx_set.h index a1835be6f..011a8017d 100644 --- a/src/util/approx_set.h +++ b/src/util/approx_set.h @@ -197,10 +197,6 @@ public: ++*this; return tmp; } - - bool operator==(iterator const & it) const { - return m_set == it.m_set; - } bool operator!=(iterator const & it) const { return m_set != it.m_set; diff --git a/src/util/array.h b/src/util/array.h index 2954035f6..d844692ef 100644 --- a/src/util/array.h +++ b/src/util/array.h @@ -26,7 +26,7 @@ public: private: #define ARRAY_SIZE_IDX -1 - T * m_data; + T * m_data = nullptr; void destroy_elements() { iterator it = begin(); iterator e = end(); @@ -71,7 +71,7 @@ public: typedef T * iterator; typedef const T * const_iterator; - array():m_data(nullptr) {} + array() = default; /** \brief Store the array in the given chunk of memory (mem). @@ -193,7 +193,7 @@ public: template class ptr_array : public array { public: - ptr_array() {} + ptr_array() = default; ptr_array(void * mem, unsigned sz, T * const * vs):array(mem, sz, vs) {} template ptr_array(Allocator & a, unsigned sz, T * const * vs):array(a, sz, vs) {} @@ -205,7 +205,7 @@ public: template class sarray : public array { public: - sarray() {} + sarray() = default; sarray(void * mem, unsigned sz, T const * vs):array(mem, sz, vs) {} template sarray(Allocator & a, unsigned sz, T const * vs):array(a, sz, vs) {} diff --git a/src/util/bit_vector.h b/src/util/bit_vector.h index 12f86dd00..7b87e045a 100644 --- a/src/util/bit_vector.h +++ b/src/util/bit_vector.h @@ -220,7 +220,6 @@ public: bool operator*() const { return b.get(m_curr); } iterator& operator++() { ++m_curr; return *this; } iterator operator++(int) { iterator tmp = *this; ++* this; return tmp; } - bool operator==(iterator const& it) const { return m_curr == it.m_curr; } bool operator!=(iterator const& it) const { return m_curr != it.m_curr; } }; diff --git a/src/util/buffer.h b/src/util/buffer.h index 3ca597af2..b71717fe6 100644 --- a/src/util/buffer.h +++ b/src/util/buffer.h @@ -275,6 +275,6 @@ public: template class sbuffer : public buffer { public: - sbuffer(): buffer() {} + sbuffer() = default; sbuffer(unsigned sz, const T& elem) : buffer(sz,elem) {} }; diff --git a/src/util/chashtable.h b/src/util/chashtable.h index b15d6017f..f245a047c 100644 --- a/src/util/chashtable.h +++ b/src/util/chashtable.h @@ -52,9 +52,8 @@ public: protected: struct cell { - cell * m_next; + cell * m_next = (cell*)1; T m_data; - cell():m_next(reinterpret_cast(1)) {} bool is_free() const { return GET_TAG(m_next) == 1; } void mark_free() { m_next = TAG(cell*, m_next, 1); } void unmark_free() { m_next = UNTAG(cell*, m_next); } @@ -552,7 +551,6 @@ public: return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } - bool operator==(iterator const & it) const { return m_list_it == it.m_list_it; } bool operator!=(iterator const & it) const { return m_list_it != it.m_list_it; } }; @@ -610,7 +608,7 @@ public: struct key_value { Key m_key; Value m_value; - key_value() {} + key_value() = default; key_value(Key const & k):m_key(k) {} key_value(Key const & k, Value const & v):m_key(k), m_value(v) {} }; diff --git a/src/util/distribution.h b/src/util/distribution.h index 0ed63d510..92aa4d805 100644 --- a/src/util/distribution.h +++ b/src/util/distribution.h @@ -95,7 +95,6 @@ public: next_index(); return *this; } - bool operator==(iterator const& other) const { return m_sz == other.m_sz; } bool operator!=(iterator const& other) const { return m_sz != other.m_sz; } }; diff --git a/src/util/dlist.h b/src/util/dlist.h index 4c0e51e58..1ed183d3d 100644 --- a/src/util/dlist.h +++ b/src/util/dlist.h @@ -213,13 +213,8 @@ public: T const& operator*() const { return *m_elem; } - - bool operator==(dll_iterator const& other) const { - return m_elem == other.m_elem && m_first == other.m_first; - } - bool operator!=(dll_iterator const& other) const { - return !operator==(other); + return m_elem != other.m_elem || m_first != other.m_first; } }; diff --git a/src/util/gparams.cpp b/src/util/gparams.cpp index 839d02ab0..171cae604 100644 --- a/src/util/gparams.cpp +++ b/src/util/gparams.cpp @@ -22,6 +22,7 @@ Notes: #include "util/mutex.h" #include "util/region.h" #include "util/map.h" +#include "util/rational.h" static DECLARE_MUTEX(gparams_mux); @@ -351,8 +352,8 @@ public: ps.set_uint(param_name, static_cast(val)); } else if (k == CPK_DOUBLE) { - char * aux; - double val = strtod(value, &aux); + rational r(value); + double val = r.get_double(); ps.set_double(param_name, val); } else if (k == CPK_BOOL) { diff --git a/src/util/hashtable.h b/src/util/hashtable.h index b59a2e7d8..acbe2a818 100644 --- a/src/util/hashtable.h +++ b/src/util/hashtable.h @@ -12,6 +12,7 @@ Abstract: Author: Leonardo de Moura (leonardo) 2006-09-11. + Chuyue Sun (liviasun) 2024-07-18. Revision History: @@ -639,6 +640,19 @@ public: #ifdef Z3DEBUG bool check_invariant() { + // The capacity must always be a power of two. + if (!is_power_of_two(m_capacity)) + return false; + + // The number of deleted plus the size must not exceed the capacity. + if (m_num_deleted + m_size > m_capacity) + return false; + + // Checking that m_num_deleted is less than or equal to m_size. + if (m_num_deleted > m_size) { + return false; + } + entry * curr = m_table; entry * end = m_table + m_capacity; unsigned num_deleted = 0; diff --git a/src/util/heap.h b/src/util/heap.h index c080c6ebd..71cafeeb8 100644 --- a/src/util/heap.h +++ b/src/util/heap.h @@ -55,6 +55,19 @@ class heap : private LT { } bool check_invariant_core(int idx) const { + + // Check that m_values starts with a dummy value at index 0. + if (m_values.empty() || m_values[0] != -1) { + return false; + } + + // // All indices in m_value2indices that are not used in m_values should be 0 + // for (int val = 0; val < static_cast(m_value2indices.size()); ++val) { + // if (std::find(m_values.begin(), m_values.end(), val) == m_values.end() && m_value2indices[val] != 0) { + // return false; // Unused indices should have a 0 value + // } + // } + if (idx < static_cast(m_values.size())) { SASSERT(m_value2indices[m_values[idx]] == idx); SASSERT(parent(idx) == 0 || !less_than(m_values[idx], m_values[parent(idx)])); diff --git a/src/util/hwf.cpp b/src/util/hwf.cpp index 8c20a4cda..e48934b5b 100644 --- a/src/util/hwf.cpp +++ b/src/util/hwf.cpp @@ -89,10 +89,6 @@ hwf_manager::hwf_manager() : // to the precision (not sure about the rounding modes though). } -hwf_manager::~hwf_manager() -{ -} - uint64_t RAW(double X) { uint64_t tmp; memcpy(&tmp, &(X), sizeof(uint64_t)); return tmp; } double DBL(uint64_t X) { double tmp; memcpy(&tmp, &(X), sizeof(double)); return tmp; } diff --git a/src/util/hwf.h b/src/util/hwf.h index 209a8fe77..926963937 100644 --- a/src/util/hwf.h +++ b/src/util/hwf.h @@ -46,7 +46,6 @@ class hwf_manager { public: typedef hwf numeral; hwf_manager(); - ~hwf_manager(); void reset(hwf & o) { set(o, 0); } void set(hwf & o, int value); diff --git a/src/util/inf_rational.h b/src/util/inf_rational.h index 2d7963ff0..7e8487d9d 100644 --- a/src/util/inf_rational.h +++ b/src/util/inf_rational.h @@ -65,7 +65,7 @@ class inf_rational { return s; } - inf_rational() {} + inf_rational() = default; explicit inf_rational(int n): m_first(rational(n)), diff --git a/src/util/list.h b/src/util/list.h index 208828ea0..a9c33fd33 100644 --- a/src/util/list.h +++ b/src/util/list.h @@ -44,7 +44,6 @@ public: T const & operator*() const { return m_curr->head(); } iterator & operator++() { m_curr = m_curr->tail(); return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } - bool operator==(iterator const & it) { return m_curr == it.m_curr; } bool operator!=(iterator const & it) { return m_curr != it.m_curr; } }; diff --git a/src/util/map.h b/src/util/map.h index 0068be31b..fb72db01f 100644 --- a/src/util/map.h +++ b/src/util/map.h @@ -24,19 +24,6 @@ template struct _key_data { Key m_key; Value m_value; - _key_data() { - } - _key_data(Key const & k): - m_key(k) { - } - _key_data(Key const & k, Value const & v): - m_key(k), - m_value(v) { - } - _key_data(Key const& k, Value&& v): - m_key(k), - m_value(std::move(v)) { - } }; template @@ -108,27 +95,27 @@ public: } void insert(key const & k, value const & v) { - m_table.insert(key_data(k, v)); + m_table.insert(key_data{k, v}); } void insert(key const& k, value&& v) { - m_table.insert(key_data(k, std::move(v))); + m_table.insert(key_data{k, std::move(v)}); } bool insert_if_not_there_core(key const & k, value const & v, entry *& et) { - return m_table.insert_if_not_there_core(key_data(k,v), et); + return m_table.insert_if_not_there_core(key_data{k,v}, et); } value & insert_if_not_there(key const & k, value const & v) { - return m_table.insert_if_not_there2(key_data(k, v))->get_data().m_value; + return m_table.insert_if_not_there2(key_data{k, v})->get_data().m_value; } entry * insert_if_not_there3(key const & k, value const & v) { - return m_table.insert_if_not_there2(key_data(k, v)); + return m_table.insert_if_not_there2(key_data{k, v}); } entry * find_core(key const & k) const { - return m_table.find_core(key_data(k)); + return m_table.find_core(key_data{k}); } bool find(key const & k, value & v) const { @@ -150,7 +137,7 @@ public: } iterator find_iterator(key const & k) const { - return m_table.find(key_data(k)); + return m_table.find(key_data{k}); } value const & find(key const& k) const { @@ -175,7 +162,7 @@ public: } void remove(key const & k) { - m_table.remove(key_data(k)); + m_table.remove(key_data{k}); } void erase(key const & k) { diff --git a/src/util/memory_manager.cpp b/src/util/memory_manager.cpp index 4ef1cac66..8c6bfc7e7 100644 --- a/src/util/memory_manager.cpp +++ b/src/util/memory_manager.cpp @@ -322,7 +322,7 @@ void* memory::reallocate(void *p, size_t s) { if (sz >= s) return p; #else - size_t *sz_p = reinterpret_cast(p)-1; + size_t *sz_p = reinterpret_cast(p) - SIZE_T_ALIGN; size_t sz = *sz_p; void *real_p = reinterpret_cast(sz_p); s = s + SIZE_T_ALIGN * sizeof(size_t); // we allocate an extra field! diff --git a/src/util/memory_manager.h b/src/util/memory_manager.h index af56c4507..a52e3e3bd 100644 --- a/src/util/memory_manager.h +++ b/src/util/memory_manager.h @@ -19,6 +19,7 @@ Revision History: #pragma once #include +#include #include #include #include "util/z3_exception.h" @@ -105,18 +106,14 @@ ALLOC_ATTR T * alloc_vect(unsigned sz); template T * alloc_vect(unsigned sz) { T * r = static_cast(memory::allocate(sizeof(T) * sz)); - T * curr = r; - for (unsigned i = 0; i < sz; i++, curr++) - new (curr) T(); + std::uninitialized_default_construct_n(r, sz); return r; } template void dealloc_vect(T * ptr, unsigned sz) { if (ptr == nullptr) return; - T * curr = ptr; - for (unsigned i = 0; i < sz; i++, curr++) - curr->~T(); + std::destroy_n(ptr, sz); memory::deallocate(ptr); } diff --git a/src/util/mpq.h b/src/util/mpq.h index 286c2758d..87ee5e17d 100644 --- a/src/util/mpq.h +++ b/src/util/mpq.h @@ -23,12 +23,12 @@ Revision History: class mpq { mpz m_num; - mpz m_den; + mpz m_den = 1; friend class mpq_manager; friend class mpq_manager; public: - mpq(int v):m_num(v), m_den(1) {} - mpq():m_den(1) {} + mpq(int v) : m_num(v) {} + mpq() = default; mpq(mpq &&) noexcept = default; mpq & operator=(mpq&&) = default; mpq & operator=(mpq const&) = delete; diff --git a/src/util/mpz.cpp b/src/util/mpz.cpp index 011b62f7f..7b9719b36 100644 --- a/src/util/mpz.cpp +++ b/src/util/mpz.cpp @@ -46,10 +46,14 @@ Revision History: #define LEHMER_GCD #endif - -#if defined(__GNUC__) +#ifdef __has_builtin + #define HAS_BUILTIN(X) __has_builtin(X) +#else + #define HAS_BUILTIN(X) 0 +#endif +#if HAS_BUILTIN(__builtin_ctz) #define _trailing_zeros32(X) __builtin_ctz(X) -#elif defined(_WINDOWS) && (defined(_M_X86) || (defined(_M_X64) && !defined(_M_ARM64EC))) +#elif defined(_WINDOWS) && (defined(_M_X86) || (defined(_M_X64) && !defined(_M_ARM64EC))) && !defined(__clang__) // This is needed for _tzcnt_u32 and friends. #include #define _trailing_zeros32(X) _tzcnt_u32(X) @@ -62,11 +66,11 @@ static uint32_t _trailing_zeros32(uint32_t x) { #endif #if (defined(__LP64__) || defined(_WIN64)) && defined(_M_X64) && !defined(_M_ARM64EC) - #if defined(__GNUC__) - #define _trailing_zeros64(X) __builtin_ctzll(X) - #else - #define _trailing_zeros64(X) _tzcnt_u64(X) - #endif +#if HAS_BUILTIN(__builtin_ctzll) +#define _trailing_zeros64(X) __builtin_ctzll(X) +#elif !defined(__clang__) +#define _trailing_zeros64(X) _tzcnt_u64(X) +#endif #else static uint64_t _trailing_zeros64(uint64_t x) { uint64_t r = 0; @@ -75,6 +79,8 @@ static uint64_t _trailing_zeros64(uint64_t x) { } #endif +#undef HAS_BUILTIN + unsigned trailing_zeros(uint32_t x) { return static_cast(_trailing_zeros32(x)); } diff --git a/src/util/obj_hashtable.h b/src/util/obj_hashtable.h index 49b37ca61..2784439a8 100644 --- a/src/util/obj_hashtable.h +++ b/src/util/obj_hashtable.h @@ -56,12 +56,11 @@ template class obj_map { public: struct key_data { - Key * m_key; + Key * m_key = nullptr; Value m_value; - key_data():m_key(nullptr), m_value() { - } + key_data() = default; key_data(Key * k): - m_key(k), m_value() { + m_key(k) { } key_data(Key * k, Value const & v): m_key(k), diff --git a/src/util/optional.h b/src/util/optional.h index 8e515f4be..c2a0fd3ef 100644 --- a/src/util/optional.h +++ b/src/util/optional.h @@ -30,7 +30,7 @@ class optional { } public: - optional() {} + optional() = default; explicit optional(const T & val) { m_obj = alloc(T, val); @@ -116,13 +116,13 @@ public: */ template class optional { - T * m_ptr; + T * m_ptr = nullptr; static optional m_undef; public: - optional():m_ptr(nullptr) {} + optional() = default; explicit optional(T * val):m_ptr(val) {} diff --git a/src/util/params.cpp b/src/util/params.cpp index 700a53109..8ea7c1da3 100644 --- a/src/util/params.cpp +++ b/src/util/params.cpp @@ -366,12 +366,11 @@ class params { }; typedef std::pair entry; svector m_entries; - std::atomic m_ref_count; + std::atomic m_ref_count = 0; void del_value(entry & e); void del_values(); public: - params():m_ref_count(0) {} ~params() { reset(); } @@ -391,7 +390,6 @@ public: void reset(char const * k); void validate(param_descrs const & p) { - symbol suffix, prefix; for (params::entry& e : m_entries) { param_kind expected = p.get_kind_in_module(e.first); if (expected == CPK_INVALID) { diff --git a/src/util/permutation.cpp b/src/util/permutation.cpp index 8b7adedf3..47b9d85a1 100644 --- a/src/util/permutation.cpp +++ b/src/util/permutation.cpp @@ -36,6 +36,7 @@ void permutation::swap(unsigned i, unsigned j) noexcept { unsigned j_prime = m_p[j]; std::swap(m_p[i], m_p[j]); std::swap(m_inv_p[i_prime], m_inv_p[j_prime]); + SASSERT(check_invariant()); } /** @@ -66,11 +67,19 @@ void permutation::display(std::ostream & out) const { bool permutation::check_invariant() const { SASSERT(m_p.size() == m_inv_p.size()); unsigned n = m_p.size(); + bool_vector check_vector(n, false); // To check for duplicate and out-of-range values for (unsigned i = 0; i < n; i++) { + unsigned pi = m_p[i]; SASSERT(m_p[i] < n); SASSERT(m_inv_p[i] < n); SASSERT(m_p[m_inv_p[i]] == i); SASSERT(m_inv_p[m_p[i]] == i); + // Check the inversion hasn't been checked yet + if (check_vector[pi]) { + return false; + } + // Mark this value as checked + check_vector[pi] = true; } return true; } diff --git a/src/util/permutation.h b/src/util/permutation.h index dfc52b370..0d4399f7e 100644 --- a/src/util/permutation.h +++ b/src/util/permutation.h @@ -38,6 +38,8 @@ public: bool check_invariant() const; }; +void swap(unsigned i, unsigned j) noexcept; + inline std::ostream & operator<<(std::ostream & out, permutation const & p) { p.display(out); return out; diff --git a/src/util/queue.h b/src/util/queue.h index 059dea573..771ebbcd4 100644 --- a/src/util/queue.h +++ b/src/util/queue.h @@ -23,13 +23,10 @@ Notes: template class queue { vector m_elems; - unsigned m_head; - unsigned m_capacity; + unsigned m_head = 0; + unsigned m_capacity = 0; public: - - queue(): m_head(0), m_capacity(0) {} - void push(T const& t) { m_elems.push_back(t); } bool empty() const { diff --git a/src/util/rational.h b/src/util/rational.h index e9924bca7..61569f40c 100644 --- a/src/util/rational.h +++ b/src/util/rational.h @@ -41,8 +41,8 @@ public: ADD_INITIALIZER('rational::initialize();') ADD_FINALIZER('rational::finalize();') */ - rational() {} - + rational() = default; + rational(rational const & r) { m().set(m_val, r.m_val); } rational(rational&&) = default; diff --git a/src/util/ref.h b/src/util/ref.h index 849e23b38..22e51b783 100644 --- a/src/util/ref.h +++ b/src/util/ref.h @@ -21,7 +21,7 @@ Revision History: template class ref { - T * m_ptr; + T * m_ptr = nullptr; void inc_ref() { if (m_ptr) { @@ -36,9 +36,7 @@ class ref { } public: - ref(): - m_ptr(nullptr) { - } + ref() = default; ref(T * ptr): m_ptr(ptr) { @@ -50,9 +48,9 @@ public: inc_ref(); } - ref (ref && r) noexcept : m_ptr(nullptr) { - std::swap(m_ptr, r.m_ptr); - } + ref(ref && r) noexcept { + std::swap(m_ptr, r.m_ptr); + } ~ref() { dec_ref(); diff --git a/src/util/s_integer.h b/src/util/s_integer.h index 6ddd2bf67..b102d6d4b 100644 --- a/src/util/s_integer.h +++ b/src/util/s_integer.h @@ -21,7 +21,7 @@ Revision History: #include "util/rational.h" class s_integer { - int m_val; + int m_val = 0; static s_integer m_zero; static s_integer m_one; static s_integer m_minus_one; @@ -41,7 +41,7 @@ public: std::string to_string() const; public: - s_integer(): m_val(0) {} + s_integer() = default; explicit s_integer(int n):m_val(n) {} struct i64 {}; explicit s_integer(int64_t i, i64):m_val(static_cast(i)) {} diff --git a/src/util/sat_literal.h b/src/util/sat_literal.h index 58088e628..61ee5f657 100644 --- a/src/util/sat_literal.h +++ b/src/util/sat_literal.h @@ -119,7 +119,7 @@ namespace sat { literal_set(literal_vector const& v) { for (unsigned i = 0; i < v.size(); ++i) insert(v[i]); } - literal_set() {} + literal_set() = default; literal_vector to_vector() const { literal_vector result; for (literal lit : *this) result.push_back(lit); @@ -146,7 +146,6 @@ namespace sat { literal operator*() const { return to_literal(*m_it); } iterator& operator++() { ++m_it; return *this; } iterator operator++(int) { iterator tmp = *this; ++m_it; return tmp; } - bool operator==(iterator const& it) const { return m_it == it.m_it; } bool operator!=(iterator const& it) const { return m_it != it.m_it; } }; iterator begin() const { return iterator(m_set.begin()); } diff --git a/src/util/scoped_numeral.h b/src/util/scoped_numeral.h index f70f5f185..0bbae754b 100644 --- a/src/util/scoped_numeral.h +++ b/src/util/scoped_numeral.h @@ -97,10 +97,19 @@ public: return a.m().eq(a, b); } + friend bool operator==(_scoped_numeral const & a, _scoped_numeral const & b) { + return a.m().eq(a.m_num, b.m_num); + } + friend bool operator!=(_scoped_numeral const & a, numeral const & b) { return !a.m().eq(a, b); } + friend bool operator!=(_scoped_numeral const & a, _scoped_numeral const & b) { + return !(a == b); + } + + friend bool operator<(_scoped_numeral const & a, numeral const & b) { return a.m().lt(a, b); } diff --git a/src/util/scoped_vector.h b/src/util/scoped_vector.h index 2c6cfaa21..6a5c1228d 100644 --- a/src/util/scoped_vector.h +++ b/src/util/scoped_vector.h @@ -106,8 +106,7 @@ public: unsigned m_index; public: iterator(scoped_vector const& v, unsigned idx): m_vec(v), m_index(idx) {} - - bool operator==(iterator const& other) const { return &other.m_vec == &m_vec && other.m_index == m_index; } + bool operator!=(iterator const& other) const { return &other.m_vec != &m_vec || other.m_index != m_index; } T const& operator*() { return m_vec[m_index]; } @@ -176,8 +175,46 @@ private: } bool invariant() const { - return - m_size <= m_elems.size() && - m_elems_start <= m_elems.size(); + + + if (!(m_size <= m_elems.size() && m_elems_start <= m_elems.size())) + return false; + + // Check that source and destination trails have the same length. + if (m_src.size() != m_dst.size()) + return false; + // The size of m_src, m_dst, and m_src_lim should be consistent with the scope stack. + if (m_src_lim.size() != m_sizes.size() || m_src.size() != m_dst.size()) + return false; + + // // m_elems_lim stores the past sizes of m_elems for each scope. Each element in m_elems_lim should be + // // within bounds and in non-decreasing order. + // for (unsigned i = 1; i < m_elems_lim.size(); ++i) { + // if (m_elems_lim[i - 1] > m_elems_lim[i]) return false; + // } + + + // // m_sizes tracks the size of the vector at each scope level. + // // Each element in m_sizes should be non-decreasing and within the size of m_elems. + // for (unsigned i = 1; i < m_sizes.size(); ++i) { + // if (m_sizes[i - 1] > m_sizes[i]) + // return false; + // } + + // // The m_src and m_dst vectors should have the same size and should contain valid indices. + // if (m_src.size() != m_dst.size()) return false; + // for (unsigned i = 0; i < m_src.size(); ++i) { + // if (m_src[i] >= m_index.size() || m_dst[i] >= m_elems.size()) return false; + // } + + + // // The size of m_src_lim should be less than or equal to the size of m_sizes and store valid indices. + // if (m_src_lim.size() > m_sizes.size()) return false; + // for (unsigned elem : m_src_lim) { + // if (elem > m_src.size()) return false; + // } + + return true; + } }; diff --git a/src/util/small_object_allocator.h b/src/util/small_object_allocator.h index 05fe32ef0..646a203c1 100644 --- a/src/util/small_object_allocator.h +++ b/src/util/small_object_allocator.h @@ -29,9 +29,8 @@ class small_object_allocator { static const unsigned NUM_SLOTS = (SMALL_OBJ_SIZE >> PTR_ALIGNMENT); struct chunk { chunk* m_next{ nullptr }; - char* m_curr{ nullptr }; + char* m_curr = m_data; char m_data[CHUNK_SIZE]; - chunk():m_curr(m_data) {} }; chunk * m_chunks[NUM_SLOTS]; void * m_free_list[NUM_SLOTS]; diff --git a/src/util/stacked_value.h b/src/util/stacked_value.h index 89be6fa53..a3a0d933b 100644 --- a/src/util/stacked_value.h +++ b/src/util/stacked_value.h @@ -52,7 +52,7 @@ public: } } - stacked_value() {} + stacked_value() = default; stacked_value(const T& m) { m_value = m; } diff --git a/src/util/symbol.h b/src/util/symbol.h index ab7d41c98..721351b7e 100644 --- a/src/util/symbol.h +++ b/src/util/symbol.h @@ -29,7 +29,7 @@ template class symbol_table; class symbol { - char const * m_data; + char const * m_data = nullptr; template friend class symbol_table; @@ -50,9 +50,7 @@ class symbol { } static symbol m_dummy; public: - symbol(): - m_data(nullptr) { - } + symbol() = default; explicit symbol(char const * d); explicit symbol(const std::string & str) : symbol(str.c_str()) {} explicit symbol(unsigned idx): diff --git a/src/util/symbol_table.h b/src/util/symbol_table.h index 6a683f201..1a805ff35 100644 --- a/src/util/symbol_table.h +++ b/src/util/symbol_table.h @@ -31,8 +31,7 @@ class symbol_table { symbol m_key; T m_data; - key_data() { - } + key_data() = default; explicit key_data(symbol k): m_key(k) { @@ -59,10 +58,12 @@ class symbol_table { struct hash_entry { typedef key_data data; key_data m_data; - + +#if 0 hash_entry() { SASSERT(m_data.m_key == symbol::null); } +#endif unsigned get_hash() const { return m_data.m_key.hash(); diff --git a/src/util/uint_set.h b/src/util/uint_set.h index 73c3bce1f..f936f1134 100644 --- a/src/util/uint_set.h +++ b/src/util/uint_set.h @@ -194,7 +194,6 @@ public: SASSERT(invariant()); } unsigned operator*() const { return m_index; } - bool operator==(iterator const& it) const { return m_index == it.m_index; } bool operator!=(iterator const& it) const { return m_index != it.m_index; } iterator & operator++() { ++m_index; scan(); return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } diff --git a/src/util/vector.h b/src/util/vector.h index d552daea1..67f6218ed 100644 --- a/src/util/vector.h +++ b/src/util/vector.h @@ -47,118 +47,551 @@ using std_vector = std::vector>; #if 0 -// portability guide to std::vector. -// memory allocator should be based on memory_allocator -// -// template -// struct memory_allocator { -// typedef T value_type; -// etc (interface seems to change between C++17, 20 versions) -// }; -// +template +class vector { + SZ m_capacity = 0; + SZ m_size = 0; + T* m_data = nullptr; -// Note: -// polynomial.h contains declaration -// typedef svector numeral_vector; -// it is crucial that it uses svector and not vector. The destructors on elements of the numeral vector are handled outside. -// Numeral gets instantiated by mpz and mpz does not support copy constructors. -// porting svector to vector is therefore blocked on the semantics of svector being -// copy-constructor free. -// + void destroy_elements() { + std::destroy_n(m_data, size()); + } -#include + void free_memory() { + memory::deallocate(m_data); + m_data = nullptr; + } + + void expand_vector() { + // ensure that the data is sufficiently aligned + // better fail to compile than produce code that may crash + + if (m_data == nullptr) { + m_capacity = 2; + m_size = 0; + m_data = reinterpret_cast(memory::allocate(sizeof(T) * m_capacity)); + } + else { + static_assert(std::is_nothrow_move_constructible::value); + SASSERT(capacity() > 0); + SZ old_capacity = m_capacity; + SZ new_capacity = (3 * old_capacity + 1) >> 1; + if (new_capacity <= old_capacity) { + throw default_exception("Overflow encountered when expanding vector"); + } + if (std::is_trivially_copyable::value) { + m_data = (T*)memory::reallocate(m_data, new_capacity); + } + else { + T* new_data = (T*)memory::allocate(new_capacity); + auto old_size = size(); + std::uninitialized_move_n(m_data, old_size, new_data); + destroy(); + m_data = new_data; + } + m_capacity = new_capacity; + } + } + + void copy_core(vector const& source) { + SASSERT(!m_data); + SZ size = source.size(); + SZ capacity = source.capacity(); + m_data = reinterpret_cast(memory::allocate(sizeof(T) * capacity)); + m_capacity = capacity; + m_size = size; + std::uninitialized_copy(source.begin(), source.end(), begin()); + } + + void destroy() { + if (m_data) { + if (CallDestructors) + destroy_elements(); + free_memory(); + } + } -template -class vector : public std::vector { public: typedef T data_t; - typedef typename std::vector::iterator iterator; + typedef T* iterator; + typedef const T* const_iterator; + + vector() = default; - vector() {} vector(SZ s) { - // TODO resize(s, T()); - } - vector(SZ s, T const& e) { - // TODO resize(s, e); + init(s); } - vector(SZ s, T const* e) { - // TODO - } - - void reset() { clear(); } - void finalize() { clear(); } - void reserve(SZ s, T const & d) { - if (s > size()) - resize(s, d); - } - void reserve(SZ s) { - - } - - void setx(SZ idx, T const & elem, T const & d) { - if (idx >= size()) - resize(idx+1, d); - (*this)[idx] = elem; - } - - T const & get(SZ idx, T const & d) const { - if (idx >= size()) { - return d; + void init(SZ s) { + SASSERT(m_data == nullptr); + if (s == 0) { + return; } - return (*this)[idx]; - } - - void insert(T const & elem) { - push_back(elem); - } - - void erase(iterator pos) { - // TODO - } - - void erase(T const& e) { - // TODO - } - void fill(T const & elem) { - for (auto& e : *this) - e = elem; - } - - void fill(unsigned sz, T const & elem) { - resize(sz); - fill(elem); - } - - void shrink(SZ s) { - resize(s); - } - void reverse() { - SZ sz = size(); - for (SZ i = 0; i < sz/2; ++i) { - std::swap((*this)[i], (*this)[sz-i-1]); + m_data = reinterpret_cast(memory::allocate(sizeof(T) * s)); + m_capacity = s; + m_size = s; + // initialize elements + iterator it = begin(); + iterator e = end(); + for (; it != e; ++it) { + new (it) T(); } } - void append(vector const & other) { - for(SZ i = 0; i < other.size(); ++i) { - push_back(other[i]); + vector(SZ s, T const& elem) { + resize(s, elem); + } + + vector(vector const& source) { + if (source.m_data) { + copy_core(source); + } + SASSERT(size() == source.size()); + } + + vector(vector&& other) noexcept { + std::swap(m_data, other.m_data); + } + + vector(SZ s, T const* data) { + for (SZ i = 0; i < s; i++) { + push_back(data[i]); } } - void append(unsigned n, T const* elems) { - // TODO + + ~vector() { + destroy(); } - bool contains(T const & elem) const { - for (auto const& e : *this) - if (e == elem) + void finalize() { + destroy(); + m_data = nullptr; + } + + bool operator==(vector const& other) const { + if (this == &other) { + return true; + } + if (size() != other.size()) + return false; + for (unsigned i = 0; i < size(); i++) { + if ((*this)[i] != other[i]) + return false; + } + return true; + } + + bool operator!=(vector const& other) const { + return !(*this == other); + } + + vector& operator=(vector const& source) { + if (this == &source) { + return *this; + } + destroy(); + if (source.m_data) + copy_core(source); + return *this; + } + + vector& operator=(vector&& source) noexcept { + if (this == &source) { + return *this; + } + destroy(); + std::swap(m_data, source.m_data); + return *this; + } + + bool containsp(std::function& predicate) const { + for (auto const& t : *this) + if (predicate(t)) return true; return false; } - -}; + /** + * retain elements that satisfy predicate. aka 'where'. + */ + vector filter_pure(std::function& predicate) const { + vector result; + for (auto& t : *this) + if (predicate(t)) + result.push_back(t); + return result; + } + + vector& filter_update(std::function& predicate) { + unsigned j = 0; + for (auto& t : *this) + if (predicate(t)) + set(j++, t); + shrink(j); + return *this; + } + + /** + * update elements using f, aka 'select' + */ + template + vector map_pure(std::function& f) const { + vector result; + for (auto& t : *this) + result.push_back(f(t)); + return result; + } + + vector& map_update(std::function& f) { + unsigned j = 0; + for (auto& t : *this) + set(j++, f(t)); + return *this; + } + + void reset() { + if (m_data) { + if (CallDestructors) { + destroy_elements(); + } + m_size = 0; + } + } + + void clear() { reset(); } + + bool empty() const { + return m_data == nullptr || m_size == 0; + } + + SZ size() const { + if (m_data == nullptr) { + return 0; + } + return m_size; + } + + SZ capacity() const { + if (m_data == nullptr) { + return 0; + } + return m_capacity; + } + + iterator begin() { + return m_data; + } + + iterator end() { + return m_data + size(); + } + + const_iterator begin() const { + return m_data; + } + + const_iterator end() const { + return m_data + size(); + } + + class reverse_iterator { + T* v; + public: + reverse_iterator(T* v) :v(v) {} + + T operator*() { return *v; } + reverse_iterator operator++(int) { + reverse_iterator tmp = *this; + --v; + return tmp; + } + reverse_iterator& operator++() { + --v; + return *this; + } + + bool operator!=(reverse_iterator const& other) const { + return other.v != v; + } + }; + + reverse_iterator rbegin() { return reverse_iterator(end() - 1); } + reverse_iterator rend() { return reverse_iterator(begin() - 1); } + + void set_end(iterator it) { + if (m_data) { + SZ new_sz = static_cast(it - m_data); + if (CallDestructors) { + iterator e = end(); + for (; it != e; ++it) { + it->~T(); + } + } + m_size = new_sz; + } + else { + SASSERT(it == 0); + } + } + + T& operator[](SZ idx) { + SASSERT(idx < size()); + return m_data[idx]; + } + + T const& operator[](SZ idx) const { + SASSERT(idx < size()); + return m_data[idx]; + } + + T& get(SZ idx) { + SASSERT(idx < size()); + return m_data[idx]; + } + + T const& get(SZ idx) const { + SASSERT(idx < size()); + return m_data[idx]; + } + + void set(SZ idx, T const& val) { + SASSERT(idx < size()); + m_data[idx] = val; + } + + void set(SZ idx, T&& val) { + SASSERT(idx < size()); + m_data[idx] = std::move(val); + } + + T& back() { + SASSERT(!empty()); + return operator[](size() - 1); + } + + T const& back() const { + SASSERT(!empty()); + return operator[](size() - 1); + } + + void pop_back() { + SASSERT(!empty()); + if (CallDestructors) { + back().~T(); + } + m_size--; + } + + vector& push_back(T const& elem) { + if (m_data == nullptr || m_size == m_capacity) { + expand_vector(); + } + new (m_data + m_size) T(elem); + m_size++; + return *this; + } + + template + vector& push_back(T const& elem, T elem2, Args ... elems) { + push_back(elem); + push_back(elem2, elems ...); + return *this; + } + + vector& push_back(T&& elem) { + if (m_data == nullptr || m_size == m_capacity) { + expand_vector(); + } + new (m_data + m_size) T(std::move(elem)); + ++m_size; + return *this; + } + + void insert(T const& elem) { + push_back(elem); + } + + void erase(iterator pos) { + SASSERT(pos >= begin() && pos < end()); + iterator prev = pos; + ++pos; + iterator e = end(); + for (; pos != e; ++pos, ++prev) { + *prev = std::move(*pos); + } + pop_back(); + } + + void erase(T const& elem) { + iterator it = std::find(begin(), end(), elem); + if (it != end()) { + erase(it); + } + } + + /** Erase all elements that satisfy the given predicate. Returns the number of erased elements. */ + template + SZ erase_if(UnaryPredicate should_erase) { + iterator i = begin(); + iterator const e = end(); + for (iterator j = begin(); j != e; ++j) + if (!should_erase(std::as_const(*j))) + *(i++) = std::move(*j); + SZ const count = e - i; + SASSERT_EQ(i - begin(), size() - count); + shrink(size() - count); + return count; + } + + void shrink(SZ s) { + if (m_data) { + SASSERT(s <= m_size); + if (CallDestructors) { + iterator it = m_data + s; + iterator e = end(); + for (; it != e; ++it) { + it->~T(); + } + } + m_size = s; + } + else { + SASSERT(s == 0); + } + } + + template + void resize(SZ s, Args args...) { + SZ sz = size(); + if (s <= sz) { shrink(s); return; } + while (s > capacity()) { + expand_vector(); + } + SASSERT(m_data != 0); + m_size = s; + iterator it = m_data + sz; + iterator end = m_data + s; + for (; it != end; ++it) { + new (it) T(std::forward(args)); + } + } + + void resize(SZ s) { + SZ sz = size(); + if (s <= sz) { shrink(s); return; } + while (s > capacity()) { + expand_vector(); + } + SASSERT(m_data != 0); + m_size = s; + iterator it = m_data + sz; + iterator end = m_data + s; + for (; it != end; ++it) { + new (it) T(); + } + } + + void append(vector const& other) { + for (SZ i = 0; i < other.size(); ++i) { + push_back(other[i]); + } + } + + void append(SZ sz, T const* data) { + for (SZ i = 0; i < sz; ++i) { + push_back(data[i]); + } + } + + void init(vector const& other) { + if (this == &other) + return; + reset(); + append(other); + } + + void init(SZ sz, T const* data) { + reset(); + append(sz, data); + } + + T* data() const { + return m_data; + } + + void swap(vector& other) noexcept { + std::swap(m_data, other.m_data); + } + + void reverse() { + SZ sz = size(); + for (SZ i = 0; i < sz / 2; ++i) { + std::swap(m_data[i], m_data[sz - i - 1]); + } + } + + void fill(T const& elem) { + iterator i = begin(); + iterator e = end(); + for (; i != e; ++i) { + *i = elem; + } + } + + void fill(unsigned sz, T const& elem) { + resize(sz); + fill(elem); + } + + bool contains(T const& elem) const { + const_iterator it = begin(); + const_iterator e = end(); + for (; it != e; ++it) { + if (*it == elem) { + return true; + } + } + return false; + } + + // set pos idx with elem. If idx >= size, then expand using default. + void setx(SZ idx, T const& elem, T const& d) { + if (idx >= size()) { + resize(idx + 1, d); + } + m_data[idx] = elem; + } + + // return element at position idx, if idx >= size, then return default + T const& get(SZ idx, T const& d) const { + if (idx >= size()) { + return d; + } + return m_data[idx]; + } + + void reserve(SZ s, T const& d) { + if (s > size()) + resize(s, d); + } + + void reserve(SZ s) { + if (s > size()) + resize(s); + } + + struct scoped_stack { + vector& s; + unsigned sz; + scoped_stack(vector& s) :s(s), sz(s.size()) {} + ~scoped_stack() { s.shrink(sz); } + }; + +}; + + + #else @@ -451,9 +884,6 @@ public: return *this; } - bool operator==(reverse_iterator const& other) const { - return other.v == v; - } bool operator!=(reverse_iterator const& other) const { return other.v != v; } @@ -738,7 +1168,7 @@ public: template class ptr_vector : public vector { public: - ptr_vector():vector() {} + ptr_vector() = default; ptr_vector(unsigned s):vector(s) {} ptr_vector(unsigned s, T * elem):vector(s, elem) {} ptr_vector(unsigned s, T * const * data):vector(s, const_cast(data)) {} @@ -758,7 +1188,7 @@ public: template class svector : public vector { public: - svector():vector() {} + svector() = default; svector(SZ s):vector(s) {} svector(SZ s, T const & elem):vector(s, elem) {} svector(SZ s, T const * data):vector(s, data) {}