libminizinc-2.8.2/0000755000175000017500000000000014541557705012505 5ustar kaolkaollibminizinc-2.8.2/mzn2doc.cpp0000644000175000017500000002662614536677021014577 0ustar kaolkaol/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Guido Tack */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifdef _MSC_VER #define _CRT_SECURE_NO_WARNINGS #endif #include #include #include #include #include #include #include #include #include #include #include using namespace MiniZinc; using namespace std; bool beginswith(const string& s, const string& t) { return s.compare(0, t.length(), t) == 0; } int main(int argc, char** argv) { string filename; vector includePaths; bool flag_verbose = false; bool flag_include_stdlib = false; bool flag_index = true; bool flag_rst = false; int toplevel_groups = 0; string output_base; string header_file; string footer_file; string std_lib_dir; if (char* MZNSTDLIBDIR = getenv("MZN_STDLIB_DIR")) { std_lib_dir = string(MZNSTDLIBDIR); } string globals_dir; if (argc < 2) { goto error; } try { for (int i = 1; i < argc; i++) { if (string(argv[i]) == string("-h") || string(argv[i]) == string("--help")) { goto error; } if (string(argv[i]) == string("--version")) { std::cout << "MiniZinc documentation generator, version " << MZN_VERSION_MAJOR << "." << MZN_VERSION_MINOR << "." << MZN_VERSION_PATCH << std::endl; std::cout << "Copyright (C) 2014-2017 Monash University, NICTA, Data61" << std::endl; std::exit(EXIT_SUCCESS); } if (beginswith(string(argv[i]), "-I")) { string include(argv[i]); if (include.length() > 2) { includePaths.push_back(include.substr(2) + string("/")); } else { i++; if (i == argc) { goto error; } includePaths.push_back(argv[i] + string("/")); } } else if (string(argv[i]) == string("-v") || string(argv[i]) == string("--verbose")) { flag_verbose = true; } else if (string(argv[i]) == "--stdlib-dir") { i++; if (i == argc) { goto error; } std_lib_dir = argv[i]; } else if (beginswith(string(argv[i]), "-G")) { string filename(argv[i]); if (filename.length() > 2) { globals_dir = filename.substr(2); } else { i++; if (i == argc) { goto error; } globals_dir = argv[i]; } } else if (string(argv[i]) == "--toplevel-groups") { i++; if (i == argc) { goto error; } toplevel_groups = atoi(argv[i]); } else if (string(argv[i]) == "--html-header" || string(argv[i]) == "--rst-header") { i++; if (i == argc) { goto error; } header_file = string(argv[i]); } else if (string(argv[i]) == "--html-footer" || string(argv[i]) == "--rst-footer") { i++; if (i == argc) { goto error; } footer_file = string(argv[i]); } else if (string(argv[i]) == "--include-stdlib") { flag_include_stdlib = true; } else if (string(argv[i]) == "--no-index") { flag_index = false; } else if (string(argv[i]) == "--globals-dir" || string(argv[i]) == "--mzn-globals-dir") { i++; if (i == argc) { goto error; } globals_dir = argv[i]; } else if (string(argv[i]) == "--output-base") { i++; if (i == argc) { goto error; } output_base = argv[i]; } else if (string(argv[i]) == "--rst-output") { flag_rst = true; toplevel_groups = 0; } else { std::string input_file(argv[i]); if (input_file.length() <= 4) { std::cerr << "Error: cannot handle file " << input_file << "." << std::endl; goto error; } size_t last_dot = input_file.find_last_of('.'); std::string extension; if (last_dot != string::npos) { extension = input_file.substr(last_dot, string::npos); } if (extension == ".mzn") { if (filename.empty()) { filename = input_file; } else { std::cerr << "Error: Multiple .mzn files given." << std::endl; goto error; } } else if (extension == ".dzn" || extension == ".json") { std::cerr << "Error: cannot generate documentation for data files." << std::endl; } else { std::cerr << "Error: cannot handle file extension " << extension << "." << std::endl; goto error; } } } if (filename.empty()) { std::cerr << "Error: no model file given." << std::endl; goto error; } if (std_lib_dir.empty()) { SolverConfigs solver_configs(std::cerr); std_lib_dir = solver_configs.mznlibDir(); } if (std_lib_dir.empty()) { std::cerr << "Error: unknown minizinc standard library directory.\n" << "Specify --stdlib-dir on the command line or set the\n" << "MZN_STDLIB_DIR environment variable.\n"; std::exit(EXIT_FAILURE); } if (!globals_dir.empty()) { includePaths.push_back(std_lib_dir + "/" + globals_dir + "/"); } includePaths.push_back(std_lib_dir + "/std/"); for (auto& includePath : includePaths) { if (!FileUtils::directory_exists(includePath)) { std::cerr << "Cannot access include directory " << includePath << "\n"; std::exit(EXIT_FAILURE); } } if (output_base.empty()) { output_base = filename.substr(0, filename.length() - 4); } { string header; size_t header_title = std::string::npos; size_t title_size = std::string("@TITLE").size(); if (!header_file.empty()) { std::ifstream hs(FILE_PATH(header_file)); if (!hs.good()) { std::cerr << "Cannot open header file " << header_file << "\n"; std::exit(EXIT_FAILURE); } std::string str((std::istreambuf_iterator(hs)), std::istreambuf_iterator()); header = str; header_title = str.find("@TITLE"); } string footer; if (!footer_file.empty()) { std::ifstream hs(FILE_PATH(footer_file)); if (!hs.good()) { std::cerr << "Cannot open footer file " << footer_file << "\n"; std::exit(EXIT_FAILURE); } std::string str((std::istreambuf_iterator(hs)), std::istreambuf_iterator()); footer = str; } std::stringstream errstream; if (flag_verbose) { std::cerr << "Parsing '" << filename << "'" << std::endl; } std::vector filenames; filenames.push_back(filename); Env env; if (Model* m = parse(env, filenames, {}, "", "", includePaths, {}, false, false, true, flag_verbose, errstream)) { try { env.model(m); if (flag_verbose) { std::cerr << "Done parsing." << std::endl; } if (flag_verbose) { std::cerr << "Typechecking ..."; } vector typeErrors; MiniZinc::typecheck(env, m, typeErrors, true, false); if (!typeErrors.empty()) { for (auto& typeError : typeErrors) { if (flag_verbose) { std::cerr << std::endl; } std::cerr << typeError.loc() << ":" << std::endl; std::cerr << typeError.what() << ": " << typeError.msg() << std::endl; } exit(EXIT_FAILURE); } if (flag_verbose) { std::cerr << " done" << std::endl; } std::string basename = output_base; std::string basedir; size_t lastSlash = output_base.find_last_of('/'); if (lastSlash != std::string::npos) { basedir = basename.substr(0, lastSlash) + "/"; basename = basename.substr(lastSlash + 1, std::string::npos); } std::vector docs; if (flag_rst) { docs = RSTPrinter::printRST(env.envi(), m, basename, toplevel_groups, flag_include_stdlib, flag_index); } else { docs = HtmlPrinter::printHtml(env.envi(), m, basename, toplevel_groups, flag_include_stdlib, flag_index); } for (auto& doc : docs) { std::ofstream os(FILE_PATH(basedir + doc.filename() + (flag_rst ? ".rst" : ".html"))); std::string header_replace = header; if (header_title != std::string::npos) { header_replace = header_replace.replace(header_title, title_size, doc.title()); } os << header_replace; os << doc.document(); os << footer; os.close(); } } catch (LocationException& e) { if (flag_verbose) { std::cerr << std::endl; } std::cerr << e.loc() << ":" << std::endl; std::cerr << e.what() << ": " << e.msg() << std::endl; exit(EXIT_FAILURE); } catch (Exception& e) { if (flag_verbose) { std::cerr << std::endl; } std::cerr << e.what() << ": " << e.msg() << std::endl; exit(EXIT_FAILURE); } } else { if (flag_verbose) { std::cerr << std::endl; } std::copy(istreambuf_iterator(errstream), istreambuf_iterator(), ostreambuf_iterator(std::cerr)); exit(EXIT_FAILURE); } } if (flag_verbose) { std::cerr << "Done." << std::endl; } return 0; } catch (...) { std::cerr << " UNHANDLED EXCEPTION." << std::endl; exit(EXIT_FAILURE); } error: std::string executable_name(argv[0]); executable_name = executable_name.substr(executable_name.find_last_of("/\\") + 1); std::cerr << "Usage: " << executable_name << " [] [-I ] .mzn [.dzn ...]" << std::endl << std::endl << "Options:" << std::endl << " --help, -h\n Print this help message" << std::endl << " --version\n Print version information" << std::endl << " --include-stdlib\n Include the standard libraries in the output" << std::endl << " -v, --verbose\n Print progress statements" << std::endl << " --stdlib-dir \n Path to MiniZinc standard library directory" << std::endl << " -G --globals-dir --mzn-globals-dir\n Search for included files in /." << std::endl << " --single-page\n Print entire documentation on a single HTML page." << std::endl << " --no-index\n Do not generate an index of all symbols." << std::endl << " --rst-output\n Generate ReStructuredText rather than HTML." << std::endl << " --html-header, --html-footer, --rst-header, --rst-footer\n Header/footer files " "to include in output." << std::endl << std::endl << "Output options:" << std::endl << std::endl << " --output-base \n Base name for output files" << std::endl; exit(EXIT_FAILURE); } libminizinc-2.8.2/.gitlab-ci.yml0000644000175000017500000002432414536677021015144 0ustar kaolkaolstages: - build - test - trigger - bench .download_bundle: &download_bundle - curl --location --header "PRIVATE-TOKEN:$ACCESS_TOKEN" --silent https://gitlab.com/api/v4/snippets/1796163/raw | tr -d '\r' > download.sh - sh download.sh minizinc-vendor master bundle:${MZNARCH} vendor.zip - unzip -q vendor.zip .download_bundle_win: &download_bundle_win - curl -o download.sh --location --header "PRIVATE-TOKEN:%ACCESS_TOKEN%" --silent https://gitlab.com/api/v4/snippets/1796163/raw - dos2unix download.sh - sh download.sh minizinc-vendor master bundle:%MZNARCH% vendor.zip - unzip -q vendor.zip variables: # CCache settings CCACHE_DIR: "$CI_PROJECT_DIR/.ccache" CCACHE_MAXSIZE: "100M" # MacOS deployment settings MACOSX_DEPLOYMENT_TARGET: "10.9" CMAKE_OSX_ARCHITECTURES: "x86_64;arm64" default: interruptible: true # ----------- Build MiniZinc ----------- .build: stage: build before_script: - bash download_vendor script: - cmake -S . -B build -G"$CMAKE_ARCH" -DCMAKE_BUILD_TYPE=Release -DBUILD_REF=$CI_PIPELINE_ID -DGecode_ROOT="$CI_PROJECT_DIR/vendor/gecode" -DOsiCBC_ROOT="$CI_PROJECT_DIR/vendor/cbc" -DCMAKE_INSTALL_PREFIX="$CI_PROJECT_DIR/minizinc" - cmake --build build --config Release --target install artifacts: paths: [minizinc/] cache: key: "$CI_JOB_STAGE:$CI_JOB_NAME" paths: [.ccache, vendor/] variables: CMAKE_C_COMPILER_LAUNCHER: "ccache" CMAKE_CXX_COMPILER_LAUNCHER: "ccache" only: [tags, merge_requests, pipelines, develop, master] build:linux: extends: .build image: ghcr.io/minizinc/docker-build-environment:cpp variables: MZNARCH: "linux" CMAKE_ARCH: "Ninja" tags: [linux, docker] build:musl: extends: .build image: ghcr.io/minizinc/docker-build-environment:alpine variables: MZNARCH: "musl" CMAKE_ARCH: "Ninja" tags: [linux, docker] build:osx: extends: .build variables: MZNARCH: "osx" CMAKE_ARCH: "Ninja" tags: [osx, cmake, cpp] build:win64: extends: .build variables: MZNARCH: "win64" CMAKE_ARCH: "Ninja" CMAKE_C_COMPILER_LAUNCHER: "buildcache" CMAKE_CXX_COMPILER_LAUNCHER: "buildcache" BUILDCACHE_DIR: "$CI_PROJECT_DIR/.ccache" BUILDCACHE_MAX_CACHE_SIZE: "104857600" script: - cmake -S . -B build -G"%CMAKE_ARCH%" -DCMAKE_BUILD_TYPE=Release -DBUILD_REF=%CI_PIPELINE_ID% -DGecode_ROOT="%CI_PROJECT_DIR%/vendor/gecode" -DOsiCBC_ROOT="%CI_PROJECT_DIR%/vendor/cbc" -DCMAKE_INSTALL_PREFIX="%CI_PROJECT_DIR%/minizinc" - cmake --build build --config Release --target install cache: key: "build_win64" tags: [win64, cmake, cpp, ninja, buildcache] # ----------- Test Suite ----------- test:format: stage: test image: ghcr.io/minizinc/docker-build-environment:clang-tools script: - cmake -S . -B build -GNinja -DCLANG_FORMAT_EXECUTABLE="run-clang-format" -DCLANG_FORMAT_FLAGS="--color always" - cmake --build build --target format tags: [linux, docker] only: changes: - "**/*.{cpp,c,h,hh,hpp}" - .clang-format refs: - merge_requests needs: [] test:analyse: extends: .build stage: test image: ghcr.io/minizinc/docker-build-environment:clang-tools variables: MZNARCH: "musl" CMAKE_ARCH: "Ninja" script: - cmake -S . -B build -G"$CMAKE_ARCH" -DCMAKE_CXX_CLANG_TIDY="clang-tidy" -DCMAKE_BUILD_TYPE="Debug" -DGecode_ROOT="$CI_PROJECT_DIR/vendor/gecode" -DOsiCBC_ROOT="$CI_PROJECT_DIR/vendor/cbc" - cmake --build build --config Debug tags: [linux, docker] only: changes: - "**/*.{cpp,c,h,hh,hpp}" - .clang-tidy refs: - merge_requests needs: [] .tests: stage: test variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" MZN_SOLVER_PATH: "$CI_PROJECT_DIR/vendor/chuffed/share/minizinc/solvers/:$CI_PROJECT_DIR/vendor/gecode/share/minizinc/solvers/" MZN_TEST_TAGS_PRESENT: gecode_presolver,cbc,cplex,highs,scip,gurobi,xpress before_script: - *download_bundle - export PATH=$CI_PROJECT_DIR/minizinc/bin:$PATH - minizinc --solvers - cd tests - python3 -m venv env - source env/bin/activate - pip install -r requirements.txt after_script: - echo "Test results at https://minizinc.gitlab.io/-/minizinc/-/jobs/${CI_JOB_ID}/artifacts/tests/output/report.html" artifacts: when: always paths: - tests/output/ reports: junit: tests/output/junit*.xml cache: key: "$CI_JOB_STAGE:$CI_JOB_NAME" paths: [.cache/pip, vendor.zip*] only: [merge_requests, pipelines, master] # Linux specific config .tests_linux: extends: .tests image: python:3.11 variables: MZNARCH: "linux" LD_LIBRARY_PATH: "$CI_PROJECT_DIR/vendor/highs/lib64" tags: [linux, docker] dependencies: ["build:linux"] needs: ["build:linux"] # OSX specific config .tests_osx: extends: .tests variables: MZNARCH: "osx" DYLD_LIBRARY_PATH: "$CI_PROJECT_DIR/vendor/highs/lib" tags: [osx] dependencies: ["build:osx"] needs: ["build:osx"] # Windows specific config .tests_win64: extends: .tests variables: MZNARCH: "win64" MZN_SOLVER_PATH: "$CI_PROJECT_DIR/vendor/chuffed/share/minizinc/solvers/;$CI_PROJECT_DIR/vendor/gecode/share/minizinc/solvers/" before_script: - *download_bundle_win - set PATH=%CI_PROJECT_DIR%/minizinc/bin;%CI_PROJECT_DIR%/vendor/highs/bin;%PATH% - cd tests - python -m venv env - call env\Scripts\activate.bat - pip install -r requirements.txt after_script: - "echo Test results at https://minizinc.gitlab.io/-/minizinc/-/jobs/%CI_JOB_ID%/artifacts/tests/output/report.html" tags: [win64] dependencies: ["build:win64"] needs: ["build:win64"] cache: key: test_win64 .tests_fast: script: - pytest .tests_full: script: - pytest --all-suites when: manual test:linux:fast: extends: [.tests_linux, .tests_fast] artifacts: expose_as: test-linux test:linux:full: extends: [.tests_linux, .tests_full] test:osx:fast: extends: [.tests_osx, .tests_fast] artifacts: expose_as: test-osx test:osx:full: extends: [.tests_osx, .tests_full] test:win64:fast: extends: [.tests_win64, .tests_fast] cache: key: test_win64_fast artifacts: expose_as: test-win64 test:win64:full: extends: [.tests_win64, .tests_full] cache: key: test_win64_full # ------------ Benchmarking ----------- .flatten_benchmark: stage: bench variables: MZNARCH: linux # Run on SLURM using srun FLATTEN_PREFIX: srun -w critical001 --nice --mem=8192 -t 10 PARALLEL_JOBS: "-1" # All in parallel, SLURM manages queue tags: [slurm] dependencies: ["build:linux"] needs: ["build:linux"] before_script: - cd tests/flattening - mkdir -p results # Download instances to benchmark - curl --location --silent https://gitlab.com/-/snippets/2095682/raw/master/instances.csv | tr -d '\r' > instances.csv - git clone https://github.com/minizinc/minizinc-benchmarks.git script: # Run benchmarks - python3 flatten.py --minizinc="$CI_PROJECT_DIR/minizinc/bin/minizinc" --prefix-args="$FLATTEN_PREFIX" --args="-G $MZNLIB" --parallel="$PARALLEL_JOBS" instances.csv results/stats.csv artifacts: paths: - tests/flattening/results/ expose_as: $CI_JOB_NAME cache: key: "$CI_JOB_STAGE:$CI_JOB_NAME" paths: [.cache/pip] # bench:std: # extends: .flatten_benchmark # variables: # MZNLIB: std # artifacts: # expose_as: bench-std # only: [tags, master, develop] # allow_failure: true # bench:linear: # extends: .flatten_benchmark # variables: # MZNLIB: linear # artifacts: # expose_as: bench-linear # only: [tags, master, develop] # allow_failure: true bench:std:manual: extends: .flatten_benchmark variables: MZNLIB: std artifacts: expose_as: bench-std-manual # only: [merge_requests, pipelines] only: [merge_requests, pipelines, tags, master, develop] when: manual bench:linear:manual: extends: .flatten_benchmark variables: MZNLIB: linear artifacts: expose_as: bench-linear-manual # only: [merge_requests, pipelines] only: [merge_requests, pipelines, tags, master, develop] when: manual # ----------- Documentation ----------- documentation: stage: test image: ghcr.io/minizinc/docker-build-environment:sphinx variables: MZNARCH: "linux" before_script: - *download_bundle script: - cp $CI_PROJECT_DIR/vendor/gecode/share/minizinc/gecode/gecode.mzn $CI_PROJECT_DIR/share/minizinc/std/ - cp $CI_PROJECT_DIR/vendor/chuffed/share/minizinc/chuffed/chuffed.mzn $CI_PROJECT_DIR/share/minizinc/std/ - echo 'include "globals.mzn"; include "gecode.mzn"; include "chuffed.mzn"; include "ide/vis.mzn"; include "experimental/all.mzn";' > $CI_PROJECT_DIR/share/minizinc/std/all.mzn - ./minizinc/bin/mzn2doc --rst-output --include-stdlib --output-base $CI_PROJECT_DIR/docs/en/lib $CI_PROJECT_DIR/share/minizinc/std/all.mzn - ./minizinc/bin/mzn2doc --rst-output --include-stdlib --output-base $CI_PROJECT_DIR/docs/chi/lib $CI_PROJECT_DIR/share/minizinc/std/all.mzn - cd $CI_PROJECT_DIR/docs - make BUILDDIR="en/_build" html latexpdf - make SPHINXOPTS="-D language=zh-CN" BUILDDIR="chi/_build" html latexpdf - MZNVERSION=$(python3 "$CI_PROJECT_DIR/docs/utils/minizinc_version.py") - mkdir -p $CI_PROJECT_DIR/docs-deploy/doc-${MZNVERSION}/en - mkdir -p $CI_PROJECT_DIR/docs-deploy/doc-${MZNVERSION}/chi - cp -r $CI_PROJECT_DIR/docs/en/_build/html/* $CI_PROJECT_DIR/docs-deploy/doc-${MZNVERSION}/en/ - cp $CI_PROJECT_DIR/docs/en/_build/latex/MiniZinc.pdf $CI_PROJECT_DIR/docs-deploy/doc-${MZNVERSION}/en/MiniZinc\ Handbook.pdf - cp -r $CI_PROJECT_DIR/docs/chi/_build/html/* $CI_PROJECT_DIR/docs-deploy/doc-${MZNVERSION}/chi/ - cp $CI_PROJECT_DIR/docs/chi/_build/latex/MiniZinc.pdf $CI_PROJECT_DIR/docs-deploy/doc-${MZNVERSION}/chi/MiniZinc\ Handbook.pdf - python3 "$CI_PROJECT_DIR/docs/utils/gen_redirects.py" "$CI_PROJECT_DIR/docs-deploy/doc-${MZNVERSION}" "$CI_PROJECT_DIR/docs-deploy/doc-latest" artifacts: paths: - docs-deploy/ expose_as: documentation tags: - linux - docker only: [tags, merge_requests, pipelines, develop, master] dependencies: ["build:linux"] needs: ["build:linux"] # ----------- Trigger FindMUS pipeline ----------- trigger:findmus: stage: trigger trigger: project: minizinc/FindMUS branch: develop only: [develop] libminizinc-2.8.2/minizinc.cpp0000644000175000017500000001010414536677021015023 0ustar kaolkaol/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Guido Tack * Gleb Belov */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* This (main) file coordinates flattening and solving. * The corresponding modules are flexibly plugged in * as derived classes, prospectively from DLLs. * A flattening module should provide MinZinc::GetFlattener() * A solving module should provide an object of a class derived from SolverFactory. * Need to get more flexible for multi-pass & multi-solving stuff TODO */ #include #include #include #include #include #include #include #include using namespace MiniZinc; namespace { int run(const std::string& exe, const std::vector& args, bool jsonStream) { try { Timer startTime; bool fSuccess = false; MznSolver slv(std::cout, std::cerr, startTime); try { fSuccess = (slv.run(args, "", exe) != SolverInstance::ERROR); } catch (const SignalRaised& e) { // Interrupted, just terminate if (slv.getFlagVerbose()) { std::cerr << std::endl << "Interrupted." << std::endl; std::cerr << " Done ("; std::cerr << "overall time " << startTime.stoptime() << ")." << std::endl; } // Re-raise signal e.raise(); return static_cast(!fSuccess); } catch (const InternalError& e) { if (slv.getFlagVerbose()) { std::cerr << std::endl; } std::cerr << "MiniZinc has encountered an internal error. This is a bug." << std::endl; std::cerr << "Please file a bug report using the MiniZinc bug tracker." << std::endl; std::cerr << "The internal error message was: " << std::endl; std::cerr << "\"" << e.msg() << "\"" << std::endl; } catch (const Exception& e) { if (jsonStream || slv.flagEncapsulateJSON) { e.json(std::cout); } else { if (slv.getFlagVerbose()) { std::cerr << std::endl; } e.print(std::cerr); } } catch (const std::exception& e) { if (slv.getFlagVerbose()) { std::cerr << std::endl; } std::cerr << e.what() << std::endl; } catch (...) { if (slv.getFlagVerbose()) { std::cerr << std::endl; } std::cerr << " UNKNOWN EXCEPTION." << std::endl; } if (slv.getFlagVerbose()) { std::cerr << " Done ("; std::cerr << "overall time " << startTime.stoptime() << ")." << std::endl; } return static_cast(!fSuccess); } catch (const Exception& e) { std::string what = e.what(); std::cerr << what << (what.empty() ? "" : ": ") << e.msg() << std::endl; std::exit(EXIT_FAILURE); } } } // namespace #ifdef _WIN32 #include int wmain(int argc, wchar_t* argv[], wchar_t* envp[]) { InterruptListener::run(); OverflowHandler::install(); std::vector args(argc - 1); bool jsonStream = false; for (int i = 1; i < argc; i++) { args[i - 1] = FileUtils::wide_to_utf8(argv[i]); if (args[i - 1] == "--json-stream") { jsonStream = true; } } auto exe = FileUtils::wide_to_utf8(argv[0]); #ifdef NDEBUG && !__MINGW32__ // Lambda to prevent object unwinding not allowed with __try..__except return ([&]() { __try { return run(exe, args, jsonStream); } __except (OverflowHandler::filter(GetExceptionCode())) { OverflowHandler::handle(GetExceptionCode()); } })(); #else // Let debugger catch SEH exceptions return run(exe, args, jsonStream); #endif } #else int main(int argc, const char** argv) { OverflowHandler::install(argv); std::vector args(argc - 1); bool jsonStream = false; for (int i = 1; i < argc; i++) { args[i - 1] = argv[i]; if (args[i - 1] == "--json-stream") { jsonStream = true; } } return run(argv[0], args, jsonStream); } #endif libminizinc-2.8.2/share/0000755000175000017500000000000014536677021013605 5ustar kaolkaollibminizinc-2.8.2/share/minizinc/0000755000175000017500000000000014536677021015425 5ustar kaolkaollibminizinc-2.8.2/share/minizinc/geas/0000755000175000017500000000000014536677021016344 5ustar kaolkaollibminizinc-2.8.2/share/minizinc/geas/fzn_table_int.mzn0000644000175000017500000000062114536677021021707 0ustar kaolkaolpredicate geas_table_int(array [int] of var int: x, array [int] of int: t); predicate fzn_table_int(array [int] of var int: x, array [int, int] of int: t) = assert (index_set_2of2(t) == index_set(x), "The second dimension of the table must equal the number of variables " ++ "in the first argument", geas_table_int(x, [ t[i,j] | i in index_set_1of2(t), j in index_set_2of2(t) ]) ); libminizinc-2.8.2/share/minizinc/geas/fzn_alldifferent_except_0.mzn0000644000175000017500000000024314536677021024174 0ustar kaolkaolpredicate fzn_alldifferent_except_0(array [int] of var int: x) = geas_all_different_except_0(x); predicate geas_all_different_except_0(array [int] of var int: x); libminizinc-2.8.2/share/minizinc/geas/fzn_disjunctive.mzn0000644000175000017500000000057114536677021022301 0ustar kaolkaol%predicate geas_disjunctive_var(array[int] of var int: s, % array[int] of var int: d); predicate geas_disjunctive(array[int] of var int: s, array[int] of int: d); %predicate disjunctive(array[int] of var int: s, array[int] of var int: d) = % geas_disjunctive_var(s, d); predicate fzn_disjunctive(array[int] of var int: s, array[int] of int: d) = geas_disjunctive(s, d); libminizinc-2.8.2/share/minizinc/geas/redefinitions.mzn0000644000175000017500000000637214536677021021744 0ustar kaolkaol%% New annotations annotation assume(array[int] of var bool: b); annotation int_priority(array[int] of var int: xs, array[int] of ann: br, ann: sel); annotation bool_priority(array[int] of var bool: xs, array[int] of ann: br, ann: sel); %% Half Reifications predicate int_eq_imp(var int: a, var int: b, var bool: r); predicate int_ne_imp(var int: a, var int: b, var bool: r); predicate int_le_imp(var int: a, var int: b, var bool: r); predicate int_lt_imp(var int: a, var int: b, var bool: r); predicate int_lin_eq_imp(array [int] of int: as, array [int] of var int: bs, int: c, var bool: r); predicate int_lin_ne_imp(array [int] of int: as, array [int] of var int: bs, int: c, var bool: r); predicate int_lin_le_imp(array [int] of int: as, array [int] of var int: bs, int: c, var bool: r); predicate bool_eq_imp(var bool: a, var bool: b, var bool: r); predicate bool_ne_imp(var bool: a, var bool: b, var bool: r); predicate bool_le_imp(var bool: a, var bool: b, var bool: r); predicate bool_lt_imp(var bool: a, var bool: b, var bool: r); predicate bool_or_imp(var bool: a, var bool: b, var bool: r); predicate bool_and_imp(var bool: a, var bool: b, var bool: r); predicate bool_xor_imp(var bool: a, var bool: b, var bool: r); predicate bool_clause_imp(array [int] of var bool: as, array [int] of var bool: bs, var bool: b); predicate array_bool_or_imp(array [int] of var bool: as, var bool: r); predicate array_bool_and_imp(array [int] of var bool: as, var bool: r); predicate bool_lin_eq_imp(array [int] of int: as, array [int] of var bool: bs, var int: c, var bool: r); predicate bool_lin_le_imp(array [int] of int: as, array [int] of var bool: bs, var int: c, var bool: r); predicate bool_lin_lt_imp(array [int] of int: as, array [int] of var bool: bs, var int: c, var bool: r); predicate bool_lin_ne_imp(array [int] of int: as, array [int] of var bool: bs, var int: c, var bool: r); %% Special cases for binary-ish x, y. predicate int_lin_eq_reif( array [int] of int: cs, array [int] of var int: xs, int: k, var bool: r) = let { var bool: a; var bool: b } in (r <-> (a /\ b)) /\ int_lin_le_reif(cs, xs, k, a) /\ int_lin_le_reif([-c | c in cs], xs, -k, b); predicate bool_xor(var bool: x, var bool: y, var bool: r) = bool_clause([x,y],[r]) /\ bool_clause([],[x,y,r]) /\ bool_clause([x, r], [y]) /\ bool_clause([y, r], [x]); predicate set_in_reif(var int: x, set of int: s, var bool: r) = if card(s) = max(s) - min(s) + 1 then r <-> (x >= min(s) /\ x <= max(s)) else bool_clause([x = k | k in s], [r]) /\ forall (k in s) (x = k -> r) endif; predicate int_pow(var int: x, var int: y, var int: z) = let { array [dom(x), dom(y)] of int: A = array2d( dom(x), dom(y), [ pow(a, b) | a in dom(x), b in dom(y) ] ); } in z = A[x, y]; predicate int_pow(var int: x, int: y, var int: z) = if y = 0 then z = 1 elseif y = 1 then z = x else let { var int: zp ::is_defined_var ; constraint int_pow(x, y div 2, zp) :: defines_var(zp); } in if y mod 2 = 0 then z = zp * zp else z = x * zp * zp endif endif; libminizinc-2.8.2/share/minizinc/geas/fzn_all_different_int.mzn0000644000175000017500000000022514536677021023416 0ustar kaolkaolpredicate fzn_all_different_int(array [int] of var int: x) = geas_all_different_int(x); predicate geas_all_different_int(array [int] of var int: x); libminizinc-2.8.2/share/minizinc/geas/fzn_inverse.mzn0000644000175000017500000000033514536677021021423 0ustar kaolkaolinclude "all_different.mzn"; predicate fzn_inverse(array [int] of var int: x, array [int] of var int: y) = alldifferent(x) /\ alldifferent(y) /\ forall (i in index_set(x), j in index_set(y)) (x[i] = j <-> y[j] = i); libminizinc-2.8.2/share/minizinc/geas/redefinitions-2.0.mzn0000644000175000017500000000206214536677021022231 0ustar kaolkaol% This file contains redefinitions of standard builtins that can be overridden % by solvers. predicate bool_clause_reif(array[int] of var bool: as, array[int] of var bool: bs, var bool: b) = clause(as,bs++[b]) /\ forall (i in index_set(as)) (as[i] -> b) /\ forall (i in index_set(bs)) (bs[i] \/ b); predicate array_float_maximum(var float: m, array[int] of var float: x) = let { int: l = min(index_set(x)), int: u = max(index_set(x)), float: ly = lb_array(x), float: uy = ub_array(x), array[l..u] of var ly..uy: y } in y[l] = x[l] /\ m = y[u] /\ forall (i in l+1 .. u) ( y[i] == max(x[i],y[i-1]) ); predicate array_float_minimum(var float: m, array[int] of var float: x) = let { int: l = min(index_set(x)), int: u = max(index_set(x)), float: ly = lb_array(x), float: uy = ub_array(x), array[l..u] of var ly..uy: y } in y[l] = x[l] /\ m = y[u] /\ forall (i in l+1 .. u) ( y[i] == min(x[i],y[i-1]) ); libminizinc-2.8.2/share/minizinc/geas/fzn_global_cardinality.mzn0000644000175000017500000000127014536677021023572 0ustar kaolkaolpredicate fzn_global_cardinality(array[int] of var int: x, array[int] of int: cover, array[int] of int: count) = geas_global_cardinality(x, cover, count); predicate fzn_global_cardinality(array[int] of var int: x, array[int] of int: cover, array[int] of var int: count) = forall (i in index_set(cover)) ( count[i] = sum (j in index_set(x)) (bool2int(x[j] = cover[i])) ); predicate geas_global_cardinality(array[int] of var int: x, array[int] of int: cover, array[int] of int: count); libminizinc-2.8.2/share/minizinc/geas/fzn_value_precede_int.mzn0000644000175000017500000000045214536677021023425 0ustar kaolkaolpredicate fzn_value_precede_int(int: s, int: t, array[int] of var int: x) = let { var index_set(x): pos_s; constraint forall (i in index_set(x)) ( (pos_s <= i) -> (x[i] = s) \/ (pos_s < i) ); } in forall(i in index_set(x)) ( (x[i] = t) -> (pos_s < i) ); libminizinc-2.8.2/share/minizinc/geas/fzn_cumulative.mzn0000644000175000017500000000115714536677021022131 0ustar kaolkaolpredicate geas_cumulative_var(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b); predicate geas_cumulative(array[int] of var int: s, array[int] of int: d, array[int] of int: r, int: b); predicate fzn_cumulative(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b) = geas_cumulative_var(s, d, r, b); %% TODO: once disjunctive propagator is fixed, add %% special case for b = 1. predicate fzn_cumulative(array[int] of var int: s, array[int] of int: d, array[int] of int: r, int: b) = geas_cumulative(s, d, r, b); libminizinc-2.8.2/share/minizinc/linear/0000755000175000017500000000000014536677021016677 5ustar kaolkaollibminizinc-2.8.2/share/minizinc/linear/fzn_lex_lesseq_bool.mzn0000644000175000017500000000107614536677021023465 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% include "fzn_lex_lesseq_int.mzn"; predicate fzn_lex_lesseq_bool(array[int] of var bool: x, array[int] of var bool: y) = fzn_lex_lesseq_int(x, y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/linear/redefs_lin_halfreifs.mzn0000644000175000017500000002074214536677021023567 0ustar kaolkaol/* % FlatZinc built-in redefinitions for linear solvers. % % AUTHORS % Sebastian Brand % Gleb Belov */ %-----------------------------------------------------------------------------% % Auxiliary: indicator constraints % p -> x # 0 where p is a 0/1 variable and # is a comparison % Base cases %% used e.g. in element predicate aux_float_eq_if_1(var float: x, var float: y, var int: p) = if is_fixed(p) then if 1==fix(p) then x==y else true endif elseif is_fixed(x) /\ is_fixed(y) then %%% Needed to avoid constant domain var if fix(x)!=fix(y) then p==0 else true endif elseif is_fixed(x-y) then %%% Hypothetically possible to land here if 0.0!=fix(x-y) then p==0 else true endif elseif fPostprocessDomains /\ fPostproDom_AUX /\ fPostproDom_DIFF then aux_float_eq_zero_if_1__POST(x - y, p, p) elseif fMZN__UseIndicators then aux_float_eq_if_1__IND(x, y, p) else aux_float_le_if_1(x, y, p) /\ aux_float_ge_if_1(x, y, p) endif; predicate aux_int_eq_if_1(var int: x, var int: y, var int: p) = if is_fixed(p) then if fix(p) = 1 then (x = y) else true endif elseif is_fixed(x) /\ is_fixed(y) then if fix(x) != fix(y) then (p = 0) else true endif % elseif is_fixed(x-y) then % TODO: Necessary for integers?? % if 0.0!=fix(x-y) then p==0 else true endif % elseif fPostprocessDomains /\ fPostproDom_AUX /\ fPostproDom_DIFF then % % TODO MIPDomains % elseif fMZN__UseIndicators then % TODO: Necessary for integers?? % aux_float_eq_if_1__IND(x, y, p) else aux_int_le_if_1(x, y, p) /\ aux_int_ge_if_1(x, y, p) endif; predicate aux_float_ne_if_1(var float: x, var float: y, var int: p) = if is_fixed(p) then if fix(p) = 1 then (x != y) else true endif elseif is_fixed(x) /\ is_fixed(y) then %%% Needed to avoid constant domain var if (fix(x) = fix(y)) then (p = 0) else true endif elseif is_fixed(x-y) then %%% Hypothetically possible to land here if (0.0 = fix(x-y)) then (p = 0) else true endif % TODO: What is necessary for not equals? % elseif fPostprocessDomains /\ fPostproDom_AUX /\ fPostproDom_DIFF then % aux_float_ne_zero_if_1__POST(x - y, p, p) % elseif fMZN__UseIndicators then % aux_float_ne_if_1__IND(x, y, p) else let { array[1..2] of var bool: q } in ( q[1] -> (x < y) ) /\ ( q[2] -> (x > y) ) /\ (sum(q) = p) endif; predicate aux_int_ne_if_1(var int: x, var int: y, var int: p) = if is_fixed(p) then if fix(p) = 1 then (x != y) else true endif elseif is_fixed(x) /\ is_fixed(y) then if fix(x) = fix(y) then (p = 0) else true endif % elseif is_fixed(x-y) then % TODO: Necessary for integers?? % if 0.0!=fix(x-y) then p==0 else true endif % elseif fPostprocessDomains /\ fPostproDom_AUX /\ fPostproDom_DIFF then % % TODO MIPDomains % elseif fMZN__UseIndicators then % TODO: Necessary for integers?? % aux_float_eq_if_1__IND(x, y, p) else let { array[1..2] of var bool: q } in ( q[1] -> (x < y) ) /\ ( q[2] -> (x > y) ) /\ (sum(q) = p) endif; predicate aux_int_le_zero_if_0(var int: x, var int: p) = if is_fixed(p) then if 0==fix(p) then x<=0 else true endif %% 0==fix !! elseif lb(x)>0 then p==1 elseif not (0 in dom(x)) then let { constraint assert( ub(x) < infinity, "aux_int_le_zero_if_0: variable \(x)'s domain: dom(\(x)) = \(dom(x)), should have finite upper bound\n" ), set of int: sDomNeg = dom(x) intersect -infinity..-1, constraint assert( card( sDomNeg ) > 0, "Variable \(x): dom(\(x)) = \(dom(x)), but dom() intersect -inf..-1: \(sDomNeg)\n" ), } in aux_int_le_if_0( x, max( sDomNeg ), p ) elseif fPostprocessDomains /\ fPostproDom_AUX then aux_int_le_zero_if_1__POST(x, 1-p) elseif fMZN__UseIndicators then aux_int_le_zero_if_0__IND(x, p) else assert( ub(x)0.0 then p==1 elseif fPostprocessDomains /\ fPostproDom_AUX then aux_float_le_zero_if_1__POST(x, 1-p, 1-p) elseif fMZN__UseIndicators then aux_float_le_zero_if_0__IND(x, p) else x <= ub(x) * p endif; predicate aux_float_lt_zero_if_0(var float: x, var int: p) = assert( has_bounds(x), "Variable \(x) needs finite bounds for a big-M constraint" ) /\ if is_fixed(p) then if 0==fix(p) then x<0.0 else true endif elseif lb(x)>=0.0 then p==1 elseif fPostprocessDomains /\ fPostproDom_AUX then aux_float_lt_zero_if_1__POST(x, 1-p, 1-p, float_lt_EPS) elseif fMZN__UseIndicators then aux_float_le_zero_if_0__IND(x+float_lt_EPS, p) %% Here just absolute EPS, TODO else %% let { float: rho = float_lt_EPS_coef__ * max(abs(ub(x)), abs(lb(x))) } % same order of magnitude as ub(x) let { float: rho = float_lt_EPS } % absolute eps in %%% This one causes 2x- derivation of EPS: %% x < (ub(x) + rho) * p %%% Better? x <= (ub(x) + rho) * p - rho %%% This just uses absolute eps: %% x < (ub(x) + float_lt_EPS) * p endif; % Derived cases predicate aux_int_le_if_0(var int: x, var int: y, var int: p) = aux_int_le_zero_if_0(x - y, p); predicate aux_int_ge_if_0(var int: x, var int: y, var int: p) = aux_int_le_zero_if_0(y - x, p); predicate aux_int_le_if_1(var int: x, var int: y, var int: p) = aux_int_le_zero_if_0(x - y, 1 - p); predicate aux_int_ge_if_1(var int: x, var int: y, var int: p) = aux_int_le_zero_if_0(y - x, 1 - p); predicate aux_int_lt_if_0(var int: x, var int: y, var int: p) = aux_int_le_zero_if_0(x - y + 1, p); predicate aux_int_gt_if_0(var int: x, var int: y, var int: p) = aux_int_le_zero_if_0(y - x + 1, p); predicate aux_int_lt_if_1(var int: x, var int: y, var int: p) = aux_int_le_zero_if_0(x - y + 1, 1 - p); predicate aux_int_gt_if_1(var int: x, var int: y, var int: p) = aux_int_le_zero_if_0(y - x + 1, 1 - p); %% int: switching differences to float to avoid creating integer vars /* Used anywhere? predicate aux_int_le_if_0(var float: x, var float: y, var int: p) = aux_float_le_zero_if_0(x - y, p); predicate aux_int_ge_if_0(var float: x, var float: y, var int: p) = aux_float_le_zero_if_0(y - x, p); predicate aux_int_le_if_1(var float: x, var float: y, var int: p) = aux_float_le_zero_if_0(x - y, 1 - p); predicate aux_int_ge_if_1(var float: x, var float: y, var int: p) = aux_float_le_zero_if_0(y - x, 1 - p); predicate aux_int_lt_if_0(var float: x, var float: y, var int: p) = aux_float_le_zero_if_0(x - y + 1.0, p); predicate aux_int_gt_if_0(var float: x, var float: y, var int: p) = aux_float_le_zero_if_0(y - x + 1.0, p); predicate aux_int_lt_if_1(var float: x, float: y, var int: p) = aux_float_le_zero_if_0(x - y + 1.0, 1 - p); */ predicate aux_float_le_if_0(var float: x, var float: y, var int: p) = aux_float_le_zero_if_0(x - y, p); predicate aux_float_ge_if_0(var float: x, var float: y, var int: p) = aux_float_le_zero_if_0(y - x, p); predicate aux_float_le_if_1(var float: x, var float: y, var int: p) = aux_float_le_zero_if_0(x - y, 1 - p); predicate aux_float_ge_if_1(var float: x, var float: y, var int: p) = aux_float_le_zero_if_0(y - x, 1 - p); predicate aux_float_lt_if_0(var float: x, var float: y, var int: p) = aux_float_lt_zero_if_0(x - y, p); predicate aux_float_gt_if_0(var float: x, var float: y, var int: p) = aux_float_lt_zero_if_0(y - x, p); predicate aux_float_lt_if_1(var float: x, var float: y, var int: p) = aux_float_lt_zero_if_0(x - y, 1 - p); predicate aux_float_gt_if_1(var float: x, var float: y, var int: p) = aux_float_lt_zero_if_0(y - x, 1 - p); % -------------------------- Domains postpro --------------------------- %% To avoid looking if an original int var x-y exists and has eq_encode: %% Passing both int and float version of the indicator for flexibility: predicate aux_float_eq_zero_if_1__POST(var float: x, var int: pI, var float: p); predicate aux_int_le_zero_if_1__POST(var int: x, var int: p); predicate aux_float_le_zero_if_1__POST(var float: x, var int: pI, var float: p); predicate aux_float_lt_zero_if_1__POST(var float: x, var int: pI, var float: p, float: eps); libminizinc-2.8.2/share/minizinc/linear/redefs_bool_imp.mzn0000644000175000017500000000534114536677021022560 0ustar kaolkaolinclude "redefs_lin_halfreifs.mzn"; % SIMPLE BOOLEAN LOGIC % TODO: why not check "is_fixed(r)" everywhere?? predicate bool_eq_imp(var bool: p, var bool: q, var bool: r ::promise_ctx_antitone) = if is_fixed(r) then if fix(r) then p = q else true endif else let { var int: x = bool2int(p), var int: y = bool2int(q), var int: z = bool2int(r) } in x + z <= y + 1 /\ y + z <= x + 1 endif; predicate bool_ne_imp(var bool: p, var bool: q, var bool: r ::promise_ctx_antitone) = bool_xor_imp(p, q, r); predicate bool_le_imp(var bool: p ::promise_ctx_antitone, var bool: q ::promise_ctx_monotone, var bool: r ::promise_ctx_antitone) = let { var int: x = bool2int(p), var int: y = bool2int(q), var int: z = bool2int(r), } in 1 - x + y >= z; predicate bool_lt_imp(var bool: p ::promise_ctx_antitone, var bool: q ::promise_ctx_monotone, var bool: r ::promise_ctx_antitone) = bool_and_imp(not p, q, r); predicate bool_or_imp(var bool: p ::promise_ctx_monotone, var bool: q ::promise_ctx_monotone, var bool: r ::promise_ctx_antitone) = array_bool_or_imp([p,q], r); predicate bool_and_imp(var bool: p ::promise_ctx_monotone, var bool: q ::promise_ctx_monotone, var bool: r ::promise_ctx_antitone) = array_bool_and_imp([p,q],r); predicate bool_xor_imp(var bool: p, var bool: q, var bool: r ::promise_ctx_antitone) = let { var int: x = bool2int(p), var int: y = bool2int(q), var int: z = bool2int(r), } in x + y >= z /\ x + y + z <= 2; % BOOLEAN ARRAY OPERATIONS predicate array_bool_or_imp(array[int] of var bool: a ::promise_ctx_monotone, var bool: b ::promise_ctx_antitone) = if forall( i in index_set( a ) )( is_fixed(a[i]) /\ not fix(a[i]) ) then not b elseif exists( i in index_set( a ) )( is_fixed(a[i]) /\ fix(a[i]) ) then true else let { array[index_set(a)] of var bool: a1; var int: x = bool2int(b), } in forall(i in index_set(a)) (a1[i] -> a[i]) /\ sum(a1) = x endif; predicate array_bool_and_imp(array[int] of var bool: a ::promise_ctx_monotone, var bool: b ::promise_ctx_antitone) = if is_fixed(b) then if fix(b) then forall(i in index_set(a))( a[i] ) else true endif elseif forall( i in index_set( a ) )( is_fixed(a[i]) /\ fix(a[i]) ) then true else let { var int: x = bool2int(b), array[index_set(a)] of var int: c = array1d(index_set(a), [ bool2int(a[i] ) | i in index_set(a) ]) } in forall(i in index_set(c)) ( c[i] >= x ) endif; %% No var int d, sorry TODO: why not??? predicate bool_lin_eq_imp(array[int] of int: c, array[int] of var bool: x, int: d, var bool: b ::promise_ctx_antitone) = aux_int_eq_if_1(sum(i in index_set(x))( c[i]*bool2int(x[i]) ), d, bool2int(b)); libminizinc-2.8.2/share/minizinc/linear/redefs_lin_imp.mzn0000644000175000017500000001406014536677021022405 0ustar kaolkaolinclude "redefs_lin_halfreifs.mzn"; include "redefs_lin_reifs.mzn"; %% var, var predicate int_le_imp(var int: x, var int: y, var bool: b) = if is_fixed(b) then if fix(b) then x<=y else true endif elseif ub(x)<=lb(y) then true elseif lb(x)>ub(y) then (not b) else aux_int_le_if_1(x, y, b) endif; %% var, var predicate int_lt_imp(var int: x, var int: y, var bool: b) = if is_fixed(x) then int_le_imp(x + 1, y, b) else int_le_imp(x, y - 1, b) endif; %% var, var predicate int_eq_imp(var int: x, var int: y, var bool: b) = if is_fixed(b) then if fix(b) then (x = y) else true endif elseif card( dom(x) intersect dom(y) ) > 0 then if is_fixed(x) then if is_fixed(y) then b -> (fix(x) = fix(y)) else int_eq_imp(y, fix(x), b) endif elseif is_fixed(y) then int_eq_imp(x, fix(y), b) else %% Simple disjunction aux_int_eq_if_1(x, y, b) endif else not b endif; %% var, const predicate int_eq_imp(var int: x, int: y, var bool: b) = if is_fixed(b) then if fix(b) then (x = y) else true endif elseif y in dom(x) then if is_fixed(x) then b -> (y = fix(x)) else aux_int_eq_if_1(x, y, b) %% Simple disjunction endif else not b endif; %%%%%%%%%%%%%%%%%%%%%%%%%%%% NOTE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% Omitting int_(lin)_ne_imp %%%%%%%%%%%%%%%%%%% %% so it falls back to _reif, full reification, for performance %% %% TODO also for floats %% %-----------------------------------------------------------------------------% %% lin_expr, const predicate int_lin_le_imp(array[int] of int: c, array[int] of var int: x, int: d, var bool: b) = if (d = 0) /\ (length(c) = 2) /\ (abs(c[1]) = 1) /\ (c[1] = -1 * c[2]) then if (c[1] < 0) then int_le_imp(x[2], x[1], b) else int_le_imp(x[1], x[2], b) endif elseif fPostprocessDomains /\ fPostproDom_DIFF then int_le_imp(sum(i in index_set(x))(c[i] * x[i]), d, b) elseif fAvoidNI then aux_float_le_if_1(sum2float(c, x), d, b) else aux_int_le_if_1(sum(i in index_set(x))(c[i] * x[i]), d, b) endif; predicate int_lin_lt_imp(array[int] of int: c, array[int] of var int: x, int: d, var bool: b) = if true then abort("int_lin_lt_imp not supposed to be called") else int_lin_le_imp(c, x, d - 1, b) endif; %% lin_expr, const predicate int_lin_eq_imp(array[int] of int: c, array[int] of var int: x, int: d, var bool: b) = if (d = 0) /\ (length(c) = 2) /\ (abs(c[1]) = 1) /\ (c[1] = -1 * c[2]) then int_eq_imp(x[1], x[2], b) elseif fPostprocessDomains /\ fPostproDom_DIFF then int_eq_imp(sum(i in index_set(x))(c[i] * x[i]), d, b) elseif fAvoidNI then aux_float_eq_if_1(sum2float(c, x), d, b) else aux_int_eq_if_1(sum(i in index_set(x))(c[i] * x[i]), d, b) endif; %-----------------------------------------------------------------------------% %% var float, var float predicate float_le_imp(var float: x, var float: y, var bool: b) = if is_fixed(b) then if fix(b) then x <= y else true endif elseif ub(x) <= lb(y) then true elseif lb(x) > ub(y) then (not b) else aux_float_le_if_1(x, y, b) endif; %% var float, var float predicate float_lt_imp(var float: x, var float: y, var bool: b) = if is_fixed(b) then if fix(b) then (x < y) else true endif else aux_float_lt_if_1(x, y, b) endif; %% var float, var float predicate float_eq_imp(var float: x, var float: y, var bool: b) = if is_fixed(b) then if fix(b) then (x = y) else true endif elseif (ub(x) < lb(y)) \/ (lb(x) > ub(y)) then not b elseif is_fixed(x) /\ is_fixed(y) then b -> (fix(x) == fix(y)) else aux_float_eq_if_1(x, y, b) endif; %% var float, var float predicate float_ne_imp(var float: x, var float: y, var bool: b) = if is_fixed(b) then if fix(b) then (x != y) else true endif elseif (ub(x) < lb(y)) \/ (lb(x) > ub(y)) then true elseif is_fixed(x) /\ is_fixed(y) then b -> (fix(x) != fix(y)) else aux_float_ne_if_1(x, y, b) endif; %-----------------------------------------------------------------------------% predicate float_lin_eq_imp(array[int] of float: c, array[int] of var float: x, float: d, var bool: b) = if (d = 0.0) /\ (length(c) = 2) /\ (abs(c[1]) = 1.0) /\ (c[1] = -1.0 * c[2]) then float_eq_imp(x[1], x[2], b) elseif fPostprocessDomains /\ fPostproDom_DIFF then float_eq_imp(sum(i in index_set(x))(c[i] * x[i]), d, b) else aux_float_eq_if_1(sum(i in index_set(x))(c[i] * x[i]), d, b) endif; predicate float_lin_ne_imp(array[int] of float: c, array[int] of var float: x, float: d, var bool: b) = if (d = 0.0) /\ (length(c) = 2) /\ (abs(c[1]) = 1.0) /\ (c[1] = -1.0 * c[2]) then float_ne_imp(x[1], x[2], b) elseif fPostprocessDomains /\ fPostproDom_DIFF then float_ne_imp(sum(i in index_set(x))(c[i] * x[i]), d, not b) else aux_float_ne_if_1(sum(i in index_set(x))(c[i] * x[i]), d, b) endif; predicate float_lin_le_imp(array[int] of float: c, array[int] of var float: x, float: d, var bool: b) = if (d = 0.0) /\ (length(c) = 2) /\ (abs(c[1]) = 1.0) /\ (c[1] = -1.0 * c[2]) then if (c[1] < 0.0) then float_le_imp(x[2], x[1], b) else float_le_imp(x[1], x[2], b) endif elseif fPostprocessDomains /\ fPostproDom_DIFF then float_le_imp(sum(i in index_set(x))(c[i] * x[i]), d, b) else aux_float_le_if_1(sum(i in index_set(x))(c[i] * x[i]), d, b) endif; predicate float_lin_lt_imp(array[int] of float: c, array[int] of var float: x, float: d, var bool: b) = if (d = 0.0) /\ (length(c) = 2) /\ (abs(c[1]) = 1.0) /\ (c[1] = -1.0 * c[2]) then if (c[1] < 0.0) then float_lt_imp(x[2], x[1], b) else float_lt_imp(x[1], x[2], b) endif elseif fPostprocessDomains /\ fPostproDom_DIFF then float_lt_imp(sum(i in index_set(x))(c[i] * x[i]), d, b) else aux_float_lt_if_1(sum(i in index_set(x))(c[i] * x[i]), d, b) endif; libminizinc-2.8.2/share/minizinc/linear/fzn_lex_less_float.mzn0000644000175000017500000000271514536677021023312 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_less_float(array[int] of var float: x, array[int] of var float: y) = assert(length(x) == length(y), "lex_less_float(\(x), \(y)): arrays of different lengths") /\ fzn_lex_less_float__MIP(x, y); predicate fzn_lex_less_float__MIP(array[int] of var float: x, array[int] of var float: y) = if length(y) = 0 then false elseif length(x) = 0 then true else let { int: lx = min(index_set(x)), int: ux = max(index_set(x)), int: ly = min(index_set(y)), int: uy = max(index_set(y)), int: size = min(ux - lx, uy - ly), array[0..size] of var 0..1: fEQ; array[0..size] of var 0..1: fLT; } in sum(fLT) == 1 /\ fEQ[0] + fLT[0] == 1 /\ forall(i in 1..size) ( fEQ[i-1] == fEQ[i] + fLT[i] ) /\ forall(i in 0..size) ( aux_float_eq_if_1(x[lx+i], y[ly+i], fEQ[i]) /\ aux_float_lt_if_1(x[lx+i], y[ly+i], fLT[i]) ) endif; %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/linear/redefs_bool_reifs.mzn0000644000175000017500000001341614536677021023105 0ustar kaolkaol/* % FlatZinc built-in redefinitions for linear solvers. % % AUTHORS % Sebastian Brand % Gleb Belov */ %-----------------------------------------------------------------------------% % % Logic operations % Use indicators for reifs (CPLEX)? Seems weak. % %-----------------------------------------------------------------------------% predicate bool_not(var bool: p) = bool2int(p)=0; predicate bool_not(var bool: p, var bool: q) = bool2int(p) + bool2int(q) = 1; predicate bool_and(var bool: p, var bool: q, var bool: r) = % my_trace(" bool_and: \(p) /\\ \(q) <-> \(r) \n") /\ if false then int_lin_le_reif__IND( [-1, -1], [p, q], -2, r) else array_bool_and( [p, q], r ) % bool_and__INT(bool2int(p), bool2int(q), bool2int(r)) endif; predicate bool_and__INT(var int: x, var int: y, var int: z) = x + y <= z + 1 /\ %% x + y >= z * 2; % weak x >= z /\ y >= z; % strong predicate bool_or(var bool: p, var bool: q, var bool: r) = if false then int_lin_le_reif__IND( [-1, -1], [p, q], -1, r) elseif true then array_bool_or( [p, q], r ) else let { var int: x = bool2int(p), var int: y = bool2int(q), var int: z = bool2int(r) } in x + y >= z /\ % x + y <= z * 2; % weak x <= z /\ y <= z % strong endif; predicate bool_xor(var bool: p, var bool: q) = 1==p+q; predicate bool_xor(var bool: p, var bool: q, var bool: r) = if false then % int_lin_eq_reif__IND( [1, 1], [p, q], 1, r) /\ true else let { var int: x = bool2int(p), var int: y = bool2int(q), var int: z = bool2int(r) } in x <= y + z /\ y <= x + z /\ z <= x + y /\ x + y + z <= 2 endif; predicate bool_eq_reif(var bool: p, var bool: q, var bool: r) = %% trace(" bool_eq_reif: \(p), \(q), \(r) \n") /\ if is_fixed(r) then % frequent case if fix(r) = true then p = q else bool_not(p,q) endif elseif is_fixed(q) then if fix(q) = true then p = r else bool_not(p,r) endif elseif is_fixed(p) then if fix(p) = true then q = r else bool_not(q,r) endif elseif false then % int_lin_eq_reif__IND( [1, -1], [p, q], 0, r) /\ true else let { var int: x = bool2int(p), var int: y = bool2int(q), var int: z = bool2int(r) } in x + y <= z + 1 /\ x + z <= y + 1 /\ y + z <= x + 1 /\ x + y + z >= 1 endif; predicate bool_ne_reif(var bool: p, var bool: q, var bool: r) = bool_xor(p, q, r); predicate bool_le(var bool: p ::promise_ctx_antitone, var bool: q ::promise_ctx_monotone) = let { var int: x ::promise_ctx_antitone = bool2int(p), var int: y ::promise_ctx_monotone = bool2int(q) } in x <= y; predicate bool_le_reif(var bool: p, var bool: q, var bool: r) = if false then % int_lin_le_reif__IND( [1, -1], [p, q], 0, r) /\ true else let { var int: x = bool2int(p), var int: y = bool2int(q), var int: z = bool2int(r) } in 1 - x + y >= z /\ %% /\ 1 - x + y <= z * 2 not needed 1 - x <= z /\ y <= z % strong endif; predicate bool_lt(var bool: p ::promise_ctx_antitone, var bool: q ::promise_ctx_monotone) = not p /\ q; predicate bool_lt_reif(var bool: p, var bool: q, var bool: r) = (not p /\ q) <-> r; %-----------------------------------------------------------------------------% %% Reified disjunction predicate array_bool_or(array[int] of var bool: a, var bool: b) = if exists( i in index_set( a ) )( is_fixed(a[i]) /\ fix(a[i]) ) then b elseif is_fixed(b) then % frequent case if fix(b) = true then sum(i in index_set(a))( bool2int(a[i]) ) >= 1 %% >=1 seems better for MIPDomains... 5.4.19 else forall(i in index_set(a))( not a[i] ) endif else let { var int: x = bool2int(b), array[1..length(a)] of var int: c = [ bool2int(a[i]) | i in index_set(a) ] } in sum(c) >= x /\ % sum(c) <= x * length(a) % weak forall (i in index_set(a)) (x >= c[i]) % strong endif; %% Reified conjunction predicate array_bool_and(array[int] of var bool: a, var bool: b) = if exists( i in index_set( a ) )( is_fixed(a[i]) /\ not fix(a[i]) ) then not b elseif is_fixed(b) then % frequent case if fix(b) = false then sum(i in index_set(a))( bool2int(a[i]) ) <= length(a)-1 else forall(i in index_set(a))( a[i] ) endif else let { var int: x = bool2int(b), array[1..length(a)] of var int: c = [ bool2int(a[i]) | i in index_set(a) ] } in length(a) - sum(c) >= 1 - x /\ % length(a) - sum(c) <= (1 - x) * length(a); % weak forall (i in index_set(a)) (x <= c[i]) % strong endif; % predicate array_bool_xor(array[int] of var bool: a) = .. sum(a) is odd .. predicate array_bool_xor(array[int] of var bool: a) = let { var 0..(length(a)-1) div 2: m, var 1..((length(a)-1) div 2)*2+1: ss = sum(i in index_set(a))( bool2int(a[i]) ) } in ss == 1 + 2 * m; predicate bool_clause(array[int] of var bool: p ::promise_ctx_monotone, array[int] of var bool: n ::promise_ctx_antitone) = sum(i in index_set(p))( bool2int(p[i]) ) - sum(i in index_set(n))( bool2int(n[i]) ) + length(n) >= 1; predicate bool_lin_eq(array[int] of int: c, array[int] of var bool: x, var int: d) :: promise_total = sum(i in index_set(x))( c[i]*bool2int(x[i]) ) == d; predicate bool_lin_eq_reif(array[int] of int: c, array[int] of var bool: x, int: d, var bool: b) = %% No var int d, sorry aux_int_eq_iff_1(sum(i in index_set(x))( c[i]*bool2int(x[i]) ), d, bool2int(b)); libminizinc-2.8.2/share/minizinc/linear/fzn_lex_chain_lesseq_orbitope.mzn0000644000175000017500000000220114536677021025506 0ustar kaolkaolinclude "lex_lesseq.mzn"; predicate fzn_lex_chain_lesseq_orbitope( array[int, int] of var int: a, int: kind) = if MZN__Orbitope then fzn_lex_chain_lesseq__orbitope( array1d(a), card(index_set_1of2(a)), kind, true, not mzn_in_symmetry_breaking_constraint() ) else fzn_lex_chain_lesseq_orbitope__CP(a, kind) endif; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SCIP 7.0.2, binary matrix, columns sorted predicate fzn_lex_chain_lesseq__orbitope(array[int] of var int: matr, int: m, int: orbType, bool: resolveprop, bool: isModelCons); predicate fzn_lex_chain_lesseq_orbitope__CP( array[int, int] of var int: a, int: kind) = let { set of int: is2 = index_set_2of2(a); } in ( forall(j in is2 where j+1 in is2) ( lex_lesseq(col(a, j), col(a, j+1)) ) /\ if 1==kind then forall(i in index_set_1of2(a))( 1 == sum(row(a, i)) ) elseif 2==kind then forall(i in index_set_1of2(a))( 1 >= sum(row(a, i)) ) else true endif ); libminizinc-2.8.2/share/minizinc/linear/fzn_table_int.mzn0000644000175000017500000000134714536677021022250 0ustar kaolkaol%-----------------------------------------------------------------------------% % A 'table' constraint table(x, T) represents the constraint x in T where we % consider each row in T to be a tuple and T as a set of tuples. % % Linear version. % % See also the equality encoding of the 'element' constraint. %-----------------------------------------------------------------------------% predicate fzn_table_int(array[int] of var int: x, array[int, int] of int: t) = let { set of int: it = index_set_1of2(t), array[it] of var 0..1: lambda } in sum(lambda) = 1 /\ forall(j in index_set(x))( sum(i in it)( t[i,j]*lambda[i] ) = x[j] ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/linear/fzn_alldifferent_except_0.mzn0000644000175000017500000000122114536677021024524 0ustar kaolkaol/** @group globals.alldifferent Constrain the array of integers \a vs to be all different except those elements that are assigned the value 0. */ predicate fzn_alldifferent_except_0(array[int] of var int: vs) = % forall(i, j in index_set(vs) where i < j) ( % (vs[i] != 0 /\ vs[j] != 0) -> vs[i] != vs[j] % ); if length(vs)<=1 then true else let { array[int,int] of var 0..1: x_eq_d = eq_encode(vs) } in ( % my_trace(" alldifferent_except_0: x[" ++ show(index_set(vs)) ++ "]\n") /\ forall(d in index_set_2of2(x_eq_d) diff {0})( sum(i in index_set_1of2(x_eq_d))( x_eq_d[i,d] ) <= 1 ) ) endif; libminizinc-2.8.2/share/minizinc/linear/fzn_sliding_sum.mzn0000644000175000017500000000061014536677021022614 0ustar kaolkaolpredicate fzn_sliding_sum(int: low, int: up, int: seq, array[int] of var int: vs) = let { int: lx = min(index_set(vs)), int: ux = max(index_set(vs)), } in forall (i in lx .. ux - seq + 1) ( let { var int: sum_of_l = sum(j in i..i + seq - 1) (vs[j]) } in low <= sum_of_l /\ sum_of_l <= up ); libminizinc-2.8.2/share/minizinc/linear/domain_encodings.mzn0000644000175000017500000001033614536677021022730 0ustar kaolkaol/*%-----------------------------------------------------------------------------% % Domain encodings %-----------------------------------------------------------------------------% */ % Linear equality encoding % Single variable: x = d <-> x_eq_d[d] predicate equality_encoding(var int: x, array[int] of var int: x_eq_d) = x in index_set(x_eq_d) /\ sum(d in dom(x))( x_eq_d[d] ) = 1 /\ sum(d in dom(x))( d * x_eq_d[d] ) = x /\ % my_trace( "eq_enc: \(x), index_set(pp)=" ++ show(index_set( x_eq_d )) ++ "\n" ) /\ if fPostprocessDomains then equality_encoding__POST(x, x_eq_d) else true endif ; % Two variables: x = d /\ y = e <-> x_eq_d[d] /\ y_eq_e[e] /\ xy_eq_de[d, e] predicate equality_encoding(var int: x, var int: y, array[int] of var int: x_eq_d, array[int] of var int: y_eq_e, array[int, int] of var int: xy_eq_de ) = x in index_set(x_eq_d) /\ y in index_set(y_eq_e) /\ index_set(x_eq_d) == index_set_1of2(xy_eq_de) /\ index_set(y_eq_e) == index_set_2of2(xy_eq_de) /\ sum(d in dom(x), e in dom(y))( xy_eq_de[d, e] ) = 1 /\ forall(d in dom(x)) (sum(e in dom(y))( xy_eq_de[d, e] ) = x_eq_d[d]) /\ forall(e in dom(y)) (sum(d in dom(x))( xy_eq_de[d, e] ) = y_eq_e[e]) ; % Array of variables: x[i] = d <-> x_eq_d[i,d] predicate equality_encoding(array[int] of var int: x, array[int, int] of var int: x_eq_d) = forall(i in index_set(x))( x[i] in index_set_2of2(x_eq_d) /\ sum(d in index_set_2of2(x_eq_d))( x_eq_d[i,d] ) = 1 /\ sum(d in index_set_2of2(x_eq_d))( d * x_eq_d[i,d] ) = x[i] ); function var int: eq_new_var(var int: x, int: i) ::promise_total = if i in dom(x) then let { var 0..1: xi; } in xi else 0 endif; function array[int] of var int: eq_encode(var int: x) ::promise_total = let { array[int] of var int: y = array1d(lb(x)..ub(x),[eq_new_var(x,i) | i in lb(x)..ub(x)]); constraint equality_encoding(x,y); % constraint % if card(dom(x))>0 then % my_trace(" eq_encode: dom(\(x)) = " ++ show(dom(x)) ++ ", card( dom(\(x)) ) = " ++ show(card(dom(x))) ++ "\n") % else true endif; %% constraint assert(card(dom(x))>1, " eq_encode: card(dom(\(x))) == " ++ show(card(dom(x)))); } in y; function array[int] of int: eq_encode(int: x) ::promise_total = array1d(lb(x)..ub(x),[ if i=x then 1 else 0 endif | i in lb(x)..ub(x)]); %%% The same for 2 variables: function var int: eq_new_var(var int: x, int: i, var int: y, int: j) ::promise_total = if i in dom(x) /\ j in dom(y) then let { var 0..1: xi; } in xi else 0 endif; function array[int, int] of var int: eq_encode(var int: x, var int: y) ::promise_total = let { array[int] of var int: pX = eq_encode(x), array[int] of var int: pY = eq_encode(y), array[int, int] of var int: pp = array2d(index_set(pX), index_set(pY), [eq_new_var(x,i,y,j) | i in index_set(pX), j in index_set(pY)]); constraint equality_encoding(x, y, pX, pY, pp); } in pp; function array[int, int] of int: eq_encode(int: x, int: y) ::promise_total = % let { % constraint if card(dom(x))*card(dom(y))>200 then % my_trace(" eq_encode: dom(\(x)) = " ++ show(dom(x)) ++ ", dom(\(y)) = " ++ show(dom(y)) ++ "\n") % else true endif; % } in array2d(lb(x)..ub(x), lb(y)..ub(y), [if i==x /\ j==y then 1 else 0 endif | i in lb(x)..ub(x), j in lb(y)..ub(y)]); function array[int,int] of var int: eq_encode(array[int] of var int: x) ::promise_total = let { array[index_set(x),lb_array(x)..ub_array(x)] of var int: y = array2d(index_set(x),lb_array(x)..ub_array(x), [ let { array[int] of var int: xi = eq_encode(x[i]) } in if j in index_set(xi) then xi[j] else 0 endif | i in index_set(x), j in lb_array(x)..ub_array(x)] ) } in y; function array[int,int] of int: eq_encode(array[int] of int: x) ::promise_total = array2d(index_set(x),lb_array(x)..ub_array(x),[ if j=x[i] then 1 else 0 endif | i in index_set(x), j in lb_array(x)..ub_array(x)]); %-----------------------------------------------------------------------------% %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/linear/redefinitions.mzn0000644000175000017500000007060414536677021022276 0ustar kaolkaol/* % FlatZinc built-in redefinitions for linear solvers. % % AUTHORS % Sebastian Brand % Gleb Belov (2015-) % cf. Belov, Stuckey, Tack, Wallace. Improved Linearization of Constraint Programming Models. CP 2016. */ %----------------------------- BOOL2INT --------------------------------% function var bool: reverse_map(var int: x) = (x==1); function bool: reverse_map(int: x) = (x==1); predicate mzn_reverse_map_var(var bool: b) = let { var int: x = bool2int(b) } in true; function var int: bool2int(var bool: x) :: promise_total = let { var 0..1: b2i; constraint (x = reverse_map(b2i)) ::is_reverse_map ; } in b2i; predicate bool_eq(var bool: x, var bool: y) = %% trace(" bool_eq: \(x), \(y) \n") /\ bool2int(x)==bool2int(y); predicate bool2int(var bool: x, var int: y) = y = bool2int(x); %---------------------------- BASIC (HALF)REIFS -----------------------------% include "options.mzn"; include "redefs_bool_reifs.mzn"; include "redefs_bool_imp.mzn"; include "domain_encodings.mzn"; include "redefs_lin_reifs.mzn"; include "redefs_lin_imp.mzn"; include "redefs_lin_halfreifs.mzn"; include "nosets.mzn"; %% For set_le, set_lt ... Usind std/nosets %% as long as the linearization is good. %-----------------------------------------------------------------------------% % Strict inequality % Uncomment the following redefinition for FlatZinc MIP solver interfaces that % do not support strict inequality. Note that it does not preserve equivalence % (some solutions of the original problem may become invalid). predicate float_lt(var float: x ::promise_ctx_antitone, var float: y ::promise_ctx_monotone) = % (x - y) <= (-float_lt_EPS_coef__)*max(abs(ub(x - y)), abs(ub(y-x))); x <= y - float_lt_EPS; predicate float_lin_lt(array[int] of float: c, array[int] of var float: x, float: d) = float_lt(sum(i in index_set(x))( c[i]*x[i] ), d); %-----------------------------------------------------------------------------% % Minimum, maximum, absolute value % Use unary as well? TODO predicate int_abs(var int: x, var int: z) = %% The simplifications seem worse on league.mzn model90-18-20.dzn: %% but the .lp seem to differ just by order...?? TODO if lb(x)>=0 then z==x elseif ub(x)<=0 then z==-x else let { var bool: p } in z >= x /\ z >= -x /\ z >= 0 /\ % This is just for preprocessor z <= max([ub(x), -lb(x)]) /\ % And this % z <= x \/ z <= -x %% simple aux_int_le_if_1(z, x, p) /\ %% even simpler aux_int_le_if_0(z, -x, p) /\ int_le_reif(0, x, p) % with reifs %int_eq_reif(z, x, p) /\ %int_eq_reif(z, -x, not p) endif ; predicate int_min(var int: x, var int: y, var int: z) = array_int_minimum(z, [x, y]); predicate int_max(var int: x, var int: y, var int: z) = array_int_maximum(z, [x, y]); predicate float_abs(var float: x, var float: z) = if lb(x)>=0.0 then z==x elseif ub(x)<=0.0 then z==-x else let { var bool: p } in z >= x /\ z >= -x /\ z >= 0.0 /\ % This is just for preprocessor z <= max([ub(x), -lb(x)]) /\ % And this % z <= x \/ z <= -x aux_float_le_if_1(z, x, (p)) /\ aux_float_le_if_0(z, -x, (p)) % /\ % float_le_reif(0.0, x, p) % with reifs - no point for floats? TODO % float_eq_reif(z, x, p) /\ % float_eq_reif(z, -x, not p) endif; predicate float_min(var float: x, var float: y, var float: z) = array_float_minimum(z, [x, y]); predicate float_max(var float: x, var float: y, var float: z) = array_float_maximum(z, [x, y]); predicate array_int_minimum_I(var int: m, array[int] of var int: x) = let { int: n = length(x), constraint assert(1 == min(index_set(x)), " array_int_minimum_I: argument indexed not from 1??"), int: iMinUB = arg_min([ub(x[i]) | i in 1..n]), int: MinUB = ub(x[iMinUB]), set of int: sLBLess = { i | i in 1..n where lb(x[i])0 then sLBLess else sLBLess union { iMinUB } endif, } in if 1==card(sActive) then m == x[min(sActive)] elseif MZN__MinMaxGeneral then fzn_array_float_minimum(m, x) %% Send to backend else let { array[1..n] of var int: p = [ if i in sActive then let { var 0..1: pi } in pi else 0 endif | i in 1..n ], constraint 1==sum(p), constraint m >= lb_array(x), constraint m <= MinUB, } in forall (i in index_set(x)) ( if i in sActive %% for at least 1 element then m<=x[i] /\ aux_int_ge_if_1(m, x[i], p[i]) endif ) %% -- exclude too big x[i] endif; predicate array_float_minimum_I(var float: m, array[int] of var float: x) = let { int: n = length(x), constraint assert(1 == min(index_set(x)), " array_float_minimum_I: argument indexed not from 1??"), int: iMinUB = arg_min([ub(x[i]) | i in 1..n]), float: MinUB = ub(x[iMinUB]), set of int: sLBLess = { i | i in 1..n where lb(x[i])0 then sLBLess else sLBLess union { iMinUB } endif, } in if 1==card(sActive) then m == x[min(sActive)] elseif MZN__MinMaxGeneral then fzn_array_float_minimum(m, x) %% Send to backend else let { array[1..n] of var int: p = [ if i in sActive then let { var 0..1: pi } in pi else 0 endif | i in 1..n ], constraint 1==sum(p), constraint m >= lb_array(x), constraint m <= MinUB, } in forall (i in index_set(x)) ( if i in sActive %% for at least 1 element then m<=x[i] /\ aux_float_ge_if_1(m, x[i], p[i]) endif ) %% -- exclude too big x[i] /\ if card(sActive)>1 /\ fMinimumCutsXZ then let { array[int] of float: AL = [ lb(x[i]) | i in 1..n], array[int] of int: srt = sort_by([i | i in 1..n], AL), %indices of lb in sorted order array[int] of float: AL_srt = [AL[srt[i]] | i in 1..n], array[int] of float: AU_srt = [ub(x[srt[i]]) | i in 1..n], array[int] of float: AM_srt = AL_srt ++ [MinUB] %% -- these are z-levels of extreme points } in forall (i in 2..n+1 where AM_srt[i]<=MinUB /\ %% this is a new "start level" AM_srt[i]!=AM_srt[i-1] )( %% and would produce a new cut m >= AM_srt[i] - sum(j in 1..i-1 where AL_srt[j]1 /\ fMinimumCutsXZB then array_var_float_element__XBZ_lb([ -x[i] | i in sActive ], [ p[i] | i in sActive ], -m) :: MIP_cut else true endif endif; %-----------------------------------------------------------------------------% % Multiplication and division predicate int_div(var int: x, var int: y, var int: q) = q == aux_int_division_modulo_fn(x,y)[1]; predicate int_mod(var int: x, var int: y, var int: r) = r == aux_int_division_modulo_fn(x,y)[2]; function array[int] of var int: aux_int_division_modulo_fn(var int: x, var int: y) = let { %% Domain of q set of int: dom_q = if lb(y)*ub(y)>0 then let { set of int: EP = { ub(x) div ub(y), ub(x) div lb(y), lb(x) div ub(y), lb(x) div lb(y) }, } in min(EP)..max(EP) else let { int: mm = max( abs(lb(x)), abs(ub(x)) ), } in -mm..mm %% TODO case when -1 or 1 not in dom(x) endif, var dom_q: q; int: by = max(abs(lb(y)), abs(ub(y))); var -by+1..by-1: r; constraint x = y * q + r, constraint 0 <= x -> 0 <= r, %% which is 0 > x \/ 0 <= r constraint x < 0 -> r <= 0, %% which is x >= 0 \/ r <= 0 % abs(r) < abs(y) var 1.. max(abs(lb(y)), abs(ub(y))): w = abs(y), constraint w > r /\ w > -r, } in [ q, r ]; %% Can also have int_times(var float, var int) ......... TODO %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% predicate float_div(var float: x, var float: y, var float: q) = x == y * q; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% predicate int_times(var int: x, var int: y, var int: z) = if is_fixed(x) then z==fix(x)*y %%%%% Need to use fix() otherwise added to CSE & nothing happens elseif is_fixed(y) then z==x*fix(y) elseif is_same(x, y) then z == pow(x, 2) elseif 0..1==dom(x) /\ 0..1==dom(y) then bool_and__INT(x,y,z) elseif card(dom(x))==2 /\ card(dom(y))==2 /\ 0 in dom(x) /\ 0 in dom(y) then let { var 0..1: xn; var 0..1: yn; var 0..1: zn; constraint x=xn*max(dom(x) diff {0}); constraint y=yn*max(dom(y) diff {0}); constraint z=zn*max(dom(x) diff {0})*max(dom(y) diff {0}); } in bool_and__INT(xn,yn,zn) elseif min(card(dom(x)), card(dom(y))) >= MZN__QuadrIntCard then fzn_int_times(x, y, z) elseif card(dom(x)) * card(dom(y)) > nMZN__UnarySizeMax_intTimes \/ ( fIntTimesBool /\ ( %% Peter's idea for *bool. More optimal but worse values on carpet cutting. (card(dom(x))==2 /\ 0 in dom(x)) \/ (card(dom(y))==2 /\ 0 in dom(y)) ) ) then %% PARAM %% ALSO NO POINT IF <=4. TODO if card(dom(x)) > card(dom(y)) \/ ( card(dom(x))==card(dom(y)) /\ 0 in dom(y) /\ not (0 in dom(x)) ) then int_times(y,x,z) else let { set of int: s = lb(x)..ub(x), set of int: r = {lb(x)*lb(y), lb(x)*ub(y), ub(x)*lb(y), ub(x)*ub(y)}, array[s] of var min(r)..max(r): ady = array1d(s, [ if d in dom(x) then d*y else min(r) endif | d in s ]) } in ady[x] = z %% use element() endif else int_times_unary(x, { }, y, z) endif; %% domx__ can be used to narrow domain... NOT IMPL. predicate int_times_unary(var int: x, set of int: domx__, var int: y, var int: z) = let { set of int: r = {lb(x)*lb(y), lb(x)*ub(y), ub(x)*lb(y), ub(x)*ub(y)}, %% set of int: domx = if card(domx__)>0 then domx__ else dom(x) endif, array[int, int] of var int: pp=eq_encode(x, y) } in z>=min(r) /\ z<=max(r) /\ z==sum(i in index_set_1of2(pp), j in index_set_2of2(pp)) (i * j * pp[i, j]) /\ forall(i in index_set_1of2(pp), j in index_set_2of2(pp) where not ((i*j) in dom(z)) )(pp[i, j]==0) ; predicate int_times_unary__NOFN(var int: x, set of int: domx__, var int: y, var int: z) = let { set of int: r = {lb(x)*lb(y), lb(x)*ub(y), ub(x)*lb(y), ub(x)*ub(y)}, %% set of int: domx = if card(domx__)>0 then domx__ else dom(x) endif, array[int] of var int: pX = eq_encode(x), array[int] of var int: pY = eq_encode(y), array[int] of int: valX = [ v | v in index_set(pX) ], %% NOT domx. array[int] of int: valY = [ v | v in index_set(pY) ], %% -- according to eq_encode! array[index_set(valX), index_set(valY)] of var 0..1: pp %% both dim 1.. } in if is_fixed(x) \/ is_fixed(y) then z==x*y else z>=min(r) /\ z<=max(r) /\ sum(pp)==1 /\ z==sum(i in index_set(valX), j in index_set(valY)) (valX[i] * valY[j] * pp[i, j]) /\ forall(i in index_set(valX)) ( pX[valX[i]] == sum(j in index_set(valY))( pp[i, j] ) ) /\ forall(j in index_set(valY)) ( pY[valY[j]] == sum(i in index_set(valX))( pp[i, j] ) ) endif; predicate float_times(var float: x, var float: y, var float: z) = if is_fixed(x) then z==fix(x)*y %%%%% Need to use fix() otherwise added to CSE & nothing happens elseif is_fixed(y) then z==x*fix(y) elseif MZN__QuadrFloat then fzn_float_times(x, y, z) else abort( "Unable to create linear formulation for the `float_times(\(x), \(y), \(z))`\n" ++ "\tconstraint. To flatten this instance a quadratic constraint is required, but the\n" ++ "\tusage of these constraints is currently disabled for the selected solver. Define\n" ++ "\t`QuadrFloat=true` if your solver supports quadratic constraints, or use\n" ++ "\tinteger variables." ) endif; %%%Define int_pow predicate int_pow( var int: x, var int: y, var int: r ) = let { array[ int, int ] of int: x2y = array2d( lb(x)..ub(x), lb(y)..ub(y), [ pow( X, Y ) | X in lb(x)..ub(x), Y in lb(y)..ub(y) ] ) } in r == x2y[ x, y ]; %%% Adding a version returning float for efficiency /** @group builtins.arithmetic Return \(\a x ^ {\a y}\) */ function var float: pow_float(var int: x, var int: y) = let { int: yy = if is_fixed(y) then fix(y) else -1 endif; } in if yy = 0 then 1 elseif yy = 1 then x else let { var float: r ::is_defined_var; constraint int_pow_float(x,y,r) ::defines_var(r); } in r endif; %%%Define int_pow_float predicate int_pow_float( var int: x, var int: y, var float: r ) = let { array[ int, int ] of float: x2y = array2d( lb(x)..ub(x), lb(y)..ub(y), [ pow( X, Y ) | X in lb(x)..ub(x), Y in lb(y)..ub(y) ] ) } in r == x2y[ x, y ]; %-----------------------------------------------------------------------------% % Array 'element' constraints predicate array_bool_element(var int: x, array[int] of bool: a, var bool: z) = array_int_element(x, arrayXd(a, [bool2int(a[i]) | i in index_set(a)]), bool2int(z)); predicate array_var_bool_element(var int: x, array[int] of var bool: a, var bool: z) = array_var_int_element(x, arrayXd(a, [bool2int(a[i]) | i in index_set(a)]), bool2int(z)); predicate array_int_element(var int: i00, array[int] of int: a, var int: z) = let { set of int: ix = index_set(a), constraint i00 in { i | i in ix where a[i] in dom(z) }, } in %%% Tighten domain of i00 before dMin/dMax let { int: dMin = min(i in dom(i00))(a[i]), int: dMax = max(i in dom(i00))(a[i]), } in if dMin==dMax then z==dMin else z >= dMin /\ z <= dMax /\ let { int: nUBi00 = max(dom(i00)), int: nLBi00 = min(dom(i00)), int: nMinDist = min(i in nLBi00 .. nUBi00-1)(a[i+1]-a[i]), int: nMaxDist = max(i in nLBi00 .. nUBi00-1)(a[i+1]-a[i]), } in if nMinDist == nMaxDist then %% The linear case z == a[nLBi00] + nMinDist*(i00-nLBi00) else let { array[int] of var int: p = eq_encode(i00) %% this needs i00 in ix } %% Faster flattening than (i==i00) @2a9df1f7 in sum(i in dom(i00))( a[i] * p[i] ) == z endif endif; predicate array_var_int_element(var int: i00, array[int] of var int: a, var int: z) = let { constraint i00 in { i | i in index_set(a) where 0 < card(dom(a[i]) intersect dom(z)) }, } in %% finish domain first let { int: minLB=min(i in dom(i00))(lb(a[i])), int: maxUB=max(i in dom(i00))(ub(a[i])) } in if minLB==maxUB then z==minLB else z >= minLB /\ z <= maxUB /\ if {0,1}==dom(i00) /*ub(i00)-lb(i00)==1*/ /*2==card( dom( i00 ) )*/ then aux_int_eq_if_1(z, a[lb(i00)], (ub(i00)-i00)) /\ aux_int_eq_if_1(z, a[ub(i00)], (i00-lb(i00))) else let { array[int] of var int: p = eq_encode(i00) %% this needs i00 in ix } %% Faster flattening than (i==i00) @2a9df1f7 in forall (i in dom(i00))( aux_int_eq_if_1(z, a[i], p[i]) ) endif endif; predicate array_float_element(var int: i00, array[int] of float: a, var float: z) = let { set of int: ix = index_set(a), constraint i00 in { i | i in ix where a[i]>=lb(z) /\ a[i]<=ub(z) }, } in %%% Tighten domain of i00 before dMin/dMax let { float: dMin = min(i in dom(i00))(a[i]), float: dMax = max(i in dom(i00))(a[i]), } in if dMin==dMax then z==dMin else z >= dMin /\ z <= dMax /\ let { int: nUBi00 = max(dom(i00)), int: nLBi00 = min(dom(i00)), float: nMinDist = min(i in nLBi00 .. nUBi00-1)(a[i+1]-a[i]), float: nMaxDist = max(i in nLBi00 .. nUBi00-1)(a[i+1]-a[i]), } in if nMinDist == nMaxDist then %% The linear case z == a[nLBi00] + nMinDist*(i00-nLBi00) else let { array[int] of var int: p = eq_encode(i00) %% this needs i00 in ix } %% Faster flattening than (i==i00) @2a9df1f7 in sum(i in dom(i00))( a[i] * p[i] ) == z endif endif; predicate array_var_float_element(var int: i00, array[int] of var float: a, var float: z) = let { set of int: ix = index_set(a), constraint i00 in { i | i in ix where lb(a[i])<=ub(z) /\ ub(a[i])>=lb(z) }, } in %% finish domain first let { float: minLB=min(i in dom(i00))(lb(a[i])), float: maxUB=max(i in dom(i00))(ub(a[i])) } in if minLB==maxUB then z==minLB else z >= minLB /\ z <= maxUB /\ if {0,1}==dom(i00) /*ub(i00)-lb(i00)==1*/ /*2==card( dom( i00 ) )*/ then aux_float_eq_if_1(z, a[lb(i00)], (ub(i00)-i00)) /\ aux_float_eq_if_1(z, a[ub(i00)], (i00-lb(i00))) else %%% The convexified bounds seem slow for ^2 and ^3 equations: % sum(i in dom(i01))( lb(a[i]) * (i==i00) ) <= z /\ %% convexify lower bounds % sum(i in dom(i01))( ub(a[i]) * (i==i00) ) >= z /\ %% convexify upper bounds let { array[int] of var int: p = eq_encode(i00) %% this needs i00 in ix } %% Faster flattening than (i==i00) @2a9df1f7 in forall (i in dom(i00))( aux_float_eq_if_1(z, a[i], p[i]) ) %% Cuts: /\ if fElementCutsXZ then array_var_float_element__ROOF([ a[i] | i in dom(i00) ], z) :: MIP_cut %% these 2 as user cuts - too slow /\ array_var_float_element__ROOF([ -a[i] | i in dom(i00) ], -z) :: MIP_cut %% or even skip them else true endif /\ if fElementCutsXZB then array_var_float_element__XBZ_lb([ a[i] | i in dom(i00) ], [ p[i] | i in dom(i00) ], z) :: MIP_cut /\ array_var_float_element__XBZ_lb([ -a[i] | i in dom(i00) ], [ p[i] | i in dom(i00) ], -z) :: MIP_cut else true endif endif endif; %%% Facets on the upper surface of the z-a polytope %%% Possible parameter: maximal number of first cuts taken only predicate array_var_float_element__ROOF(array[int] of var float: a, var float: z) = let { set of int: ix = index_set(a), int: n = length(a), array[int] of float: AU = [ ub(a[i]) | i in 1..n], array[int] of int: srt_ub = sort_by([i | i in 1..n], AU), %indices of ub sorted up array[int] of float: AU_srt_ub = [ub(a[srt_ub[i]]) | i in 1..n], array[int] of float: AL_srt_ub = [lb(a[srt_ub[i]]) | i in 1..n], array[int] of float: MaxLBFrom = [ max(j in index_set(AL_srt_ub) where j>=i)(AL_srt_ub[j]) | i in 1..n ], %% direct, O(n^2) array[int] of float: ULB = [ if 1==i then MaxLBFrom[1] else max([AU_srt_ub[i-1], MaxLBFrom[i]]) endif | i in 1..n ] } in %%% "ROOF" forall (i in 1..n where if i==n then true else ULB[i]!=ULB[i+1] endif %% not the same base bound )( z <= ULB[i] + sum( j in i..n where AU_srt_ub[i] != AL_srt_ub[i] ) %% not a const ( (AU_srt_ub[j]-ULB[i]) * (a[srt_ub[j]]-AL_srt_ub[j]) / (AU_srt_ub[j]-AL_srt_ub[j]) ) ) ; predicate array_var_float_element__XBZ_lb(array[int] of var float: x, array[int] of var int: b, var float: z) = if fUseXBZCutGen then array_var_float_element__XBZ_lb__cutgen(x, b, z) :: MIP_cut else %% Adding some cuts a priori, also to make solver extract the variables let { int: i1 = min(index_set(x)) } in (z <= sum(i in index_set(x))(ub(x[i]) * b[i])) %:: MIP_cut -- does not work to put them here TODO /\ forall(i in index_set(x) intersect i1..(i1+19)) %% otherwise too many on amaze2 ( assert(lb(x[i]) == -ub(-x[i]) /\ ub(x[i]) == -lb(-x[i]), " negated var's bounds should swap " ) /\ z <= x[i] + sum(j in index_set(x) where i!=j)((ub(x[j])-lb(x[i]))*b[j])) %:: MIP_cut %% (ub_j-lb_i) * b_j /\ forall(i in index_set(x) intersect i1..(i1+19)) ( z <= ub(x[i])*b[i] + sum(j in index_set(x) where i!=j)(x[j]+lb(x[j])*(b[j]-1)) ) %:: MIP_cut /\ (z <= sum(i in index_set(x))(x[i] + lb(x[i]) * (b[i]-1))) %:: MIP_cut endif; %-----------------------------------------------------------------------------% % Set constraints %% ----------------------------------------------- (NO) SETS ---------------------------------------------- % XXX only for a fixed set here, general see below. % Normally not called because all plugged into the domain. % Might be called instead of set_in(x, var set of int s) if s gets fixed? predicate set_in(var int: x, set of int: s__) = let { set of int: s = if has_bounds(x) then s__ intersect dom(x) else s__ endif, constraint min(s) <= x, constraint x <= max(s), } in if s = min(s)..max(s) then true elseif fPostprocessDomains then set_in__POST(x, s) else %% Update eq_encode let { array[int] of var int: p = eq_encode(x); } in forall(i in index_set(p) diff s)(p[i]==0) % let { % array[int] of int: sL = [ e | e in s where not (e - 1 in s) ]; % array[int] of int: sR = [ e | e in s where not (e + 1 in s) ]; % array [index_set(sR)] of var 0..1: B; % constraint assert(length(sR)==length(sL), "N of lb and ub of sub-intervals of a set should be equal"); % } in % sum(B) = 1 %% use indicators % /\ % x >= sum(i in index_set(sL))(B[i]*sL[i]) % /\ % x <= sum(i in index_set(sR))(B[i]*sR[i]) endif; %%% for a fixed set predicate set_in_reif(var int: x, set of int: s__, var bool: b) = if is_fixed(b) then if fix(b) then x in s__ else x in dom(x) diff s__ endif elseif has_bounds(x) /\ not (s__ subset dom(x)) then b <-> x in s__ intersect dom(x) %% Use CSE else let { set of int: s = if has_bounds(x) then s__ intersect dom(x) else s__ endif, } in ( if dom(x) subset s then b==true elseif card(dom(x) intersect s)==0 then b==false elseif fPostprocessDomains then set_in_reif__POST(x, s, b) %% Bad. Very much so for CBC. 27.06.2019: elseif s == min(s)..max(s) then %% b <-> (min(s) <= x /\ x <= max(s)) else if card(dom(x))<=nMZN__UnaryLenMax_setInReif then %% PARAM TODO let { array[int] of var int: p = eq_encode(x); } in sum(i in s intersect dom(x))(p[i]) == bool2int(b) else bool2int(b) == fVarInBigSetOfInt(x, s) endif endif ) endif; % Alternative predicate alt_set_in_reif(var int: x, set of int: s, var bool: b) = b <-> exists(i in 1..length([ 0 | e in s where not (e - 1 in s) ]))( let { int: l = [ e | e in s where not (e - 1 in s) ][i], int: r = [ e | e in s where not (e + 1 in s) ][i] } in l <= x /\ x <= r ); %%% for a fixed set predicate set_in_imp(var int: x, set of int: s__, var bool: b) = if is_fixed(b) then if fix(b) then x in s__ else true endif elseif has_bounds(x) /\ not (s__ subset dom(x)) then b -> x in s__ intersect dom(x) %% Use CSE else let { set of int: s = if has_bounds(x) then s__ intersect dom(x) else s__ endif, } in ( if dom(x) subset s then true elseif card(dom(x) intersect s)==0 then b==false elseif s == min(s)..max(s) then (b -> min(s) <= x) /\ (b -> x <= max(s)) else if card(dom(x))<=nMZN__UnaryLenMax_setInReif then %% PARAM TODO let { array[int] of var int: p = eq_encode(x); } in sum(i in s intersect dom(x))(p[i]) >= bool2int(b) else bool2int(b) <= fVarInBigSetOfInt(x, s) endif endif ) endif; function var 0..1: fVarInBigSetOfInt(var int: x, set of int: s) = let { array[int] of int: sL = [ e | e in s where not (e - 1 in s) ]; array[int] of int: sR = [ e | e in s where not (e + 1 in s) ]; constraint assert(length(sR)==length(sL), "N of lb and ub of sub-intervals of a set should be equal"); } in sum(i in index_set(sL)) (bool2int(x>=sL[i] /\ x<=sR[i])); %% use indicators %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% OTHER SET STUFF COMING FROM nosets.mzn %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %-----------------------------------------------------------------------------% %-----------------------------------------------------------------------------% annotation bool_search(array[int] of var bool: x, ann: a1, ann: a2, ann: a3) = int_search([bool2int(x_i) | x_i in x], a1, a2, a3); annotation warm_start( array[int] of var bool: x, array[int] of bool: v ) = warm_start( [ bool2int(x[i]) | i in index_set(x) ], [ bool2int(v[i]) | i in index_set(v) ] ); annotation sat_goal(var bool: b) = int_max_goal(b); annotation int_max_goal(var int: x); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DOMAIN POSTPROCESSING BUILT-INS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Single variable: x = d <-> x_eq_d[d] predicate equality_encoding__POST(var int: x, array[int] of var int: x_eq_d); %%%%%%% var int: b: bool2int is a reverse_map, not passed to .fzn predicate set_in__POST(var int: x, set of int: s__); predicate set_in_reif__POST(var int: x, set of int: s__, var int: b); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LOGICAL CONSTRAINTS TO THE SOLVER %%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%% var int: b: bool2int is a reverse_map, not passed to .fzn => REPEAT TESTS. TODO predicate int_lin_eq_reif__IND(array[int] of int: c, array[int] of var int: x, int: d, var int: b); predicate int_lin_le_reif__IND(array[int] of int: c, array[int] of var int: x, int: d, var int: b); predicate int_lin_ne__IND(array[int] of int: c, array[int] of var int: x, int: d); predicate aux_int_le_zero_if_0__IND(var int: x, var int: b); predicate float_lin_le_reif__IND(array[int] of float: c, array[int] of var float: x, float: d, var int: b); predicate aux_float_eq_if_1__IND(var float: x, var float: y, var int: b); predicate aux_float_le_zero_if_0__IND(var float: x, var int: b); predicate array_int_minimum__IND(var int: m, array[int] of var int: x); predicate array_int_maximum__IND(var int: m, array[int] of var int: x); predicate array_float_minimum__IND(var float: m, array[int] of var float: x); predicate array_float_maximum__IND(var float: m, array[int] of var float: x); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% XBZ cut generator, currently CPLEX only %%%%%%%%%%%%%%%%%%%%%%%%%% predicate array_var_float_element__XBZ_lb__cutgen(array[int] of var float: x, array[int] of var int: b, var float: z); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Quadratic expressions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 predicate fzn_float_times(var float: a, var float: b, var float: c); predicate fzn_int_times(var int: a, var int: b, var int: c); predicate fzn_array_float_minimum(var float: m, array[int] of var float: x); libminizinc-2.8.2/share/minizinc/linear/redefinitions-2.0.2.mzn0000644000175000017500000000226614536677021022732 0ustar kaolkaol% This file contains redefinitions of standard builtins for version 2.0.2 % that can be overridden by solvers. predicate symmetry_breaking_constraint(var bool: b) = (b) %:: MIP_lazy %:: MIP_cut %% MIP_cut wrong in CPLEX 12.6.3 %% Symm breaking as lazy is 1% better in Gurobi 6.5.2 on the Challenges 2012-2015 %% But caused a bug in 7.5.1 - switched off %% true %% TO omit all symmetry_breaking_constraint's ; %% Make sure no feasible solutions are cut off: predicate redundant_constraint(var bool: b) = (b) %:: MIP_cut % true %% To omit all redundant_constraint's ; %% Linearized element: just call without shifting predicate array_var_bool_element_nonshifted(var int: idx, array[int] of var bool: x, var bool: c) = array_var_bool_element(idx,x,c); predicate array_var_int_element_nonshifted(var int: idx, array[int] of var int: x, var int: c) = array_var_int_element(idx,x,c); predicate array_var_float_element_nonshifted(var int: idx, array[int] of var float: x, var float: c) = array_var_float_element(idx,x,c); predicate array_var_set_element_nonshifted(var int: idx, array[int] of var set of int: x, var set of int: c) = array_var_set_element(idx,x,c); libminizinc-2.8.2/share/minizinc/linear/fzn_lex_chain_lesseq_bool.mzn0000644000175000017500000000022014536677021024615 0ustar kaolkaolinclude "fzn_lex_chain_lesseq_int.mzn"; predicate fzn_lex_chain_lesseq_bool(array[int, int] of var bool: a) = fzn_lex_chain_lesseq_int(a); libminizinc-2.8.2/share/minizinc/linear/fzn_lex_lesseq_int.mzn0000644000175000017500000000446614536677021023332 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% opt bool: UseCPLexLesseq; %% When not UseOrbisack, use CP decomposition opt bool: OrbisackAlwaysModelConstraint; %% Use with SCIP 7.0.2 predicate fzn_lex_lesseq_int(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) = assert(length(x) == length(y), %% SCIP cannot "lex_lesseq_int(\(x), \(y)): arrays of different lengths") /\ if MZN__Orbisack /\ dom_array(x) subset 0..1 /\ dom_array(y) subset 0..1 then fzn_lex_lesseq__orbisack(x, y, ( occurs(OrbisackAlwaysModelConstraint) /\ deopt(OrbisackAlwaysModelConstraint) ) \/ not mzn_in_symmetry_breaking_constraint()) elseif occurs(UseCPLexLesseq) /\ deopt(UseCPLexLesseq) then lex_lesseq_std_decomposition(x, y) else fzn_lex_lesseq_int__MIP(x, y) endif; predicate fzn_lex_lesseq_int__MIP(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) = if length(x) = 0 then true elseif length(y) = 0 then length(x) = 0 else let { int: lx = min(index_set(x)), int: ux = max(index_set(x)), int: ly = min(index_set(y)), int: uy = max(index_set(y)), int: size = min(ux - lx, uy - ly), array[0..size] of var 0..1: fEQ; array[0..size] of var 0..1: fLT; } in sum(fLT) <= 1 /\ fEQ[0] + fLT[0] == 1 /\ forall(i in 1..size) ( fEQ[i-1] == fEQ[i] + fLT[i] ) /\ forall(i in 0..size) ( aux_int_eq_if_1(x[lx+i], y[ly+i], fEQ[i]) /\ aux_int_lt_if_1(x[lx+i], y[ly+i], fLT[i]) ) endif; %% SCIP constraint handler orbisack predicate fzn_lex_lesseq__orbisack( array[int] of var int: vec1, array[int] of var int: vec2, bool: isModelCons); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/linear/fzn_if_then_else_int.mzn0000644000175000017500000000042714536677021023603 0ustar kaolkaolpredicate fzn_if_then_else_int(array[int] of var bool: c, array[int] of int: x, var int: y) = let { array[index_set(c)] of var 0..1: d; } in forall (i in index_set(c)) (sum(j in 1..i-1)(c[j])+d[i] >= c[i]) /\ sum(d)=1 /\ y = sum (i in index_set(c)) ( d[i]*x[i] ); libminizinc-2.8.2/share/minizinc/linear/fzn_lex_less_int.mzn0000644000175000017500000000226114536677021022773 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than array 'y'. % Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_less_int(array[int] of var int: x, array[int] of var int: y) = if length(y) = 0 then false elseif length(x) = 0 then true else let { int: lx = min(index_set(x)), int: ux = max(index_set(x)), int: ly = min(index_set(y)), int: uy = max(index_set(y)), int: size = min(ux - lx, uy - ly), array[0..size] of var 0..1: fEQ; array[0..size] of var 0..1: fLT; } in sum(fLT) == 1 /\ fEQ[0] + fLT[0] == 1 /\ forall(i in 1..size) ( fEQ[i-1] == fEQ[i] + fLT[i] ) /\ forall(i in 0..size) ( aux_int_eq_if_1(x[lx+i], y[ly+i], fEQ[i]) /\ aux_int_lt_if_1(x[lx+i], y[ly+i], fLT[i]) ) endif; %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/linear/redefinitions-2.2.1.mzn0000644000175000017500000000040014536677021022717 0ustar kaolkaol% This file contains redefinitions of standard builtins for version 2.2.1 % that can be overridden by solvers. /** @group flatzinc.int Constrains \a z = \(\a x ^ {\a y}\) */ predicate int_pow_fixed(var int: x, int: y, var int: z) = int_pow( x, y, z ); libminizinc-2.8.2/share/minizinc/linear/fzn_all_different_int.mzn0000644000175000017500000000152514536677021023755 0ustar kaolkaol%-----------------------------------------------------------------------------% % 'all_different' constrains an array of objects to be all different. % % Linear version: equality encoding; see e.g. [Refalo, CP 2000] % % For a given d in dom(x), at most one i with x_i = d can exist. %-----------------------------------------------------------------------------% include "domain_encodings.mzn"; predicate fzn_all_different_int(array[int] of var int: x) = if length(x)<=1 then true else let { array[int,int] of var 0..1: x_eq_d = eq_encode(x) } in ( % my_trace(" all_different_int: x[" ++ show(index_set(x)) ++ "]\n") /\ forall(d in index_set_2of2(x_eq_d))( sum(i in index_set_1of2(x_eq_d))( x_eq_d[i,d] ) <= 1 ) ) endif; %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/linear/fzn_subcircuit.mzn0000644000175000017500000000376614536677021022472 0ustar kaolkaolinclude "alldifferent.mzn"; %% Linear version predicate fzn_subcircuit(array[int] of var int: x) = if length(x) = 0 then true else let { set of int: S = index_set(x), int: l = min(S), int: u = max(S), int: n = card(S), array[S] of var 1..n: order, array[S] of var bool: ins = array1d(S,[ x[i] != i | i in S]), var l..u+1: firstin = min([ u+1 + bool2int(ins[i])*(i-u-1) | i in S]), %% ... var S: lastin, var bool: empty = (firstin == u+1), } in alldifferent(x) /\ % NO alldifferent(order) /\ % If the subcircuit is empty then each node points at itself. % (empty <-> forall(i in S)(not ins[i])) /\ % If the subcircuit is non-empty then order numbers the subcircuit. % ((not empty) <-> %% Another way to express minimum. % forall(i in l..u+1)( % i==firstin <-> ins[i] % /\ forall(j in S where j firstin /\ % The lastin node points at firstin. x[lastin] = firstin /\ % And both are in ins[lastin] /\ ins[firstin] /\ % The successor of each node except where it is firstin is % numbered one more than the predecessor. % forall(i in S) ( % (ins[i] /\ x[i] != firstin) -> order[x[i]] = order[i] + 1 % ) /\ %%% MTZ model. Note that INTEGER order vars seem better!: forall (i,j in S where i!=j) ( order[i] - order[j] + n*bool2int( x[i]==j /\ i!=lastin ) % + (n-2)*bool2int(x[j]==i) %% the Desrochers & Laporte '91 term <= n-1 ) /\ % Each node that is not in is numbered after the lastin node. forall(i in S) ( true % (not ins[i]) <-> (n == order[i]) ) ) endif; %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/linear/fzn_inverse_reif.mzn0000644000175000017500000000050514536677021022762 0ustar kaolkaolpredicate fzn_inverse_reif(array[int] of var int: f, array[int] of var int: invf, var bool: b) = b <-> forall(i in index_set(f), j in index_set(invf)) ( f[i] in index_set(invf) /\ invf[j] in index_set(f) /\ (j == f[i] <-> i == invf[j]) ); libminizinc-2.8.2/share/minizinc/linear/fzn_lex_less_bool.mzn0000644000175000017500000000106314536677021023133 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% include "fzn_lex_less_int.mzn"; predicate fzn_lex_less_bool(array[int] of var bool: x, array[int] of var bool: y) = fzn_lex_less_int(x, y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/linear/fzn_inverse.mzn0000644000175000017500000000117014536677021021754 0ustar kaolkaol%-----------------------------------------------------------------------------% % Constrains two arrays of int variables to represent inverse functions. % All the values in each array must be within the index set of the other array. % % Linear version. %-----------------------------------------------------------------------------% include "fzn_inverse_in_range.mzn"; predicate fzn_inverse(array[int] of var int: f, array[int] of var int: invf) = forall(i in index_set(f)) ( f[i] in index_set(invf) ) /\ forall(j in index_set(invf)) ( invf[j] in index_set(f) ) /\ fzn_inverse_in_range(f, invf); libminizinc-2.8.2/share/minizinc/linear/fzn_inverse_in_range_reif.mzn0000644000175000017500000000041014536677021024617 0ustar kaolkaolpredicate fzn_inverse_in_range_reif(array[int] of var int: f, array[int] of var int: invf, var bool: b) = b <-> forall(i in index_set(f), j in index_set(invf)) ( (j == f[i] <-> i == invf[j]) ); libminizinc-2.8.2/share/minizinc/linear/redefinitions-2.0.mzn0000644000175000017500000000140414536677021022563 0ustar kaolkaolpredicate bool_clause_reif(array[int] of var bool: p, array[int] of var bool: n, var bool: c) = c = ( sum(i in index_set(p))( bool2int(p[i]) ) - sum(i in index_set(n))( bool2int(n[i]) ) + length(n) >= 1 ); predicate array_int_minimum(var int: m, array[int] of var int: x) = array_int_minimum_I( m, [ x[i] | i in index_set(x)]); predicate array_int_maximum(var int: m, array[int] of var int: x) = array_int_minimum_I(-m, [-x[i] | i in index_set(x)]); predicate array_float_minimum(var float: m, array[int] of var float: x) = array_float_minimum_I( m, [ x[i] | i in index_set(x)]); predicate array_float_maximum(var float: m, array[int] of var float: x) = array_float_minimum_I(-m, [-x[i] | i in index_set(x)]); libminizinc-2.8.2/share/minizinc/linear/redefs_lin_reifs.mzn0000644000175000017500000003653514536677021022743 0ustar kaolkaol/* % FlatZinc built-in redefinitions for linear solvers. % % AUTHORS % Sebastian Brand % Gleb Belov */ %-----------------------------------------------------------------------------% % % Linear equations and inequations % TODO Use indicators for (half)reifs. % Otherwise and more using unary encoding for reasonable domains % %-----------------------------------------------------------------------------% % Domains: reduce all to aux_ stuff? %% never use Concert's reif feature %% var, var predicate int_le_reif(var int: x, var int: y, var bool: b) = %% trace(" int_le_reif VV: \(x), \(y), \(b) \n") /\ if is_fixed(b) then if true==fix(b) then x<=y else x>y endif elseif ub(x)<=lb(y) then b==true elseif lb(x)>ub(y) then b==false elseif fPostprocessDomains /\ fPostproDom_DIFF then int_le_reif__POST(x-y, 0, b) else int_le_reif__NOPOST(x, y, b) endif ; %% const, var predicate int_le_reif(int: x, var int: y, var bool: b) = %% trace(" int_le_reif CV: \(x), \(y), \(b) \n") /\ if is_fixed(b) then if true==fix(b) then x<=y else x>y endif elseif ub(x)<=lb(y) then b==true elseif lb(x)>ub(y) then b==false elseif not (x in dom(y)) then %% dom(y) has holes let { set of int: sDom2 = dom(y) intersect x+1..infinity, constraint assert( card( sDom2 ) > 0, "Variable: dom(\(y)) = \(dom(y)), but dom() intersect \(x)..inf: \(sDom2)\n" ), } in b <-> min( sDom2 ) <= y elseif fPostprocessDomains then int_ge_reif__POST(y, x, b) else int_le_reif(-y, -x, b) endif ; %% var, const predicate int_le_reif(var int: x, int: y, var bool: b) = %% trace(" int_le_reif VC: \(x), \(y), \(b) \n") /\ if is_fixed(b) then if true==fix(b) then x<=y else x>y endif elseif ub(x)<=lb(y) then b==true elseif lb(x)>ub(y) then b==false elseif not (y in dom(x)) then %% dom(x) has holes let { set of int: sDom2 = dom(x) intersect -infinity..y-1, constraint assert( card( sDom2 ) > 0, "Variable: dom(\(x)) = \(dom(x)), but dom() intersect -inf..\(y): \(sDom2)\n" ), } in b <-> x <= max( sDom2 ) else if fPostprocessDomains then int_le_reif__POST(x, y, b) else int_le_reif__NOPOST(x, y, b) endif endif ; %% var int, var int predicate int_le_reif__NOPOST(var int: x, var int: y, var bool: b) = aux_int_le_if_1(x, y, b) /\ %% This can call POSTs... TODO aux_int_gt_if_0(x, y, b) ; %% var, var predicate int_lt_reif(var int: x, var int: y, var bool: b) = %% int_le_reif(x-y, -1, b); %% This would produce a new variable x-y and possibly POST it %% but it looks like differences should not be if is_fixed( x ) then int_le_reif(x+1, y, b) else int_le_reif(x, y-1, b) endif; %% var, var predicate int_ne(var int: x, var int: y) = if fPostproDom_DIFF then int_ne(x-y, 0) else int_ne__SIMPLE(x-y, 0) endif; %% var, const predicate int_ne(var int: x, int: y) = if y in dom(x) then if y==ub(x) then x <= y-1 elseif y==lb(x) then x >= y+1 elseif fPostprocessDomains then int_ne__POST(x, y) elseif card(dom(x))y) > 0 endif; %% var, var predicate int_eq_reif(var int: x, var int: y, var bool: b) = %% trace(" int_eq_reif VV: \(x), \(y), \(b) \n") /\ if is_fixed(b) then if fix(b) then x==y else x!=y endif elseif card(dom(x) intersect dom(y))>0 then if is_fixed(x) then if is_fixed(y) then b <-> fix(x)==fix(y) else int_eq_reif(y, fix(x), b) endif elseif is_fixed(y) then int_eq_reif(x, fix(y), b) elseif fPostprocessDomains /\ fPostproDom_DIFF then int_eq_reif(x-y, 0, b) else aux_int_eq_iff_1(x, y, b) endif else not b endif; %% var, const predicate int_eq_reif(var int: x, int: y, var bool: b) = %% trace(" int_eq_reif VC: \(x), \(y), \(b) \n") /\ if is_fixed(b) then if fix(b) then x==y else x!=y endif elseif y in dom(x) then if is_fixed(x) then b <-> y==fix(x) elseif card(dom(x))==2 then x == max(dom(x) diff {y}) + b*(y - max(dom(x) diff {y})) %% This should directly connect b to var 0..1: x elseif fPostprocessDomains then int_eq_reif__POST(x, y, b) %%% THIS seems pretty complex, especially for binaries, and does not connect to eq_encoding (/ MIPD?) %% elseif y==lb(x) then %% int_lt_reif(y, x, not b) %% elseif y==ub(x) then %% int_lt_reif(x, y, not b) elseif card(dom(x))y endif elseif false then float_lin_le_reif__IND( [1.0, -1.0], [x, y], 0.0, b) elseif ub(x) <= y then b == true elseif lb(x) > y then b == false elseif fPostprocessDomains then float_le_reif__POST(x, y, b, float_lt_EPS) else float_le_reif__NOPOST(x, y, b) endif; %% const, var float predicate float_le_reif(float: x, var float: y, var bool: b) = if is_fixed(b) then if true==fix(b) then x<=y else x>y endif elseif false then float_lin_le_reif__IND( [1.0, -1.0], [x, y], 0.0, b) elseif ub(x) <= lb(y) then b == true elseif lb(x) > ub(y) then b == false elseif fPostprocessDomains then float_ge_reif__POST(y, x, b, float_lt_EPS) else float_le_reif(-y, -x, b) endif; %% var float, var float predicate float_le_reif(var float: x, var float: y, var bool: b) = if is_fixed(b) then if true==fix(b) then x<=y else x>y endif elseif ub(x)<=lb(y) then b==true elseif lb(x)>ub(y) then b==false elseif fPostprocessDomains /\ fPostproDom_DIFF then float_le_reif(x-y, 0.0, b) else float_le_reif__NOPOST(x-y, 0, b) endif ; %% var float, var float predicate float_le_reif__NOPOST(var float: x, var float: y, var bool: b) = aux_float_le_if_1(x, y, (b)) /\ %% Can call __POSTs TODO aux_float_gt_if_0(x, y, (b)) ; %% TODO predicate float_lt_reif(var float: x, var float: y, var bool: b) = %% Actually = float_le_reif(x, y-eps, b). if is_fixed(b) then if true==fix(b) then x=y endif elseif fPostprocessDomains /\ fPostproDom_DIFF then aux_float_lt_zero_iff_1__POST(x - y, b, float_lt_EPS) else aux_float_lt_if_1(x, y, (b)) /\ aux_float_ge_if_0(x, y, (b)) endif; %% var, const predicate float_ne(var float: x, float: y) = if fPostprocessDomains then float_ne__POST(x, y, float_lt_EPS) else float_ne__SIMPLE(x, y) endif; predicate float_ne__SIMPLE(var float: x, var float: y) = if true then let { var 0..1: p } in aux_float_lt_if_1(x, y, (p)) /\ aux_float_gt_if_0(x, y, (p)) else %TODO: Why is this not half-reified? 1 == (x>y) + (xub(y) then b == false elseif is_fixed(x) /\ is_fixed(y) then b == (fix(x) == fix(y)) elseif fPostprocessDomains /\ fPostproDom_DIFF then float_eq_reif__POST(x-y, 0, b, float_lt_EPS) else aux_float_eq_iff_1(x, y, (bool2int(b))) endif; predicate float_ne_reif(var float: x, var float: y, var bool: b) = float_eq_reif(x, y, not (b)); %-----------------------------------------------------------------------------% predicate float_lin_eq_reif(array[int] of float: c, array[int] of var float: x, float: d, var bool: b) = if fPostprocessDomains /\ fPostproDom_DIFF then float_eq_reif(sum(i in index_set(x))( c[i]*x[i] ), d, b) else aux_float_eq_iff_1(sum(i in index_set(x))( c[i]*x[i] ), d, b) endif; predicate float_lin_ne_reif(array[int] of float: c, array[int] of var float: x, float: d, var bool: b) = if fPostprocessDomains /\ fPostproDom_DIFF then float_ne_reif(sum(i in index_set(x))( c[i]*x[i] ), d, not b) else aux_float_eq_iff_1(sum(i in index_set(x))( c[i]*x[i] ), d, not b) endif; predicate float_lin_le_reif(array[int] of float: c, array[int] of var float: x, float: d, var bool: b) = if fPostprocessDomains /\ fPostproDom_DIFF then float_le_reif(sum(i in index_set(x))( c[i]*x[i] ), d, b) else float_le_reif__NOPOST(sum(i in index_set(x))( c[i]*x[i] ), d, b) endif; predicate float_lin_lt_reif(array[int] of float: c, array[int] of var float: x, float: d, var bool: b) = float_lt_reif(sum(i in index_set(x))( c[i]*x[i] ), d, b); %-----------------------------------------------------------------------------% % Auxiliary: equality reified onto a 0/1 variable predicate aux_int_eq_iff_1(var int: x, var int: y, var int: p) = if is_fixed(p) then if 1==fix(p) then x==y else x!=y endif elseif fPostprocessDomains /\ fPostproDom_DIFF then abort(" aux_int_eq_iff_1 should not be used with full domain postprocessing") elseif false then true elseif fAuxIntEqOLD00 then let { array[1..2] of var 0..1: q } in aux_int_le_if_1(x, y, p) /\ aux_int_ge_if_1(x, y, p) /\ aux_int_lt_if_0(x, y, q[1]) /\ aux_int_gt_if_0(x, y, q[2]) /\ sum(q) == p + 1 else %% redundant p == (x<=y /\ y<=x) /\ 1+p == (x<=y) + (y<=x) endif; predicate aux_int_eq_iff_1__float(var float: x, float: y, var int: p) = if fAuxIntEqOLD00 then assert( false, "Don't use aux_int_eq_iff_1__float" ) /* let { array[1..2] of var 0..1: q } in aux_int_le_if_1(x, y, p) /\ aux_int_ge_if_1(x, y, p) /\ aux_int_lt_if_0(x, y, q[1]) /\ aux_int_gt_if_0(x, y, q[2]) /\ sum(q) == p + 1 */ else assert( false, "Don't use aux_int_eq_iff_1__float with fAuxIntEqOLD00" ) endif; % Alternative 2 predicate aux_int_eq_iff_1__WEAK1(var int: x, var int: y, var int: p) = let { array[1..2] of var 0..1: q_458 } in aux_int_lt_if_0(x - p, y, q_458[1]) /\ aux_int_gt_if_0(x + p, y, q_458[2]) /\ sum(q_458) <= 2 - 2*p /\ sum(q_458) <= 1 + p; % Alternative 1 predicate alt_1_aux_int_eq_iff_1(var int: x, var int: y, var int: p) = let { array[1..2] of var 0..1: q } in aux_int_lt_if_0(x - p, y, q[1]) /\ aux_int_gt_if_0(x + p, y, q[2]) /\ q[1] <= 1 - p /\ q[2] <= 1 - p /\ sum(q) <= 1 + p; predicate aux_float_eq_iff_1(var float: x, var float: y, var int: p) = if is_fixed(p) then if 1==fix(p) then x==y else x!=y endif elseif fPostprocessDomains /\ fPostproDom_DIFF then abort(" aux_float_eq_iff_1 should not be used with full domain postprocessing") elseif fAuxFloatEqOLD00 then let { array[1..2] of var 0..1: q } in aux_float_le_if_1(x, y, p) /\ aux_float_ge_if_1(x, y, p) /\ aux_float_lt_if_0(x, y, (q[1])) /\ aux_float_gt_if_0(x, y, (q[2])) /\ sum(i in 1..2)((q[i])) == 1 + p else %% redundant p == (x<=y /\ y<=x) /\ 1+p == (x<=y) + (y<=x) endif; % ----------------------------- Domains postpro --------------------------- %%%%%%%%%%%%%%%%%% predicate int_le_reif__POST(var int: x, var int: y, var int: b); %%%%%%%%%%%%%%%%%% predicate int_le_reif__POST(int: x, var int: y, var int: b); %%%%%%% var int: b: bool2int is a reverse_map, not passed to .fzn %% var, const predicate int_le_reif__POST(var int: x, int: y, var int: b); %% var, const predicate int_ge_reif__POST(var int: x, int: y, var int: b); %% var, const predicate int_eq_reif__POST(var int: x, int: y, var int: b); %% var, const predicate int_ne__POST(var int: x, int: y); %%%%%%%%%%%%%%%%%% predicate float_le_reif__POST(var float: x, var float: y, var int: b); %%%%%%%%%%%%%%%%%% predicate float_le_reif__POST(float: x, var float: y, var int: b); %% var, const predicate float_le_reif__POST(var float: x, float: y, var int: b, float: epsRel); %% var, const predicate float_ge_reif__POST(var float: x, float: y, var int: b, float: epsRel); %% var, var predicate aux_float_lt_zero_iff_1__POST(var float: x, var int: b, float: epsRel); %% var, const predicate float_eq_reif__POST(var float: x, float: y, var int: b, float: epsRel); %% var, const predicate float_ne__POST(var float: x, float: y, float: epsRel); libminizinc-2.8.2/share/minizinc/linear/fzn_regular.mzn0000644000175000017500000001103614536677021021744 0ustar kaolkaol/** @group globals.extensional The sequence of values in array \a x (which must all be in the range 1..\a S) is accepted by the DFA of \a Q states with input 1..\a S and transition function \a d (which maps (1..\a Q, 1..\a S) -> 0..\a Q)) and initial state \a q0 (which must be in 1..\a Q) and accepting states \a F (which all must be in 1..\a Q). We reserve state 0 to be an always failing state. */ predicate fzn_regular(array[int] of var int: x, int: Q, int: S, array[int,int] of int: d, int: q0, set of int: F) = if length(x) = 0 then q0 in F else % my_trace(" regular: index_set(x)=" ++ show(index_set(x)) % ++ ", dom_array(x)=" ++ show(dom_array(x)) % ++ ", dom_array(a)=" ++ show(1..Q) % ++ "\n") /\ let { % If x has index set m..n-1, then a[m] holds the initial state % (q0), and a[i+1] holds the state we're in after processing % x[i]. If a[n] is in F, then we succeed (ie. accept the string). int: m = min(index_set(x)), int: n = max(index_set(x)) + 1, array[m..n] of var 1..Q: a, constraint a[m] = q0 /\ % Set a[0]. a[n] in F, % Check the final state is in F. constraint forall(i in index_set(x)) ( x[i] in 1..S % Do this in case it's a var. /\ %% trying to eliminate non-reachable states: let { set of int: va_R = { d[va, vx] | va in dom(a[i]), vx in dom(x[i]) } diff { 0 } %% Bug in MZN 2.0.4 } in a[i+1] in va_R ) } in let { constraint forall(i in [n-i | i in 1..length(x)]) ( a[i] in { va | va in dom(a[i]) where exists(vx in dom(x[i]))(d[va, vx] in dom(a[i+1])) } /\ x[i] in { vx | vx in dom(x[i]) where exists(va in dom(a[i]))(d[va, vx] in dom(a[i+1])) } ) } in forall(i in index_set(x)) ( let { set of int: va_R = { d[va, vx] | va in dom(a[i]), vx in dom(x[i]) } diff { 0 } %% Bug in MZN 2.0.4 } in % my_trace(" S" ++ show(i) % ++ ": dom(a[i])=" ++ show(dom(a[i])) % ++ ", va_R="++show(va_R) % ++ ", index_set_2of2(eq_a) diff va_R=" ++ show(index_set_2of2(eq_a) diff va_R) % ++ ", dom(a[i+1])=" ++ show(dom(a[i+1])) % ) /\ a[i+1] in va_R %/\ a[i+1] in min(va_R)..max(va_R) ) % /\ my_trace(" regular -- domains after prop: index_set(x)=" ++ show(index_set(x)) % ++ ", dom_array(x)=" ++ show(dom_array(x)) % ++ ", dom_array(a)=" ++ show(dom_array(a)) % ++ "\n") % /\ my_trace("\n") /\ let { array[int, int] of var int: eq_a=eq_encode(a), array[int, int] of var int: eq_x=eq_encode(x), } in forall(i in index_set(x)) ( % a[i+1] = d[a[i], x[i]] % Determine a[i+1]. if card(dom(a[i]))*card(dom(x[i])) > nMZN__UnarySizeMax_1step_regular then %% Implication decomposition: forall(va in dom(a[i]), vx in dom(x[i]))( if d[va, vx] in dom(a[i+1]) then eq_a[i+1, d[va, vx]] >= eq_a[i, va] + eq_x[i, vx] - 1 %% The only-if part of conj else 1 >= eq_a[i, va] + eq_x[i, vx] endif ) else %% Network-flow decomposition: %% {regularIP07} M.-C. C{\^o}t{\'e}, B.~Gendron, and L.-M. Rousseau. %% \newblock Modeling the regular constraint with integer programming. let { % array[int, int] of set of int: VX_a12 = %% set of x for given a1 that produce a2 % array2d(1..S, 1..Q, [ { vx | vx in 1..S where d[va1, vx]==va2 } | va1 in dom(a[i]), va2 in dom(a[i+1]) ]); array[int, int] of var int: ppAX = eq_encode(a[i], x[i]); } in forall (va2 in dom(a[i+1])) ( eq_a[i+1, va2] = sum(va1 in dom(a[i]), vx in dom(x[i]) where d[va1, vx]==va2) (ppAX[va1, vx]) ) /\ forall(va1 in dom(a[i]), vx in dom(x[i]))( if not (d[va1, vx] in dom(a[i+1])) then ppAX[va1, vx] == 0 else true endif ) endif ) endif; libminizinc-2.8.2/share/minizinc/linear/fzn_inverse_in_range.mzn0000644000175000017500000000031414536677021023615 0ustar kaolkaolpredicate fzn_inverse_in_range(array[int] of var int: f, array[int] of var int: invf) = forall(i in index_set(f), j in index_set(invf)) ( (j == f[i] <-> i == invf[j]) ); libminizinc-2.8.2/share/minizinc/linear/fzn_circuit.mzn0000644000175000017500000000334014536677021021744 0ustar kaolkaolinclude "alldifferent.mzn"; % Linear version. predicate fzn_circuit(array[int] of var int: x) = if length(x) = 0 then true else let { set of int: S = index_set(x), int: l = min(S), int: u = max(S), int: n = card(S), constraint forall( i in S )( x[i] in S diff {i} ), %% Self-mapping and exclude i->i before alldifferent } in alldifferent(x) /\ % alldifferent(order) /\ if nMZN__fSECcuts>0 then let { array [int, int] of var int: eq_x = eq_encode( x ), constraint assert( l==min( index_set_2of2( eq_x ) ), "circuit: index set mismatch" ), %% self-mapping constraint assert( u==max( index_set_2of2( eq_x ) ), "circuit: index set mismatch" ), } in circuit__SECcuts(array1d(eq_x)) else true endif /\ if nMZN__fSECcuts<2 then %%% MTZ model. Note that INTEGER order vars seem better!: let { array[l+1..l+n-1] of var 2..n: order, } in forall (i,j in l+1..l+n-1 where i!=j /\ j in dom(x[i])) ( order[i] - order[j] + (n-1)* bool2int(x[i]==j) + (n-3)*bool2int(x[j]==i) %% the Desrochers & Laporte '91 term %%%% --- strangely enough it is much worse on vrp-s2-v2-c7_vrp-v2-c7_det_ADAPT_1_INVERSE.mzn! <= n-2 ) else true endif %% ... but seems improved with this (leaving also for SEC) /\ if n>2 then forall (i,j in S where i z=x-y<0 if absent( fMIPdomDiff ) then false %% seems best for Gurobi, worse for CBC else deopt( fMIPdomDiff ) endif; mzn_opt_only_range_domains = not fPostprocessDomains; %% currently unused %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Avoid creating new int vars %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % --------------------------------------------------------------------------------------- % opt bool: fAvoidNewInts; bool: fAvoidNI = %% Actually this is only for ..._lin_..., not for just x-y if absent( fAvoidNewInts ) then false else deopt( fAvoidNewInts ) endif; opt bool: fNewVarsInAuxEq; bool: fAuxIntEqOLD00 = if absent(fNewVarsInAuxEq) then false else deopt(fNewVarsInAuxEq) endif; bool: fAuxFloatEqOLD00 = if absent(fNewVarsInAuxEq) then false else deopt(fNewVarsInAuxEq) endif; %%%%%%%%%%%%%%%%%%%%% Redundant constraints ---------------------------------------------- % bool: fMZN__IgnoreRedundantCumulative=false; %% NOT WORKING NOW, use redefs_2.0.2.mzn: %%%%% bool: fMZN__IgnoreAllUserRedundant=false; %% ignore all user-spec redundant constr %%%%%%%%%%%%%%%%%%%%% Element, minimuum convex hull --------------------------------------- % opt bool: fXBZCuts01; %% orders 0, 1 opt bool: fXBZCutGen; %% only works if Cuts01 bool: fElementCutsXZ=false; %% Use simple XZ & XZB cuts for element bool: fElementCutsXZB = if absent(fXBZCuts01) then false else deopt(fXBZCuts01) endif; bool: fMinimumCutsXZ=false; %% Use simple XZ & XZB cuts for minimum bool: fMinimumCutsXZB = if absent(fXBZCuts01) then false else deopt(fXBZCuts01) endif; bool: fUseXBZCutGen = if absent(fXBZCutGen) then false else deopt(fXBZCutGen) endif; % ----------------------------------------------------------------------------------------- % bool: fIntTimesBool=true; %% Special handling of multiplication with a boolean(*const) %-----------------------------------------------------------------------------% % If not postprocessing domains: For unary encoding: maximal domain length to invoke it int: nMZN__UnarySizeMax_intTimes=20; int: nMZN__UnarySizeMax_cumul=2000; int: nMZN__UnarySizeMax_1step_regular=20000; %% network-flow decomp in the regular constraint int: nMZN__UnaryLenMin__ALL=1; %% can be used by the indiv. cases int: nMZN__UnaryLenMax__ALL=2000; %% can be used by the indiv. cases % Some more detailed parameters int: nMZN__UnaryLenMin_leq = 1; int: nMZN__UnaryLenMin_neq = nMZN__UnaryLenMin__ALL; int: nMZN__UnaryLenMin_eq = nMZN__UnaryLenMin__ALL; int: nMZN__UnaryLenMax_leq = -1; int: nMZN__UnaryLenMax_neq = nMZN__UnaryLenMax__ALL; int: nMZN__UnaryLenMax_eq = nMZN__UnaryLenMax__ALL; int: nMZN__UnaryLenMax_setIn = nMZN__UnaryLenMax__ALL; int: nMZN__UnaryLenMax_setInReif = nMZN__UnaryLenMax__ALL; %-----------------------------------------------------------------------------% % Strict inequality % The relative epsilon %%% Has the problem that when relating to upper bound of various differences, %%% getting different absolute eps...? %% float: float_lt_EPS_coef__ = 1e-03; ABANDONED 12.4.18 due to #207 %%% Absolute one, used everywhere %%% Might make no sense for floats with smaller domains etc. opt float: float_EPS; float: float_lt_EPS = if absent( float_EPS ) then 1e-6 else deopt( float_EPS ) endif; %-----------------------------------------------------------------------------% %%% Set =true to PRINT TRACING messages for some constraints: opt bool: fMIPTrace; bool: mzn__my_trace_on = if absent( fMIPTrace ) then false else deopt( fMIPTrace ) endif; test my_trace(string: msg) ::promise_total = if mzn__my_trace_on then trace(msg) else true endif; test my_trace(string: msg, bool: bb) ::promise_total = if mzn__my_trace_on then trace(msg, bb) else bb endif; function var bool: my_trace(string: msg, var bool: bb) ::promise_total = if mzn__my_trace_on then trace(msg, bb) else bb endif; %%% Set =true to PRINT TRACING messages for the currently debugged constraints: opt bool: fMIPTraceDBG; bool: mzn__my_trace__DBG_on = if absent( fMIPTraceDBG ) then false else deopt( fMIPTraceDBG ) endif; test my_trace__DBG(string: msg) ::promise_total = if mzn__my_trace__DBG_on then trace(msg) else true endif; libminizinc-2.8.2/share/minizinc/linear/subcircuit_wDummy.mzn0000644000175000017500000000541114536677021023144 0ustar kaolkaol/* Linearized version * Uses a predicate which constructs a subcircuit which always includes an extra dummy vertex * Is worse than the just slightly adapted standard variant... */ include "alldifferent.mzn"; %% Linear version predicate subcircuit(array[int] of var int: x) = let { set of int: S = index_set(x), int: l = min(S), int: u = max(S), int: n = card(S), constraint forall(i in S)(x[i] in l..u), array[l..u+1] of var l..u+1: xx, constraint forall(i in S)(xx[i] in dom(x[i]) union {u+1}), } in alldifferent(x) /\ subcircuit_wDummy(xx) /\ forall( i in S, j in dom(x[i]) )( %% also when i==j? eq_encode(x[i])[j] >= 2*eq_encode(xx[i])[j] + eq_encode(xx[i])[u+1] + eq_encode(xx[u+1])[j] - 1 %% -1 /\ eq_encode(x[i])[j] >= eq_encode(xx[i])[j] /\ eq_encode(x[i])[j] <= eq_encode(xx[i])[j] + eq_encode(xx[i])[u+1] /\ eq_encode(x[i])[j] <= eq_encode(xx[i])[j] + eq_encode(xx[u+1])[j] ) /\ forall( i in S )( eq_encode(x[i])[i] == eq_encode(xx[i])[i] ) ; %% Should include at least 2 nodes if >0? %% xx[n] is dummy predicate subcircuit_wDummy(array[int] of var int: x) = let { set of int: S = index_set(x), int: l = min(S), int: u = max(S), int: n = card(S), set of int: S__ = S diff {u}, %% the real nodes array[S__] of var 2..n: order, %% constraint order[n]==1, %% fix the dummy %% var bool: empty = (firstin == u+1), no, break 2-cycles with dummy } in alldifferent(x) /\ % NO alldifferent(order) /\ %%% MTZ model. Note that INTEGER order vars seem better!: forall( i in S__, j in dom(x[i]) where i!=j /\ j!=u )( order[i] - order[j] + (n-1)*eq_encode(x[i])[j] % + (n-3)*bool2int(x[j]==i) %% the Desrochers & Laporte '91 term % --- strangely enough it is much worse on vrp-s2-v2-c7_vrp-v2-c7_det_ADAPT_1_INVERSE.mzn! <= n-2 ) /\ %% Break 2-cycles with dummy: forall( i in S__ )( eq_encode(x[i])[u] + eq_encode(x[u])[i] <= 1 /\ %% Ensure dummy is in: if i in dom(x[i]) then eq_encode(x[i])[i] >= eq_encode(x[u])[u] else true endif ) /\ % Symmetry? Each node that is not in is numbered after the lastin node. forall(i in S) ( true % (not ins[i]) <-> (n == order[i]) ) ; predicate subcircuit_reif(array[int] of var int: x, var bool: b) = abort("Reified subcircuit/1 is not supported."); %-----------------------------------------------------------------------------% %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/linear/fzn_cumulative.mzn0000644000175000017500000000762514536677021022472 0ustar kaolkaol/** @group globals.scheduling Requires that a set of tasks given by start times \a s, durations \a d, and resource requirements \a r, never require more than a global resource bound \a b at any one time. Assumptions: - forall \p i, \a d[\p i] >= 0 and \a r[\p i] >= 0 Linear version. */ predicate fzn_cumulative(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b ::promise_ctx_monotone) = if mzn_in_redundant_constraint() /\ fMZN__IgnoreRedundantCumulative then true else let { set of int: tasks = {i | i in index_set(s) where ub(r[i]) > 0 /\ ub(d[i]) > 0 }, set of int: times = dom_array( [ s[i] | i in tasks ] ) } in if 0==card(tasks) then /*true*/ 0==card(index_set(s)) \/ b>=0 elseif MZN__Cumulative_Fixed_d_r /\ is_fixed(d) /\ is_fixed(r) /\ is_fixed(b) then fzn_cumulative_fixed_d_r(s, fix(d), fix(r), fix(b)) elseif nMZN__UnarySizeMax_cumul>=card(times)*card(tasks) then cumulative_time_decomp(s, d, r, b, times) else cumulative_task_decomp(s, d, r, b) endif endif; %% Can be called with a given set of times: predicate cumulative_set_times(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b, set of int: TIMES01) = assert(index_set(s) == index_set(d) /\ index_set(s) == index_set(r), "cumulative: the 3 array arguments must have identical index sets", assert(lb_array(d) >= 0 /\ lb_array(r) >= 0, "cumulative: durations and resource usages must be non-negative", let { set of int: tasks = {i | i in index_set(s) where ub(r[i]) > 0 /\ ub(d[i]) > 0 }, set of int: times = dom_array( [ s[i] | i in tasks ] ) intersect TIMES01 } in if false then cumulative_time_decomp(s, d, r, b, times) else cumulative_task_decomp(s, d, r, b) endif )); predicate cumulative_time_decomp(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b ::promise_ctx_monotone, set of int: TIMES01) = let { set of int: tasks = {i | i in index_set(s) where ub(r[i]) > 0 /\ ub(d[i]) > 0 }, set of int: times = { i | i in min([ lb(s[i]) | i in tasks ]) .. max([ ub(s[i]) + ub(d[i]) | i in tasks ]) where i in TIMES01 } } in forall( t in times ) ( b >= sum( i in tasks ) ( if is_fixed(d[i]) then bool2int( s[i] in t-fix(d[i])+1..t ) else bool2int( s[i] <= t /\ t < s[i] + d[i] ) endif * r[i] ) ); predicate cumulative_task_decomp(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b ::promise_ctx_monotone) = let { set of int: tasks = {i | i in index_set(s) where ub(r[i]) > 0 /\ ub(d[i]) > 0 } } in forall( j in tasks) ( b-r[j] >= sum( i in tasks where i != j /\ lb(s[i])<=ub(s[j]) /\ lb(s[j]) ..)) 82s vs 45s on ProjPlanning_12_8libminizinc-2.8.2/share/minizinc/linear/fzn_if_then_else_float.mzn0000644000175000017500000000043514536677021024115 0ustar kaolkaolpredicate fzn_if_then_else_float(array[int] of var bool: c, array[int] of float: x, var float: y) = let { array[index_set(c)] of var 0..1: d; } in forall (i in index_set(c)) (sum(j in 1..i-1)(c[j])+d[i] >= c[i]) /\ sum(d)=1 /\ y = sum (i in index_set(c)) ( d[i]*x[i] ); libminizinc-2.8.2/share/minizinc/std/0000755000175000017500000000000014536677021016217 5ustar kaolkaollibminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_opt_float.mzn0000644000175000017500000000057614536677021024325 0ustar kaolkaolpredicate fzn_if_then_else_opt_float(array[int] of var bool: c, array[int] of opt float: x, var opt float: y) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/increasing_bool.mzn.deprecated.mzn0000644000175000017500000000022314536677021025001 0ustar kaolkaolpredicate increasing_bool(array[$X] of var bool: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_network_flow_reif.mzn0000644000175000017500000000106414536677021023350 0ustar kaolkaolpredicate fzn_network_flow_reif(array[int,1..2] of int: arc, array[int] of int: balance, array[int] of var int: flow, var bool: b) = let { int: source_node = 1; int: sink_node = 2; set of int: ARCS = index_set_1of2(arc); set of int: NODES = index_set(balance); } in b <-> forall (i in NODES) ( sum (j in ARCS where i == arc[j,source_node]) (flow[j]) - sum (j in ARCS where i == arc[j,sink_node]) (flow[j]) = balance[i] ); libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_low_up_closed.mzn0000644000175000017500000000077314536677021026372 0ustar kaolkaolpredicate fzn_global_cardinality_low_up_closed(array[int] of var int: x, array[int] of int: cover, array[int] of int: lbound, array[int] of int: ubound) = forall(i in index_set(x))( x[i] in { d | d in array2set(cover) } ) /\ global_cardinality_low_up(x, cover, lbound, ubound) /\ % Implied condition length(x) in sum(lbound)..sum(ubound); include "global_cardinality_low_up.mzn"; libminizinc-2.8.2/share/minizinc/std/fzn_subgraph_int_reif.mzn0000644000175000017500000000061014536677021023311 0ustar kaolkaolpredicate fzn_subgraph_reif(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of var bool: ns, array[int] of var bool: es, var bool: b) = b <-> forall(e in 1..E) ( (es[e] -> ns[from[e]]) /\ (es[e] -> ns[to[e]]) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_lex_lesseq_bool_reif.mzn0000644000175000017500000000114214536677021024004 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_lesseq_bool_reif(array[int] of var bool: x, array[int] of var bool: y, var bool: c) = c <-> lex_lesseq_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/count_neq.mzn0000644000175000017500000000173014536677021020741 0ustar kaolkaolinclude "fzn_count_neq_par.mzn"; include "fzn_count_neq.mzn"; include "fzn_count_neq_par_reif.mzn"; include "fzn_count_neq_reif.mzn"; /** @group globals.counting Constrains \a c to be not equal to the number of occurrences of \a y in \a x. */ predicate count_neq(array[$X] of var $$E: x, var $$E: y, var int: c) = fzn_count_neq(array1d(x), y, c); /** @group globals.counting Constrains \a c to be not equal to the number of occurrences of \a y in \a x. */ predicate count_neq(array[$X] of var opt $$E: x, var $$E: y, var int: c) =let { % Set <> to something not y int: def = if 0 in dom(y) then lb(y)-1 else 0 endif; } in count_neq([i default def | i in x], y, c); /** @group globals.counting Constrains \a c to be not equal to the number of occurrences of \a y in \a x. */ predicate count_neq(array[$X] of var $$E: x, $$E: y, int: c) = fzn_count_neq_par(array1d(x), y, c); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/all_equal_set.mzn.deprecated.mzn0000644000175000017500000000022714536677021024462 0ustar kaolkaolpredicate all_equal_set(array[$X] of var set of int: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_cumulative_opt_decomp.mzn0000644000175000017500000000407514536677021024217 0ustar kaolkaolpredicate fzn_cumulative_opt_decomp(array[int] of var opt int: s, array[int] of var int: d, array[int] of var int: r, var int: b) = let { set of int: Tasks = {i | i in index_set(s) where ub(occurs(s[i])) > 0 /\ ub(r[i]) > 0 /\ ub(d[i]) > 0 } } in if 0==card(Tasks) then /*true*/ 0==card(index_set(s)) \/ b>=0 else let { int: early = min([ lb(s[i]) | i in Tasks ]), int: late = max([ ub(s[i]) + ub(d[i]) | i in Tasks ]) } in ( if late - early > 5000 then fzn_cumulative_opt_task(s, d, r, b) else fzn_cumulative_opt_time(s, d, r, b) endif ) endif ; predicate fzn_cumulative_opt_task(array[int] of var opt int: s, array[int] of var int: d, array[int] of var int: r, var int: b) = let { set of int: Tasks = {i | i in index_set(s) where ub(occurs(s[i])) > 0 /\ ub(r[i]) > 0 /\ ub(d[i]) > 0 } } in ( forall( j in Tasks ) ( occurs(s[j]) -> b >= r[j] + sum( i in Tasks where i != j ) ( (occurs(s[i]) /\ deopt(s[i]) <= deopt(s[j]) /\ deopt(s[j]) < deopt(s[i]) + d[i] ) * r[i] ) ) ); predicate fzn_cumulative_opt_time(array[int] of var opt int: s, array[int] of var int: d, array[int] of var int: r, var int: b) = let { set of int: Tasks = {i | i in index_set(s) where ub(occurs(s[i])) > 0 /\ ub(r[i]) > 0 /\ ub(d[i]) > 0 }, int: early = min([ lb(s[i]) | i in Tasks ]), int: late = max([ ub(s[i]) + ub(d[i]) | i in Tasks ]) } in ( forall( t in early..late ) ( b >= sum( i in Tasks ) ( (occurs(s[i]) /\ deopt(s[i]) <= t /\ t < deopt(s[i]) + d[i]) * r[i] ) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_at_least_int.mzn0000644000175000017500000000053014536677021022266 0ustar kaolkaolinclude "count_fn.mzn"; %-----------------------------------------------------------------------------% % Requires at least 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate fzn_at_least_int(int: n, array[int] of var int: x, int: v) = count(x, v) >= n; libminizinc-2.8.2/share/minizinc/std/fzn_member_bool.mzn0000644000175000017500000000050614536677021022105 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array or set 'x'. %-----------------------------------------------------------------------------% predicate fzn_member_bool(array[int] of var bool: x, var bool: y) = exists(i in index_set(x)) ( x[i] == y ); libminizinc-2.8.2/share/minizinc/std/fzn_subgraph_enum.mzn0000644000175000017500000000051214536677021022457 0ustar kaolkaolpredicate fzn_subgraph(array[int] of $$N: from, array[int] of $$N: to, array[$$N] of var bool: ns, array[int] of var bool: es) = forall(e in index_set(from)) ( (es[e] -> ns[from[e]]) /\ (es[e] -> ns[to[e]]) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_span_reif.mzn0000644000175000017500000000061114536677021021566 0ustar kaolkaolpredicate fzn_span_reif(var opt int: s0, var int: d0, array[int] of var opt int: s, array[int] of var int: d, var bool: b) = b <-> ( (occurs(s0) <-> exists(i in index_set(s))(occurs(s[i]))) /\ s0 = min(s) /\ (absent(s0) -> d0 = 0) /\ s0 ~+ d0 = max([s[i] ~+ d[i] | i in index_set(s)]) ); libminizinc-2.8.2/share/minizinc/std/fzn_diffn_nonstrict_k.mzn0000644000175000017500000000171614536677021023332 0ustar kaolkaolpredicate fzn_diffn_nonstrict_k(array[int,int] of var int: box_posn, array[int,int] of var int: box_size) = let { set of int: DIMS= index_set_2of2(box_posn) } in forall(b1, b2 in index_set_1of2(box_posn) where b1 < b2) (fzn_diffn_nonstrict_nonoverlap_k([ box_posn[b1,j] | j in DIMS ], [ box_size[b1,j] | j in DIMS ], [ box_posn[b2,j] | j in DIMS ], [ box_size[b2,j] | j in DIMS ] ) ) ; predicate fzn_diffn_nonstrict_nonoverlap_k(array[int] of var int: x1, array[int] of var int: w1, array[int] of var int: x2, array[int] of var int: w2) = exists(j in index_set(x1)) (w1[j] = 0 \/ w2[j] = 0 \/ x1[j] + w1[j] <= x2[j] \/ x2[j] + w2[j] <= x1[j]); libminizinc-2.8.2/share/minizinc/std/arg_min_float.mzn0000644000175000017500000000020614536677021021544 0ustar kaolkaolinclude "fzn_arg_min_float.mzn"; predicate minimum_arg_float(array[$$E] of var float: x, var $$E: i) = fzn_minimum_arg_float(x, i); libminizinc-2.8.2/share/minizinc/std/fzn_lex_lesseq_bool.mzn0000644000175000017500000000112014536677021022773 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_lesseq_bool(array[int] of var bool: x ::promise_ctx_antitone, array[int] of var bool: y ::promise_ctx_monotone) = lex_lesseq_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_regular_regexp.mzn0000644000175000017500000000007414536677021022636 0ustar kaolkaolpredicate fzn_regular(array[int] of var int: x, string: r); libminizinc-2.8.2/share/minizinc/std/fzn_subcircuit_reif.mzn0000644000175000017500000000035314536677021023004 0ustar kaolkaolinclude "alldifferent.mzn"; predicate fzn_subcircuit_reif(array[int] of var int: x, var bool: b) = abort("Reified subcircuit/1 is not supported."); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/atleast.mzn0000644000175000017500000000022414536677021020400 0ustar kaolkaol% The actual definitions are in at_least.mzn. % This file is used to handle the case where users include % "atleast.mzn"; % include "at_least.mzn"; libminizinc-2.8.2/share/minizinc/std/write.mzn0000644000175000017500000000150514536677021020100 0ustar kaolkaolinclude "fzn_write.mzn"; include "fzn_write_reif.mzn"; /** @group globals.array Creates a new array \a O from an input array \a I with a change at position \a i to take value \a v \a I is an array of integers \a O is an array of integers with same index set as \a I \a i is an index for \a I \a v is an integer value */ predicate write(array[$$E] of var int: I, var int: i, var int: v, array[$$E] of var int: O) = assert(index_set(O) = index_set(I),"writet: index set of I must be same as O") /\ fzn_write(I, i, v, O); function array[int] of var int: write(array[int] of var int: I, var int: i, var int: v) = let { array[index_set(I)] of var int: O; constraint fzn_write(I,i,v,O); } in O; %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_disjunctive_strict.mzn0000644000175000017500000000042314536677021023540 0ustar kaolkaolpredicate fzn_disjunctive_strict(array[int] of var int: s, array[int] of var int: d) = forall (i in index_set(d)) (d[i] >= 0) /\ forall (i,j in index_set(d) where i dreachable(N,2*E,dfrom,dto,r,ns,des); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_span.mzn0000644000175000017500000000047614536677021020572 0ustar kaolkaolpredicate fzn_span(var opt int: s0, var int: d0, array[int] of var opt int: s, array[int] of var int: d) = (occurs(s0) <-> exists (i in index_set(s)) (occurs(s[i]))) /\ s0 = min_weak(s) /\ (absent(s0) -> d0 = 0) /\ s0 ~+ d0 = max_weak([s[i] ~+ d[i] | i in index_set(s)]); libminizinc-2.8.2/share/minizinc/std/fzn_increasing_int_opt_reif.mzn0000644000175000017500000000127714536677021024514 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order iff b is true %-----------------------------------------------------------------------------% predicate fzn_increasing_int_opt_reif(array[int] of var opt int: x, var bool: b) = let { array[int] of var opt int: xx = array1d(x); array[1..length(xx)] of var int: y; constraint forall(i in 1..length(xx)) ( y[i] = if occurs(xx[i]) then deopt(xx[i]) elseif i = 1 then lb_array(xx) else y[i-1] endif ); } in b <-> forall (i in 2..length(y) where occurs(xx[i])) ( deopt(xx[i]) >= y[i-1] ); libminizinc-2.8.2/share/minizinc/std/arg_min_bool.mzn0000644000175000017500000000020214536677021021366 0ustar kaolkaolinclude "fzn_arg_min_bool.mzn"; predicate minimum_arg_bool(array[$$E] of var bool: x, var $$E: i) = fzn_minimum_arg_bool(x, i); libminizinc-2.8.2/share/minizinc/std/lex_chain_less.mzn0000644000175000017500000000127114536677021021726 0ustar kaolkaolinclude "fzn_lex_chain_less_bool.mzn"; include "fzn_lex_chain_less_bool_reif.mzn"; include "fzn_lex_chain_less_int.mzn"; include "fzn_lex_chain_less_int_reif.mzn"; /** @group globals.lexicographic Requires that the columns of matrix \a a are lexicographically sorted, strictly increasing. */ predicate lex_chain_less(array[int, int] of var bool: a) = if card(index_set_2of2(a)) > 1 then fzn_lex_chain_less_bool(a) endif; /** @group globals.lexicographic Requires that the columns of matrix \a a are lexicographically sorted, strictly increasing. */ predicate lex_chain_less(array[int, int] of var int: a) = if card(index_set_2of2(a)) > 1 then fzn_lex_chain_less_int(a) endif; libminizinc-2.8.2/share/minizinc/std/arg_min_float.mzn.deprecated.mzn0000644000175000017500000000024314536677021024447 0ustar kaolkaolpredicate minimum_arg_float(array[$$E] of var float: x, var $$E: i) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/lex_chain_greatereq.mzn0000644000175000017500000000173614536677021022745 0ustar kaolkaolinclude "lex_chain_lesseq.mzn"; /** @group globals.lexicographic Requires that the columns of matrix \a a are lexicographically sorted, non-increasing. */ predicate lex_chain_greatereq(array[int, int] of var bool: a) = if 1>=card(index_set_2of2(a)) then true else lex_chain_lesseq( array2d( index_set_1of2(a), index_set_2of2(a), [a[i, max(index_set_2of2(a)) - j + min(index_set_2of2(a))] | i in index_set_1of2(a), j in index_set_2of2(a)] ) ) endif; /** @group globals.lexicographic Requires that the columns of matrix \a a are lexicographically sorted, non-increasing. */ predicate lex_chain_greatereq(array[int, int] of var int: a) = if 1>=card(index_set_2of2(a)) then true else lex_chain_lesseq( array2d( index_set_1of2(a), index_set_2of2(a), [a[i, max(index_set_2of2(a)) - j + min(index_set_2of2(a))] | i in index_set_1of2(a), j in index_set_2of2(a)] ) ) endif; libminizinc-2.8.2/share/minizinc/std/fzn_seq_precede_chain_set_reif.mzn0000644000175000017500000000021614536677021025122 0ustar kaolkaolpredicate fzn_seq_precede_chain_set_reif(array[int] of var set of int: X) = abort("Reified seq_precede_chain constraint is not supported"); libminizinc-2.8.2/share/minizinc/std/fzn_exactly_set_reif.mzn0000644000175000017500000000057314536677021023160 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires exactly 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate fzn_exactly_set_reif(int: n, array[int] of var set of int: x, set of int: v, var bool: b) = b <-> n == sum(i in index_set(x)) ( x[i] == v ); libminizinc-2.8.2/share/minizinc/std/fzn_count_gt_reif.mzn0000644000175000017500000000057614536677021022461 0ustar kaolkaolinclude "count_fn.mzn"; predicate fzn_count_gt_reif(array[int] of var int: x, var int: y, var int: c, var bool: b) = let { var int: z = count(x,y) } in b <-> z < c; % This needs to be written with a let rather than count(x,y) < c % so that the automatic rewriting of the latter doesn't kick in %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_lex_chain_lesseq_orbitope_reif.mzn0000644000175000017500000000113114536677021026034 0ustar kaolkaolinclude "lex_lesseq.mzn"; predicate fzn_lex_chain_lesseq_orbitope_reif( array[int, int] of var int: a, int: kind, var bool: b) = let { set of int: is2 = index_set_2of2(a); } in b <-> ( forall(j in is2 where j+1 in is2) ( lex_lesseq(col(a, j), col(a, j+1)) ) /\ if 1==kind then forall(i in index_set_1of2(a))( 1 == sum(row(a, i)) ) elseif 2==kind then forall(i in index_set_1of2(a))( 1 >= sum(row(a, i)) ) else true endif ); libminizinc-2.8.2/share/minizinc/std/fzn_all_disjoint_reif.mzn0000644000175000017500000000027514536677021023306 0ustar kaolkaolinclude "fzn_disjoint.mzn"; predicate fzn_all_disjoint_reif(array[int] of var set of int: S, var bool: b) = b <-> forall(i,j in index_set(S) where i < j) ( fzn_disjoint(S[i], S[j]) ); libminizinc-2.8.2/share/minizinc/std/table.mzn0000644000175000017500000000264314536677021020041 0ustar kaolkaolinclude "fzn_table_bool.mzn"; include "fzn_table_bool_reif.mzn"; include "fzn_table_int.mzn"; include "fzn_table_int_reif.mzn"; include "fzn_table_int_opt.mzn"; /** @group globals.extensional Represents the constraint \a x in \a t where we consider each row in \a t to be a tuple and \a t as a set of tuples. */ predicate table(array[$$E] of var bool: x, array[int, $$E] of bool: t) = assert( index_set_2of2(t) == index_set(x), "The second dimension of the table must equal the number of variables " ++ "in the first argument", ) /\ fzn_table_bool(x, t); /** @group globals.extensional Represents the constraint \a x in \a t where we consider each row in \a t to be a tuple and \a t as a set of tuples. */ predicate table(array[$$E] of var int: x, array[int, $$E] of int: t) = assert( index_set_2of2(t) == index_set(x), "The second dimension of the table must equal the number of variables " ++ "in the first argument", ) /\ fzn_table_int(x, t); /** @group globals.extensional Represents the constraint \a x in \a t if the variable \a x_i and the value \a t_i occur where we consider each row in \a t to be a tuple and \a t as a set of tuples. */ predicate table(array[int] of var opt int: x, array[int, int] of opt int: t) = assert( index_set_2of2(t) == index_set(x), "The second dimension of the table must equal the number of variables " ++ "in the first argument", ) /\ fzn_table_int_opt(x, t); libminizinc-2.8.2/share/minizinc/std/bin_packing_load.mzn0000644000175000017500000000144314536677021022212 0ustar kaolkaolinclude "bin_packing_load_fn.mzn"; include "fzn_bin_packing_load.mzn"; include "fzn_bin_packing_load_reif.mzn"; /** @group globals.packing Requires that each item \p i with weight \a w[\p i], be put into \a bin[\p i] such that the sum of the weights of the items in each bin \p b is equal to \a load[\p b]. Assumptions: - forall \p i, \a w[\p i] >=0 */ predicate bin_packing_load(array[int] of var int: load, array[int] of var int: bin, array[int] of int: w) = assert(index_set(bin) == index_set(w), "bin_packing_load: the bin and weight arrays must have identical index sets", assert(lb_array(w) >= 0, "bin_packing_load: the weights must be non-negative", fzn_bin_packing_load(load, bin, w) )); libminizinc-2.8.2/share/minizinc/std/fzn_bounded_dpath_enum.mzn0000644000175000017500000000047014536677021023447 0ustar kaolkaolinclude "path.mzn"; predicate fzn_bounded_dpath(array[int] of $$N: from, array[int] of $$N: to, array[int] of int: w, var $$N: s, var $$N: t, array[$$N] of var bool: ns, array[int] of var bool: es, var int: K) = dpath(from,to,s,t,ns,es) /\ K = sum(e in index_set(es))(es[e]*w[e]); libminizinc-2.8.2/share/minizinc/std/global_cardinality.mzn0000644000175000017500000001364214536677021022576 0ustar kaolkaolinclude "fzn_global_cardinality.mzn"; include "fzn_global_cardinality_reif.mzn"; include "fzn_global_cardinality_opt.mzn"; include "fzn_global_cardinality_set.mzn"; include "fzn_global_cardinality_low_up.mzn"; include "fzn_global_cardinality_low_up_reif.mzn"; include "fzn_global_cardinality_low_up_opt.mzn"; include "fzn_global_cardinality_low_up_set.mzn"; /** @group globals.counting Requires that the number of occurrences of \a cover[\p i] in \a x is \a counts[\p i]. */ predicate global_cardinality(array[$X] of var $$E: x, array[$Y] of $$E: cover, array[$Y] of var int: counts) = assert(index_sets_agree(cover, counts), "global_cardinality: " ++ "cover has index sets " ++ show_index_sets(cover) ++ " and count has index sets " ++ show_index_sets(counts) ++ ", but they must have identical index sets", if length(x) == 0 then forall(c in array1d(counts))(c = 0) else fzn_global_cardinality(array1d(x), array1d(cover), array1d(counts)) endif ); /** @group globals.counting Requires that the number of occurrences of \a cover[\p i] in \a x is \a counts[\p i]. */ predicate global_cardinality(array[$X] of var opt $$E: x, array[$Y] of $$E: cover, array[$Y] of var int: counts) = assert(index_sets_agree(cover, counts), "global_cardinality: " ++ "cover has index sets " ++ show_index_sets(cover) ++ " and count has index sets " ++ show_index_sets(counts) ++ ", but they must have identical index sets", if length(x) == 0 then forall(c in array1d(counts))(c = 0) else fzn_global_cardinality_opt(array1d(x), array1d(cover), array1d(counts)) endif ); /** @group globals.counting Requires that for all \p i, the value \a cover[\p i] appears at least \a lbound[\p i] and at most \a ubound[\p i] times in the array \a x. */ predicate global_cardinality(array[$X] of var $$E: x, array[$Y] of $$E: cover, array[$Y] of int: lbound, array[$Y] of int: ubound) = assert( index_sets_agree(cover,lbound) /\ index_sets_agree(cover,ubound), "global_cardinality: " ++ "cover has index sets " ++ show_index_sets(cover) ++ ", lbound has index sets " ++ show_index_sets(lbound) ++ ", and ubound has index sets " ++ show_index_sets(lbound) ++ ", but they must have identical index sets", if length(x) == 0 then assert(forall(l in array1d(lbound))( l <= 0) /\ forall(u in array1d(ubound))( u >= 0) \/ length(cover) == 0, "global_cardinality_low_up: " ++ "lbound and ubound must allow a count of 0 when x is empty, or also be empty", true) else fzn_global_cardinality_low_up(array1d(x), array1d(cover), array1d(lbound), array1d(ubound)) endif ); /** @group globals.counting Requires that for all \p i, the value \a cover[\p i] appears at least \a lbound[\p i] and at most \a ubound[\p i] times in the array \a x. */ predicate global_cardinality(array[$X] of var opt $$E: x, array[$Y] of $$E: cover, array[$Y] of int: lbound, array[$Y] of int: ubound) = assert( index_sets_agree(cover,lbound) /\ index_sets_agree(cover,ubound), "global_cardinality_low_up: " ++ "cover has index sets " ++ show_index_sets(cover) ++ ", lbound has index sets " ++ show_index_sets(lbound) ++ ", and ubound has index sets " ++ show_index_sets(lbound) ++ ", but they must have identical index sets", if length(x) == 0 then assert(forall(l in array1d(lbound))( l <= 0) /\ forall(u in array1d(ubound))( u >= 0) \/ length(cover) == 0, "global_cardinality_low_up: " ++ "lbound and ubound must allow a count of 0 when x is empty, or also be empty", true) else fzn_global_cardinality_low_up_opt(array1d(x), array1d(cover), array1d(lbound), array1d(ubound)) endif ); /** @group globals.counting Requires that the number of occurrences of \a cover[\p i] in \a x is \a counts[\p i]. */ predicate global_cardinality(array[$X] of var set of $$E: x, array[$Y] of $$E: cover, array[$Y] of var int: counts) = assert(index_sets_agree(cover, counts), "global_cardinality: " ++ "cover has index sets " ++ show_index_sets(cover) ++ " and count has index sets " ++ show_index_sets(counts) ++ ", but they must have identical index sets", if length(x) == 0 then forall(c in array1d(counts))(c = 0) else fzn_global_cardinality_set(array1d(x), array1d(cover), array1d(counts)) endif ); /** @group globals.counting Requires that for all \p i, the value \a cover[\p i] appears at least \a lbound[\p i] and at most \a ubound[\p i] times in the array \a x. */ predicate global_cardinality(array[$X] of var set of $$E: x, array[$Y] of $$E: cover, array[$Y] of int: lbound, array[$Y] of int: ubound) = assert( index_sets_agree(cover,lbound) /\ index_sets_agree(cover,ubound), "global_cardinality_low_up: " ++ "cover has index sets " ++ show_index_sets(cover) ++ ", lbound has index sets " ++ show_index_sets(lbound) ++ ", and ubound has index sets " ++ show_index_sets(lbound) ++ ", but they must have identical index sets", if length(x) == 0 then assert(forall (l in lbound) (l <= 0) /\ forall (u in ubound) (u >= 0) \/ length(cover) == 0, "global_cardinality_low_up: " ++ "lbound and ubound must allow a count of 0 when x is empty, or also be empty", true) else fzn_global_cardinality_low_up_set(array1d(x), array1d(cover), array1d(lbound), array1d(ubound)) endif ); libminizinc-2.8.2/share/minizinc/std/member_float.mzn0000644000175000017500000000057214536677021021405 0ustar kaolkaolinclude "fzn_member_float.mzn"; include "fzn_member_float_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array or set 'x'. %-----------------------------------------------------------------------------% predicate member_float(array[int] of var float: x, var float: y) = fzn_member_float(x, y); libminizinc-2.8.2/share/minizinc/std/table_bool.mzn.deprecated.mzn0000644000175000017500000000025714536677021023755 0ustar kaolkaolpredicate table_bool( array[$$E] of var bool: x, array[int, $$E] of bool: t ) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_distribute.mzn0000644000175000017500000000042114536677021021775 0ustar kaolkaolinclude "count.mzn"; predicate fzn_distribute(array[int] of var int: card, array[int] of var int: value, array[int] of var int: base) = forall (i in index_set(card)) ( count(base, value[i], card[i]) ); libminizinc-2.8.2/share/minizinc/std/value_precede_set.mzn.deprecated.mzn0000644000175000017500000000025414536677021025326 0ustar kaolkaolpredicate value_precede_set($$E: s, $$E: t, array[int] of var set of $$E: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_count_leq.mzn0000644000175000017500000000055114536677021021614 0ustar kaolkaolinclude "count_fn.mzn"; predicate fzn_count_leq(array[int] of var int: x, var int: y, var int: c) = let { var int: z = count(x,y) } in z >= c; % This needs to be written with a let rather than count(x,y) >= c % so that the automatic rewriting of the latter doesn't kick in %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_arg_min_float.mzn0000644000175000017500000000163314536677021022426 0ustar kaolkaolpredicate fzn_minimum_arg_float(array[int] of var float: x, var int: i) = let { int: l = min(index_set(x)); int: u = max(index_set(x)); float: ly = lb_array(x); } in if exists(j in l..u)(ub(x[j]) = ly) then let { array[l..u] of var bool: d; } in % min is known to be ly x[i] = ly /\ % ith case must be equal to ub forall(j in l..u)(x[j] = ly -> i <= j) /\ % lower bound d[l] = (x[l] != ly) /\ forall(j in l+1..u)(d[j] <-> (d[j-1] /\ (x[j] != ly))) /\ forall(j in l..u)(d[j] -> i >= j+1) % upper bound else let { float: uy = ub_array(x); array[l..u] of var ly..uy: y; array[l..u] of var l..u: mi; } in y[l] = x[l] /\ mi[l] = l /\ i = mi[u] /\ forall (j in l+1 .. u) ( y[j] == min(x[j],y[j-1]) /\ mi[j] = if y[j-1] <= x[j] then mi[j-1] else j endif ) endif; libminizinc-2.8.2/share/minizinc/std/arg_min_int.mzn0000644000175000017500000000017614536677021021237 0ustar kaolkaolinclude "fzn_arg_min_int.mzn"; predicate minimum_arg_int(array[$$E] of var int: x, var $$E: i) = fzn_minimum_arg_int(x, i); libminizinc-2.8.2/share/minizinc/std/fzn_disjoint.mzn0000644000175000017500000000013414536677021021443 0ustar kaolkaolpredicate fzn_disjoint(var set of int: s1, var set of int: s2) = s1 intersect s2 == {}; libminizinc-2.8.2/share/minizinc/std/fzn_cumulatives.mzn0000644000175000017500000000117314536677021022165 0ustar kaolkaolinclude "fzn_cumulatives_decomp.mzn"; % min_m is the first machine (which is the minimum, of the index set of b). % For native implementations, you can subtract (min_m - 1) from the m array % values to obtain 1-based machine numbers. predicate fzn_cumulatives(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, array[int] of var int: m, array[int] of var int: b, bool: upper, int: min_m) = fzn_cumulatives_decomp(s, d, r, m, b, upper); libminizinc-2.8.2/share/minizinc/std/increasing_set.mzn.deprecated.mzn0000644000175000017500000000023014536677021024637 0ustar kaolkaolpredicate increasing_set(array[$X] of var set of int: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_regular_set_reif.mzn0000644000175000017500000000037314536677021023146 0ustar kaolkaolpredicate fzn_regular_reif(array[int] of var int: x, int: Q, set of int: S, array[int,int] of int: d, int: q0, set of int: F, var bool: b) = abort("Reified regular constraint is not supported"); libminizinc-2.8.2/share/minizinc/std/distribute.mzn0000644000175000017500000000110114536677021021114 0ustar kaolkaolinclude "fzn_distribute.mzn"; include "fzn_distribute_reif.mzn"; /** @group globals.counting Requires that \a card[\p i] is the number of occurrences of \a value[\p i] in \a base. The values in \a value need not be distinct. */ predicate distribute(array[$X] of var int: card, array[$X] of var int: value, array[$Y] of var int: base) = assert(index_sets_agree(card, value), "distribute: card and value arrays must have identical index sets", fzn_distribute(array1d(card), array1d(value), array1d(base)) ); libminizinc-2.8.2/share/minizinc/std/network_flow.mzn0000644000175000017500000000362414536677021021472 0ustar kaolkaolinclude "fzn_network_flow.mzn"; include "fzn_network_flow_reif.mzn"; include "fzn_network_flow_cost.mzn"; include "fzn_network_flow_cost_reif.mzn"; /** @group globals.graph Defines a network flow constraint. @param arc: a directed arc of the flow network. Arc \p i connects node \a arc[\p i,1] to node \a arc[\p i,2]. @param balance: the difference between input and output flow for each node. @param flow: the flow going through each arc. */ predicate network_flow(array[int,1..2] of int: arc, array[int] of int: balance, array[int] of var int: flow) = let { set of int: ARCS = index_set_1of2(arc); set of int: NODES = index_set(balance); } in assert ( ARCS == index_set(flow) /\ lb_array(arc) >= min(NODES) /\ ub_array(arc) <= max(NODES), "network_flow: wrong sizes of input array parameters", fzn_network_flow(arc, balance, flow) ); /** @group globals.graph Defines a network flow constraint with cost. @param arc: a directed arc of the flow network. Arc \p i connects node \a arc[\p i,1] to node \a arc[\p i,2]. @param balance: the difference between input and output flow for each node. @param weight: the unit cost of the flow through the arc. @param flow: the flow going through each arc. @param cost: the overall cost of the flow. */ predicate network_flow_cost(array[int,1..2] of int: arc, array[int] of int: balance, array[int] of int: weight, array[int] of var int: flow, var int: cost) = let { set of int: ARCS = index_set_1of2(arc); set of int: NODES = index_set(balance); } in assert ( ARCS == index_set(flow) /\ ARCS == index_set(weight) /\ lb_array(arc) >= min(NODES) /\ ub_array(arc) <= max(NODES), "network_flow: wrong sizes of input array parameters", fzn_network_flow_cost(arc, balance, weight, flow, cost) ); libminizinc-2.8.2/share/minizinc/std/fzn_lex_lesseq_set.mzn0000644000175000017500000000105414536677021022641 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_lesseq_set(array[int] of var set of int: x, array[int] of var set of int: y) = lex_lesseq_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_link_set_to_booleans.mzn0000644000175000017500000000020614536677021024014 0ustar kaolkaolpredicate fzn_link_set_to_booleans(var set of int: s, array[int] of var bool: b) = forall(i in index_set(b)) ( b[i] <-> i in s ); libminizinc-2.8.2/share/minizinc/std/global_cardinality_low_up_closed.mzn0000644000175000017500000000130714536677021025507 0ustar kaolkaolinclude "global_cardinality_closed.mzn"; /** @group globals.deprecated Requires that for all \p i, the value \a cover[\p i] appears at least \a lbound[\p i] and at most \a ubound[\p i] times in the array \a x. The elements of \a x must take their values from \a cover. This constraint is deprecated. Use global_cardinality_closed(x, cover, lbound, ubound) instead. */ predicate global_cardinality_low_up_closed(array[$X] of var int: x, array[$Y] of int: cover, array[$Y] of int: lbound, array[$Y] of int: ubound) = global_cardinality_closed(x, cover, lbound, ubound); libminizinc-2.8.2/share/minizinc/std/fzn_circuit_opt_reif.mzn0000644000175000017500000000044414536677021023155 0ustar kaolkaolinclude "subcircuit.mzn"; predicate fzn_circuit_opt_reif(array[int] of var opt int: x, var bool: b) = b <-> ( subcircuit(array1d(index_set(x),[if occurs(x[i]) then deopt(x[i]) else i endif | i in index_set(x)])) /\ forall (i in index_set(x)) (occurs(x[i]) -> deopt(x[i]) != i)); libminizinc-2.8.2/share/minizinc/std/fzn_lex_less_float.mzn0000644000175000017500000000103414536677021022623 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than array 'y'. % Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_less_float(array[int] of var float: x, array[int] of var float: y) = lex_less_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/sliding_sum.mzn0000644000175000017500000000054314536677021021264 0ustar kaolkaolinclude "fzn_sliding_sum.mzn"; include "fzn_sliding_sum_reif.mzn"; /** @group globals.math Requires that in each subsequence \a vs[\p i], ..., \a vs[\p i + \a seq - 1] the sum of the values belongs to the interval [\a low, \a up]. */ predicate sliding_sum(int: low, int: up, int: seq, array[int] of var int: vs) = fzn_sliding_sum(low, up, seq, vs); libminizinc-2.8.2/share/minizinc/std/fzn_geost_smallest_bb.mzn0000644000175000017500000000234414536677021023315 0ustar kaolkaolpredicate fzn_geost_smallest_bb( int : k , array[int,int] of int : rect_size , array[int,int] of int : rect_offset , array[int ] of set of int : shape , array[int,int] of var int : x , array[int ] of var int : kind , array[int ] of var int : l , array[int ] of var int : u ) = % Two useful definitions let { set of int: DIMS = 1..k; set of int: OBJECTS = index_set(kind); } in ( % Posting the geost constraint fzn_geost_bb(k, rect_size, rect_offset, shape, x, kind, l, u) /\ % Posting the smallest bounding box constraints forall(j in DIMS)( % Lower boundary exists(o in OBJECTS, s in dom(kind[o]))( kind[o] = s /\ exists(r in shape[s])( x[o,j] + rect_offset[r,j] == l[j] ) ) /\ % Upper boundary exists(o in OBJECTS, s in dom(kind[o]))( kind[o] = s /\ exists(r in shape[s])( x[o,j] + rect_offset[r,j] + rect_size[r,j] == u[j] ) ) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_count_leq_reif.mzn0000644000175000017500000000060114536677021022615 0ustar kaolkaolinclude "count_fn.mzn"; predicate fzn_count_leq_reif(array[int] of var int: x, var int: y, var int: c, var bool: b) = let { var int: z = count(x,y) } in b <-> z >= c; % This needs to be written with a let rather than count(x,y) >= c % so that the automatic rewriting of the latter doesn't kick in %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/var_sqr_sym.mzn0000644000175000017500000000064714536677021021321 0ustar kaolkaolinclude "fzn_var_sqr_sym.mzn"; /** @group globals.lexicographic Requires that the square array \a x is lex least under the 7 symmetries: 3 rotations and 4 reflections */ predicate var_sqr_sym(array[$$X, $$X] of var $$Y: x) = let { int: n = card(index_set_1of2(x)); constraint assert(n = card(index_set_2of2(x)),"square symmetry applied to non-square array"); } in fzn_var_sqr_sym(array2d(1..n, 1..n, x)); libminizinc-2.8.2/share/minizinc/std/fzn_all_different_int_reif.mzn0000644000175000017500000000055614536677021024305 0ustar kaolkaol%-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all different. %-----------------------------------------------------------------------------% predicate fzn_all_different_int_reif(array[int] of var int: x, var bool: b) = b <-> forall(i,j in index_set(x) where i < j) ( x[i] != x[j] ); libminizinc-2.8.2/share/minizinc/std/fzn_network_flow_cost.mzn0000644000175000017500000000113414536677021023371 0ustar kaolkaolpredicate fzn_network_flow_cost(array[int,1..2] of int: arc, array[int] of int: balance, array[int] of int: weight, array[int] of var int: flow, var int: cost) = let { int: source_node = 1; int: sink_node = 2; set of int: ARCS = index_set_1of2(arc); set of int: NODES = index_set(balance); } in cost = sum(i in ARCS) (flow[i] * weight[i]) /\ forall (i in NODES) ( sum (j in ARCS where i == arc[j,source_node]) (flow[j]) - sum (j in ARCS where i == arc[j,sink_node]) (flow[j]) = balance[i] ); libminizinc-2.8.2/share/minizinc/std/fzn_wst_reif.mzn0000644000175000017500000000050314536677021021442 0ustar kaolkaolpredicate fzn_wst_reif(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, array[int] of var bool: es, var int: K, var bool: b) = abort("Reified wst constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_knapsack_reif.mzn0000644000175000017500000000053714536677021022427 0ustar kaolkaolpredicate fzn_knapsack_reif(array[int] of int: w, array[int] of int:p, array[int] of var int:x, var int: W, var int: P, var bool: b) = b <-> ( forall (i in index_set(x)) (x[i] >= 0) /\ W >= 0 /\ P >= 0 /\ P = sum(i in index_set(p)) (x[i]*p[i]) /\ W = sum(i in index_set(w)) (x[i]*w[i]) ); libminizinc-2.8.2/share/minizinc/std/fzn_increasing_bool.mzn0000644000175000017500000000062614536677021022763 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate fzn_increasing_bool(array[int] of var bool: x) = if length(x) > 1 then forall(i in index_set(x) diff { min(index_set(x)) }) (x[i-1] <= x[i]) endif; libminizinc-2.8.2/share/minizinc/std/fzn_lex_less_bool_reif.mzn0000644000175000017500000000112614536677021023460 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than array 'y'. % Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_less_bool_reif(array[int] of var bool: x, array[int] of var bool: y, var bool: c) = c <-> lex_less_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/seq_precede_chain.mzn0000644000175000017500000000113114536677021022362 0ustar kaolkaolinclude "fzn_seq_precede_chain_int.mzn"; include "fzn_seq_precede_chain_int_reif.mzn"; include "fzn_seq_precede_chain_set.mzn"; include "fzn_seq_precede_chain_set_reif.mzn"; /** @group globals.lexicographic Requires that \a i precedes \a i+1 in the array \a x for all positive \a i. */ predicate seq_precede_chain(array[int] of var int: x) = fzn_seq_precede_chain_int(x); /** @group globals.lexicographic Requires that \a i appears in a set in array \a x before \a i+1 for all positive \a i */ predicate seq_precede_chain(array[int] of var set of int: x) = fzn_seq_precede_chain_set(x); libminizinc-2.8.2/share/minizinc/std/regular_regexp.mzn0000644000175000017500000000242314536677021021761 0ustar kaolkaolinclude "fzn_regular_regexp.mzn"; include "regular.mzn"; /** @group globals.extensional The sequence of values in array \a x is accepted by the regular expression \a r. This constraint generates its DFA equivalent. Regular expressions can use the following syntax: - Selection: - Concatenation: "12 34", 12 followed by 34. (Characters are assumed to be the part of the same number unless split by syntax or whitespace.) - Union: "7|11", a 7 or 11. - Groups: "7(6|8)", a 7 followed by a 6 or an 8. - Wildcard: ".", any value within the domain. - Classes: "[3-6 7]", a 3,4,5,6, or 7. - Negated classes: "[^3 5]", any value within the domain except for a 3 or a 5. - Quantifiers: - Asterisk: "12*", 0 or more times a 12. - Question mark: "5?", 0 or 1 times a 5. (optional) - Plus sign: "42+", 1 or more time a 42. - Exact: "1{3}", exactly 3 times a 1. - At least: "9{5,}", 5 or more times a 9. - Between: "7{3,5}", at least 3 times, but at most 5 times a 7. Members of enumerated types can be used in place of any integer (e.g., "A B", A followed by B). Enumerated identifiers still use whitespace for concatenation. */ predicate regular(array[int] of var int: x, string: r) = fzn_regular(x, r); libminizinc-2.8.2/share/minizinc/std/decreasing_set.mzn.deprecated.mzn0000644000175000017500000000023014536677021024621 0ustar kaolkaolpredicate decreasing_set(array[$X] of var set of int: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_closed.mzn0000644000175000017500000000052514536677021025000 0ustar kaolkaolinclude "global_cardinality.mzn"; predicate fzn_global_cardinality_closed(array[int] of var int: x, array[int] of int: cover, array[int] of var int: counts) = forall(i in index_set(x))( x[i] in { d | d in cover } ) /\ global_cardinality(x, cover, counts); libminizinc-2.8.2/share/minizinc/std/fzn_value_precede_chain_int.mzn0000644000175000017500000000134314536677021024442 0ustar kaolkaolinclude "seq_precede_chain.mzn"; predicate fzn_value_precede_chain_int(array[int] of int: T, array[int] of var int: X) = if length(T) = 0 then true elseif min(index_set(T)) = 1 /\ forall (i in index_set(T))(T[i] = i) /\ max(T) = ub_array(X) then seq_precede_chain(X) else let { int: offset = min(index_set(T)) - 1; int: l = lb_array(X); int: u = ub_array(X); array[1.. u -l +1] of int : p = [sum([i - offset | i in index_set(T) where T[i] = j]) | j in l..u]; array [int] of var 0..length(T): Y = array1d(index_set(X),[p[X[i]-l+1] | i in index_set(X)]); } in seq_precede_chain(Y) endif; libminizinc-2.8.2/share/minizinc/std/flatzinc_builtins.mzn0000644000175000017500000006146714536677021022506 0ustar kaolkaol%-----------------------------------------------------------------------------% % % FlatZinc builtins % % This section contains declarations for the standard FlatZinc builtins. % They can be redefined by providing a custom redefinitions.mzn in the % solver globals library. % include "stdlib/stdlib_ann.mzn"; /*** @groupdef flatzinc FlatZinc builtins These are the standard constraints that need to be supported by FlatZinc solvers (or redefined in the redefinitions.mzn file). */ /*** @groupdef flatzinc.int Integer FlatZinc builtins */ /** @group flatzinc.int Constrains \a b to be the absolute value of \a a */ predicate int_abs(var int: a, var int: b); /** @group flatzinc.int Constrains \a a to be equal to \a b */ predicate int_eq(var int: a, var int: b) ::promise_commutative; /** @group flatzinc.int Constrains (\a a=\a b) \( \leftrightarrow \) \a r */ predicate int_eq_reif(var int: a, var int: b, var bool: r); /** @group flatzinc.int Constrains \a a to be less than or equal to \a b */ predicate int_le(var int: a, var int: b); /** @group flatzinc.int Constrains (\a a ≤ \a b) \( \leftrightarrow \) \a r */ predicate int_le_reif(var int: a, var int: b, var bool: r); /** @group flatzinc.int Constrains \( \a c = \sum_i \a as[i]*\a bs[i] \) */ predicate int_lin_eq(array[int] of int: as, array[int] of var int: bs, int: c); /** @group flatzinc.int Constrains \( \a r \leftrightarrow (\a c = \sum_i \a as[i]*\a bs[i]) \) */ predicate int_lin_eq_reif(array[int] of int: as, array[int] of var int: bs,int: c, var bool: r); /** @group flatzinc.int Constrains \( \a c \neq \sum_i \a as[i]*\a bs[i] \) */ predicate int_lin_ne(array[int] of int: as, array[int] of var int: bs, int: c); /** @group flatzinc.int Constrains \( \a r \leftrightarrow (\a c \neq \sum_i \a as[i]*\a bs[i]) \) */ predicate int_lin_ne_reif(array[int] of int: as, array[int] of var int: bs,int: c, var bool: r); /** @group flatzinc.int Constrains \( \sum \) \a as[\p i]*\a bs[\p i] ≤ \a c */ predicate int_lin_le(array[int] of int: as, array[int] of var int: bs, int: c); /** @group flatzinc.int Constrains \a r \( \leftrightarrow \) (\( \sum \) \a as[\p i]*\a bs[\p i] ≤ \a c) */ predicate int_lin_le_reif(array[int] of int: as, array[int] of var int: bs,int: c, var bool: r); /** @group flatzinc.int Constrains \a a ≠ \a b */ predicate int_ne(var int: a, var int: b) ::promise_commutative; /** @group flatzinc.int \a r \( \leftrightarrow \) (\a a ≠ \a b) */ predicate int_ne_reif(var int: a, var int: b, var bool: r); /** @group flatzinc.int Constrains \a a + \a b = \a c */ predicate int_plus(var int: a, var int: b, var int: c); /** @group flatzinc.int Constrains \a a / \a b = \a c */ predicate int_div(var int: a, var int: b, var int: c); /** @group flatzinc.int Constrains \a a < \a b */ predicate int_lt(var int: a, var int: b); /** @group flatzinc.int Constrains \a r \( \leftrightarrow \) (\a a < \a b) */ predicate int_lt_reif(var int: a, var int: b, var bool: r); /** @group flatzinc.int Constrains max(\a a, \a b) = \a c */ predicate int_max(var int: a, var int: b, var int: c); /** @group flatzinc.int Constrains min(\a a, \a b) = \a c */ predicate int_min(var int: a, var int: b, var int: c); /** @group flatzinc.int Constrains \a a % \a b = \a c */ predicate int_mod(var int: a, var int: b, var int: c); /** @group flatzinc.int Constrains \a a * \a b = \a c */ predicate int_times(var int: a, var int: b, var int: c); /** @group flatzinc.int Constrains \a z = \(\a x ^ {\a y}\), \a z is constrained to ``1 div pow(x, abs(y))`` when \(\a y < 0\) */ predicate int_pow(var int: x, var int: y, var int: z); /** @group flatzinc.int Constrains \a x \( \in \) \a S */ predicate set_in(var int: x, set of int: S); /*** @groupdef flatzinc.bool Bool FlatZinc builtins */ /** @group flatzinc.bool Constrains \( \a b \in \{0,1\} \) and \( \a a \leftrightarrow \a b=1 \) */ predicate bool2int(var bool: a, var int: b); /** @group flatzinc.bool Constrains \( \a r \leftrightarrow \a a \land \a b \) */ predicate bool_and(var bool: a, var bool: b, var bool: r); /** @group flatzinc.bool Constrains \( \bigvee_i \a as[i] \lor \bigvee_j \lnot \a bs[j] \) */ predicate bool_clause(array[int] of var bool: as ::promise_ctx_monotone, array[int] of var bool: bs ::promise_ctx_antitone); /** @group flatzinc.bool Constrains \a a = \a b */ predicate bool_eq(var bool: a, var bool: b) ::promise_commutative; /** @group flatzinc.bool Constrains \a r \( \leftrightarrow \) (\a a = \a b) */ predicate bool_eq_reif(var bool: a, var bool: b, var bool: r); /** @group flatzinc.bool Constrains \a a ≤ \a b */ predicate bool_le(var bool: a ::promise_ctx_antitone, var bool: b ::promise_ctx_monotone); /** @group flatzinc.bool Constrains \a r \( \leftrightarrow \) (\a a ≤ \a b) */ predicate bool_le_reif(var bool: a, var bool: b, var bool: r); /** @group flatzinc.bool Constrains \( \a c = \sum_i \a as[i]*\a bs[i] \) */ predicate bool_lin_eq(array[int] of int: as, array[int] of var bool: bs, var int: c); /** @group flatzinc.bool Constrains \( \sum_i \a as[i]*\a bs[i] \leq \a c \) */ predicate bool_lin_le(array[int] of int: as, array[int] of var bool: bs, int: c); /** @group flatzinc.bool Constrains \a a < \a b */ predicate bool_lt(var bool: a ::promise_ctx_antitone, var bool: b ::promise_ctx_monotone); /** @group flatzinc.bool Constrains \a r \( \leftrightarrow \) (\a a < \a b) */ predicate bool_lt_reif(var bool: a, var bool: b, var bool: r); /** @group flatzinc.bool Constrains \a a ≠ \a b */ predicate bool_not(var bool: a, var bool: b); /** @group flatzinc.bool Constrains \( \a r \leftrightarrow \a a \lor \a b \) */ predicate bool_or(var bool: a, var bool: b, var bool: r); /** @group flatzinc.bool Constrains \( \a r \leftrightarrow \a a \oplus \a b \) */ predicate bool_xor(var bool: a, var bool: b, var bool: r); /** @group flatzinc.bool Constrains \a a \( \oplus \) \a b */ predicate bool_xor(var bool: a, var bool: b) ::promise_commutative; /*** @groupdef flatzinc.set Set FlatZinc builtins */ /** @group flatzinc.set Constrains \a x \( \in \) \a S */ predicate set_in(var int: x, var set of int: S); /** @group flatzinc.set Constrains \a x = |\a S| */ predicate set_card(var set of int: S, var int: x); /** @group flatzinc.set Constrains \( \a r \leftrightarrow (\a x \in \a S) \) */ predicate set_in_reif(var int: x, set of int: S, var bool: r); /** @group flatzinc.set Constrains \( \a r \leftrightarrow (\a x \in \a S) \) */ predicate set_in_reif(var int: x, var set of int: S, var bool: r); /** @group flatzinc.set Constrains \a x \( \subseteq \) \a y */ predicate set_subset(var set of int: x, var set of int: y); /** @group flatzinc.set Constrains \a x \( \supseteq \) \a y */ predicate set_superset(var set of int: x, var set of int: y); /** @group flatzinc.set Constrains \( \a r \leftrightarrow (\a x \subseteq \a y) \) */ predicate set_subset_reif(var set of int: x, var set of int: y, var bool: r); /** @group flatzinc.set Constrains \( \a r \leftrightarrow (\a x \subseteq \a y) \) */ predicate set_superset_reif(var set of int: x, var set of int: y, var bool: r); /** @group flatzinc.set Constrains \a x ≤ \a y (lexicographic order of the sorted lists of elements) */ predicate set_le(var set of int: x, var set of int: y); /** @group flatzinc.set Constrains \( \a r \leftrightarrow (\a x \leq \a y) \) (lexicographic order of the sorted lists of elements) */ predicate set_le_reif(var set of int: x, var set of int: y, var bool: r); /** @group flatzinc.set Constrains \a x < \a y (lexicographic order of the sorted lists of elements) */ predicate set_lt(var set of int: x, var set of int: y); /** @group flatzinc.set Constrains \( \a r \leftrightarrow (\a x < \a y) \) (lexicographic order of the sorted lists of elements) */ predicate set_lt_reif(var set of int: x, var set of int: y, var bool: r); /** @group flatzinc.set Constrains \a x = \a y */ predicate set_eq(var set of int: x, var set of int: y) ::promise_commutative; /** @group flatzinc.set Constrains \a r \( \leftrightarrow \) (\a x = \a y) */ predicate set_eq_reif(var set of int: x, var set of int: y, var bool: r); /** @group flatzinc.set Constrains \a x ≠ \a y */ predicate set_ne(var set of int: x, var set of int: y) ::promise_commutative; /** @group flatzinc.set Constrains \a r \( \leftrightarrow \) (\a x ≠ \a y) */ predicate set_ne_reif(var set of int: x, var set of int: y, var bool: r); /** @group flatzinc.set Constrains \a r = \a x \( \cap \) \a y */ predicate set_intersect(var set of int: x, var set of int: y, var set of int: r); /** @group flatzinc.set Constrains \a r = \a x \( \cup \) \a y */ predicate set_union(var set of int: x, var set of int: y, var set of int: r); /** @group flatzinc.set Constrains \a r = \a x \( \setminus \) \a y */ predicate set_diff(var set of int: x, var set of int: y, var set of int: r); /** @group flatzinc.set Constrains \a r to be the symmetric difference of \a x and \a y */ predicate set_symdiff(var set of int: x, var set of int: y, var set of int: r); /*** @groupdef flatzinc.float Float FlatZinc builtins */ /** @group flatzinc.float Constrains \a b to be the absolute value of \a a */ predicate float_abs(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = acos(\a a) */ predicate float_acos(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = acosh(\a a) */ predicate float_acosh(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = asin(\a a) */ predicate float_asin(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = asinh(\a a) */ predicate float_asinh(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = atan(\a a) */ predicate float_atan(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = atanh(\a a) */ predicate float_atanh(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = cos(\a a) */ predicate float_cos(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = cosh(\a a) */ predicate float_cosh(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = exp(\a a) */ predicate float_exp(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = ln(\a a) */ predicate float_ln(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = log10(\a a) */ predicate float_log10(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = log2(\a a) */ predicate float_log2(var float: a, var float: b); /** @group flatzinc.float Constrains \(\a b = \sqrt{\a a}\) */ predicate float_sqrt(var float: a, var float: b); /** @group flatzinc.float Constrains \a z = \(\a x ^ {\a y}\) */ predicate float_pow(var float: x, var float: y, var float: z); /** @group flatzinc.float Constrains \a b = sin(\a a) */ predicate float_sin(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = sinh(\a a) */ predicate float_sinh(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = tan(\a a) */ predicate float_tan(var float: a, var float: b); /** @group flatzinc.float Constrains \a b = tanh(\a a) */ predicate float_tanh(var float: a, var float: b); /** @group flatzinc.float Constrains \a a = \a b */ predicate float_eq(var float: a, var float: b) ::promise_commutative; /** @group flatzinc.float Constrains \a r \( \leftrightarrow \) (\a a = \a b) */ predicate float_eq_reif(var float: a, var float: b, var bool: r); /** @group flatzinc.float Constrains \a a ≤ \a b */ predicate float_le(var float: a, var float: b); /** @group flatzinc.float Constrains \a r \( \leftrightarrow \) (\a a ≤ \a b) */ predicate float_le_reif(var float: a, var float: b, var bool: r); /** @group flatzinc.float Constrains \a a < \a b */ predicate float_lt(var float: a, var float: b); /** @group flatzinc.float Constrains \a r \( \leftrightarrow \) (\a a < \a b) */ predicate float_lt_reif(var float: a, var float: b, var bool: r); /** @group flatzinc.float Constrains \a a ≠ \a b */ predicate float_ne(var float: a, var float: b) ::promise_commutative; /** @group flatzinc.float Constrains \a r \( \leftrightarrow \) (\a a ≠ \a b) */ predicate float_ne_reif(var float: a, var float: b, var bool: r); /** @group flatzinc.float Constrains \( \a a \in\ [ \a b, \a c ] \) */ predicate float_in(var float: a, float: b, float: c); /** @group flatzinc.float Constrains \a r \( \leftrightarrow \) \( \a a \in\ [ \a b, \a c ] \) */ predicate float_in_reif(var float: a, float: b, float: c, var bool: r); /** @group flatzinc.float Constrains the domain of \a x using the values in \a as, using each pair of values \a as[2*\p i-1]..\a as[2*\p i] for \p i in 1..\p n/2 as a possible range */ predicate float_dom(var float: x, array[int] of float: as); /** @group flatzinc.float Constrains \( \a c = \sum_i \a as[i]*\a bs[i] \) */ predicate float_lin_eq(array[int] of float: as, array[int] of var float: bs, float: c); /** @group flatzinc.float Constrains \( \a r \leftrightarrow (\a c = \sum_i \a as[i]*\a bs[i]) \) */ predicate float_lin_eq_reif(array[int] of float: as, array[int] of var float: bs, float: c, var bool: r); /** @group flatzinc.float Constrains \( \sum_i \a as[i]*\a bs[i] \leq \a c \) */ predicate float_lin_le(array[int] of float: as, array[int] of var float: bs, float: c); /** @group flatzinc.float Constrains \( \a r \leftrightarrow (\sum_i \a as[i]*\a bs[i] \leq \a c) \) */ predicate float_lin_le_reif(array[int] of float: as, array[int] of var float: bs, float: c, var bool: r); /** @group flatzinc.float Constrains \( \sum_i \a as[i]*\a bs[i] < \a c \) */ predicate float_lin_lt(array[int] of float: as, array[int] of var float: bs, float: c); /** @group flatzinc.float Constrains \( \a r \leftrightarrow (\sum_i \a as[i]*\a bs[i] < \a c) \) */ predicate float_lin_lt_reif(array[int] of float: as, array[int] of var float: bs, float: c, var bool: r); /** @group flatzinc.float Constrains \( \a c \neq \sum_i \a as[i]*\a bs[i] \) */ predicate float_lin_ne(array[int] of float: as, array[int] of var float: bs, float: c); /** @group flatzinc.float Constrains \( \a r \leftrightarrow (\a c \neq \sum_i \a as[i]*\a bs[i]) \) */ predicate float_lin_ne_reif(array[int] of float: as, array[int] of var float: bs, float: c, var bool: r); /** @group flatzinc.float Constrains max(\a a, \a b) = \a c */ predicate float_max(var float: a, var float: b, var float: c); /** @group flatzinc.float Constrains min(\a a, \a b) = \a c */ predicate float_min(var float: a, var float: b, var float: c); /** @group flatzinc.float Constrains \a a + \a b = \a c */ predicate float_plus(var float: a, var float: b, var float: c); /** @group flatzinc.float Constrains \a a / \a b = \a c */ predicate float_div(var float: a, var float: b, var float: c); /** @group flatzinc.float Constrains \a a * \a b = \a c */ predicate float_times(var float: a, var float: b, var float: c); /** @group flatzinc.float Constrains \a y=\a x */ predicate int2float(var int: x, var float: y); /** @group flatzinc.float Constrains \( \a y = \lceil{ \a x} \rceil \) */ predicate float_ceil(var float: x, var int: y); /** @group flatzinc.float Constrains \( \a y = \lfloor{ \a x} \rfloor \) */ predicate float_floor(var float: x, var int: y); /** @group flatzinc.float Constrains that \a y is the nearest integer to \a x */ predicate float_round(var float: x, var int: y); % Array constraints /** @group flatzinc.bool Constrains \( \a r \leftrightarrow \bigwedge_i \a as[i]\) */ predicate array_bool_and(array[int] of var bool: as, var bool: r); /** @group flatzinc.bool Constrains \( \oplus_i\ \a as[i]\) */ predicate array_bool_xor(array[int] of var bool: as); /** @group flatzinc.bool Constrains \a as[\a b] = \a c */ predicate array_bool_element(var int: b, array[int] of bool: as, var bool: c); /** @group flatzinc.int Constrains \a as[\a b] = \a c */ predicate array_int_element(var int: b, array[int] of int: as, var int: c); /** @group flatzinc.float Constrains \a as[\a b] = \a c */ predicate array_float_element(var int: b, array[int] of float: as, var float: c); /** @group flatzinc.set Constrains \a as[\a b] = \a c */ predicate array_set_element(var int: b, array[int] of set of int: as, var set of int: c); /** @group flatzinc.bool Constrains \a as[\a b] = \a c */ predicate array_var_bool_element(var int: b, array[int] of var bool: as, var bool: c); /** @group flatzinc.int Constrains \a as[\a b] = \a c */ predicate array_var_int_element(var int: b, array[int] of var int: as, var int: c); /** @group flatzinc.float Constrains \a as[\a b] = \a c */ predicate array_var_float_element(var int: b, array[int] of var float: as, var float: c); /** @group flatzinc.set Constrains \a as[\a b] = \a c */ predicate array_var_set_element(var int: b, array[int] of var set of int: as, var set of int: c); /** @group flatzinc.int Constrains \a m to be the maximum value of the (non-empty) array \a x */ predicate array_int_maximum(var int: m, array[int] of var int: x); /** @group flatzinc.float Constrains \a m to be the maximum value of the (non-empty) array \a x */ predicate array_float_maximum(var int: m, array[int] of var int: x); /** @group flatzinc.int Constrains \a m to be the minimum value of the (non-empty) array \a x */ predicate array_int_minimum(var int: m, array[int] of var int: x); /** @group flatzinc.float Constrains \a m to be the minimum value of the (non-empty) array \a x */ predicate array_float_minimum(var int: m, array[int] of var int: x); /*** @groupdef flatzinc.two FlatZinc builtins added in MiniZinc 2.0.0. These functions and predicates define built-in operations of the MiniZinc language that have been added in MiniZinc 2.0.0. Solvers that support these natively need to include a file called redefinitions-2.0.mzn in their solver library that redefines these predicates as builtins. */ /** @group flatzinc.two Reified clause constraint. Constrains \( \a b \leftrightarrow \bigvee_i \a as[i] \lor \bigvee_j \lnot \a bs[j] \) */ predicate bool_clause_reif(array[int] of var bool: as, array[int] of var bool: bs, var bool: b); /** @group flatzinc.two Constrains \a m to be the maximum value in array \a x. */ predicate array_int_maximum(var int: m, array[int] of var int: x); /** @group flatzinc.two Constrains \a m to be the maximum value in array \a x. */ predicate array_float_maximum(var float: m, array[int] of var float: x); /** @group flatzinc.two Constrains \a m to be the minimum value in array \a x. */ predicate array_int_minimum(var int: m, array[int] of var int: x); /** @group flatzinc.two Constrains \a m to be the minimum value in array \a x. */ predicate array_float_minimum(var float: m, array[int] of var float: x); /*** @groupdef flatzinc.twootwo FlatZinc builtins added in MiniZinc 2.0.2. These functions and predicates define built-in operations of the MiniZinc language that have been added in MiniZinc 2.0.2. Solvers that support these natively need to include a file called redefinitions-2.0.2.mzn in their solver library that redefines these predicates as builtins. */ /** @group flatzinc.twootwo Element constraint on array with MiniZinc index set, constrains \a x[\a idx] = \a c This can be overridden in a solver that can perform the index calculation more efficiently than using a MiniZinc decomposition. */ predicate array_var_bool_element_nonshifted(var int: idx, array[int] of var bool: x, var bool: c); /** @group flatzinc.twootwo Element constraint on array with MiniZinc index set, constrains \a x[\a idx] = \a c This can be overridden in a solver that can perform the index calculation more efficiently than using a MiniZinc decomposition. */ predicate array_var_int_element_nonshifted(var int: idx, array[int] of var int: x, var int: c); /** @group flatzinc.twootwo Element constraint on array with MiniZinc index set, constrains \a x[\a idx] = \a c This can be overridden in a solver that can perform the index calculation more efficiently than using a MiniZinc decomposition. */ predicate array_var_float_element_nonshifted(var int: idx, array[int] of var float: x, var float: c); /** @group flatzinc.twootwo Element constraint on array with MiniZinc index set, constrains \a x[\a idx] = \a c This can be overridden in a solver that can perform the index calculation more efficiently than using a MiniZinc decomposition. */ predicate array_var_set_element_nonshifted(var int: idx, array[int] of var set of int: x, var set of int: c); /*** @groupdef flatzinc.twoone FlatZinc builtins added in MiniZinc 2.1.0. These functions and predicates define built-in operations of the MiniZinc language that have been added in MiniZinc 2.1.0. Solvers that support these natively need to include a file called redefinitions-2.1.0.mzn in their solver library that redefines these predicates as builtins. */ /** @group flatzinc.twoone Constrains \a a ≤ \a x ≤ \a b */ predicate float_in(var float: x, float: a, float: b); /** @group flatzinc.twoone Constrains \a x to take one of the values in \a as */ predicate float_dom(var float: x, array[int] of float: as); /*** @groupdef flatzinc.twooneone FlatZinc builtins added in MiniZinc 2.1.1. These functions and predicates define built-in operations of the MiniZinc language that have been added in MiniZinc 2.1.1. Solvers that support these natively need to include a file called redefinitions-2.1.1.mzn in their solver library that redefines these predicates as builtins. */ /** @group flatzinc.twooneone Returns variable constrained to be equal to the minimum of the set \a s. An alternative implementation can be found in the comments of the source code. */ function var $$E: min(var set of $$E: s); /** @group flatzinc.twooneone Returns variable constrained to be equal to the maximum of the set \a s. An alternative implementation can be found in the comments of the source code. */ function var $$E: max(var set of $$E: s); /*** @groupdef flatzinc.twotwoone FlatZinc builtins added in MiniZinc 2.2.1. These functions and predicates define built-in operations of the MiniZinc language that have been added in MiniZinc 2.2.1. Solvers that support these natively need to include a file called redefinitions-2.2.1.mzn in their solver library that redefines these predicates as builtins. */ /** @group flatzinc.twotwoone Constrains \a z = \(\a x ^ {\a y}\), \a z is constrained to ``1 div pow(x, abs(y))`` when \(\a y < 0\) **/ predicate int_pow_fixed(var int: x, int: y, var int: z); /*** @groupdef flatzinc.twothreethree FlatZinc builtins added in MiniZinc 2.3.3. These functions and predicates define built-in operations of the MiniZinc language that have been added in MiniZinc 2.3.3. Solvers that support these natively need to include a file called redefinitions-2.3.3.mzn in their solver library that redefines these predicates as builtins. */ /** @group flatzinc.twothreethree Constrains \a x \( \in \) \a S */ predicate float_set_in(var float: x, set of float: S); /*** @groupdef flatzinc.twofivetwo FlatZinc builtins added in MiniZinc 2.5.2. These functions and predicates define built-in operations of the MiniZinc language that have been added in MiniZinc 2.5.2. Solvers that support these natively need to include a file called redefinitions-2.5.2.mzn in their solver library that redefines these predicates as builtins. */ /** @group flatzinc.twofivetwo Element constraint on 2d array with MiniZinc index set, constrains \a x[\a idx1,\a idx2] = \a c This can be overridden in a solver that can perform the index calculation more efficiently than using a MiniZinc decomposition. */ predicate array_var_int_element2d_nonshifted(var int: idx1, var int: idx2, array[int,int] of var int: x, var int: c); /** @group flatzinc.twofivetwo Element constraint on 2d array with MiniZinc index set, constrains \a x[\a idx1,\a idx2] = \a c This can be overridden in a solver that can perform the index calculation more efficiently than using a MiniZinc decomposition. */ predicate array_var_bool_element2d_nonshifted(var int: idx1, var int: idx2, array[int,int] of var bool: x, var bool: c); /** @group flatzinc.twofivetwo Element constraint on 2d array with MiniZinc index set, constrains \a x[\a idx1,\a idx2] = \a c This can be overridden in a solver that can perform the index calculation more efficiently than using a MiniZinc decomposition. */ predicate array_var_float_element2d_nonshifted(var int: idx1, var int: idx2, array[int,int] of var float: x, var float: c); /** @group flatzinc.twofivetwo Element constraint on 2d array with MiniZinc index set, constrains \a x[\a idx1,\a idx2] = \a c This can be overridden in a solver that can perform the index calculation more efficiently than using a MiniZinc decomposition. */ predicate array_var_set_element2d_nonshifted(var int: idx1, var int: idx2, array[int,int] of var set of int: x, var set of int: c); /*** @groupdef flatzinc.deprecated Deprecated FlatZinc builtins These builtin constraints are no longer produced by the MiniZinc compiler, and they will be removed in future versions of MiniZinc. */ /** @group flatzinc.deprecated Constrains \( \a r \leftrightarrow \bigvee_i \a as[i]\) */ predicate array_bool_or(array[int] of var bool: as, var bool: r)::mzn_deprecated("2.7.0","https://www.minizinc.org/doc-2.7.0/en/lib-flatzinc-deprecated.html"); libminizinc-2.8.2/share/minizinc/std/fzn_reachable_enum.mzn0000644000175000017500000000132314536677021022553 0ustar kaolkaolinclude "subgraph.mzn"; predicate fzn_reachable(array[int] of $$N: from, array[int] of $$N: to, var $$N: r, array[$$N] of var bool: ns, array[int] of var bool: es) = let { int: E = length(es); set of int: NODE = index_set(ns); array[1..2*E] of NODE: dfrom = from ++ to; array[1..2*E] of NODE: dto = to ++ from; array[1..2*E] of var bool: des = es ++ es; array[NODE] of var bool: dns = array1d(NODE,ns); var NODE: dr = r; } in /* duplicate the edges so that we can use directed graph reachability */ fzn_dreachable(dfrom,dto,dr,dns,des); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/nvalue_fn.mzn0000644000175000017500000000115714536677021020726 0ustar kaolkaolinclude "nvalue.mzn"; /** @group globals.alldifferent Returns the number of distinct values in \a x. */ function var int: nvalue(array[$X] of var int: x) :: promise_total = let { var bool2int(length(x) > 0)..min(length(x),card(dom_array(x))): n::is_defined_var; constraint nvalue(n,x)::defines_var(n); } in n; /** @group globals.alldifferent Returns the number of distinct values in \a x. */ function var int: nvalue(array[$X] of var opt int: x) = let { any: xdom = dom_array(x); int: def = if 0 in xdom then min(xdom) - 1 else 0 endif; } in nvalue([x_i default def | x_i in x] ++ [def]) - 1; libminizinc-2.8.2/share/minizinc/std/fzn_path_int_reif.mzn0000644000175000017500000000063714536677021022443 0ustar kaolkaolinclude "tree.mzn"; include "subgraph.mzn"; predicate fzn_path_reif(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: s, var int: t, array[int] of var bool: ns, array[int] of var bool: es, var bool: b) = abort("Reified path constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/all_different_except_0.mzn0000644000175000017500000000074314536677021023336 0ustar kaolkaolinclude "fzn_alldifferent_except_0.mzn"; include "fzn_alldifferent_except_0_reif.mzn"; /** @group globals.alldifferent Constrain the elements of the array of integers \a vs to be pairwise different except for those elements that are assigned the value 0. */ predicate all_different_except_0(array[$X] of var int: vs) = fzn_alldifferent_except_0(array1d(vs)); % Synonym for the above. predicate alldifferent_except_0(array[$X] of var int: vs) = all_different_except_0(vs); libminizinc-2.8.2/share/minizinc/std/fzn_member_float.mzn0000644000175000017500000000051114536677021022253 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array or set 'x'. %-----------------------------------------------------------------------------% predicate fzn_member_float(array[int] of var float: x, var float: y) = exists(i in index_set(x)) ( x[i] == y ); libminizinc-2.8.2/share/minizinc/std/fzn_lex_chain_less_bool.mzn0000644000175000017500000000041114536677021023611 0ustar kaolkaolinclude "lex_less.mzn"; predicate fzn_lex_chain_less_bool(array[int, int] of var bool: a) = let { set of int: is2 = index_set_2of2(a); } in ( forall(j in is2 where j+1 in is2) ( lex_less(col(a, j), col(a, j+1)) ) ); libminizinc-2.8.2/share/minizinc/std/element_int.mzn.deprecated.mzn0000644000175000017500000000024714536677021024155 0ustar kaolkaolpredicate element_int(var $$E: i, array[$$E] of var $$T: x, var $$T: y) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_regular_nfa_set.mzn0000644000175000017500000000153714536677021022770 0ustar kaolkaolpredicate fzn_regular_nfa(array[int] of var int: x, int: Q, set of int: S, array[int,int] of set of int: d, int: q0, set of int: F) = if length(x) = 0 then q0 in F else let { % If x has index set m..n-1, then a[m] holds the initial state % (q0), and a[i+1] holds the state we're in after processing % x[i]. If a[n] is in F, then we succeed (ie. accept the string). int: m = min(index_set(x)), int: n = max(index_set(x)) + 1, array[m..n] of var 1..Q: a } in a[m] = q0 /\ % Set a[0]. forall(i in index_set(x)) ( x[i] in S /\ % Do this in case it's a var. a[i+1] in d[a[i], x[i]] % Determine a[i+1]. ) /\ a[n] in F % Check the final state is in F. endif;libminizinc-2.8.2/share/minizinc/std/fzn_value_precede_set.mzn0000644000175000017500000000115214536677021023277 0ustar kaolkaolpredicate fzn_value_precede_set(int: s, int: t, array[int] of var set of int: x) = if length(x) = 0 then true else let { int: imin = min(index_set(x)), int: imax = max(index_set(x)), array[imin..imax + 1] of var bool: b } in ( forall (i in imin..imax) ( let { var bool: xis = (s in x[i] /\ not (t in x[i])) } in (xis -> (b[i + 1] == true)) /\ ((not xis) -> (b[i] == b[i + 1])) /\ ((not b[i]) -> (s in x[i] \/ not (t in x[i]))) ) /\ b[imin] == false ) endif;libminizinc-2.8.2/share/minizinc/std/value_precede.mzn0000644000175000017500000000227414536677021021555 0ustar kaolkaolinclude "fzn_value_precede_int.mzn"; include "fzn_value_precede_int_reif.mzn"; include "fzn_value_precede_int_opt.mzn"; include "fzn_value_precede_set.mzn"; include "fzn_value_precede_set_reif.mzn"; /** @group globals.lexicographic Requires that \a s precede \a t in the array \a x. Precedence means that if any element of \a x is equal to \a t, then another element of \a x with a lower index is equal to \a s. */ predicate value_precede($$E: s, $$E: t, array[int] of var $$E: x) = fzn_value_precede_int(s, t, x); /** @group globals.lexicographic Requires that \a s precede \a t in the array \a x. Precedence means that if any element of \a x is equal to \a t, then another element of \a x with a lower index is equal to \a s. */ predicate value_precede($$E: s, $$E: t, array[int] of var opt $$E: x) = fzn_value_precede_int_opt(s, t, x); /** @group globals.lexicographic Requires that \a s precede \a t in the array \a x. Precedence means that if an element of \a x contains \a t but not \a s, then another element of \a x with lower index contains \a s but not \a t. */ predicate value_precede($$E: s, $$E: t, array[int] of var set of $$E: x) = fzn_value_precede_set(s, t, x); libminizinc-2.8.2/share/minizinc/std/fzn_count_neq_par_reif.mzn0000644000175000017500000000035514536677021023467 0ustar kaolkaolinclude "fzn_count_neq_reif.mzn"; predicate fzn_count_neq_par_reif(array[int] of var int: x, int: y, int: c, var bool: b) = fzn_count_neq_reif(x,y,c,b); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_at_most1.mzn0000644000175000017500000000022414536677021021347 0ustar kaolkaolpredicate fzn_at_most1(array[int] of var set of int: s) = forall(i,j in index_set(s) where i < j) ( card(s[i] intersect s[j]) <= 1 ); libminizinc-2.8.2/share/minizinc/std/fzn_partition_set_reif.mzn0000644000175000017500000000043414536677021023514 0ustar kaolkaolinclude "all_disjoint.mzn"; predicate fzn_partition_set_reif(array[int] of var set of int: S, set of int: universe, var bool: b) = b <-> ( all_disjoint(S) /\ universe == array_union(i in index_set(S)) ( S[i] ) ); libminizinc-2.8.2/share/minizinc/std/fzn_lex_less_int_reif.mzn0000644000175000017500000000112114536677021023312 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than array 'y'. % Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_less_int_reif(array[int] of var int: x, array[int] of var int: y, var bool: c) = c <-> lex_less_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/lex_less_set.mzn0000644000175000017500000000136414536677021021442 0ustar kaolkaolinclude "lex_less.mzn"; include "fzn_lex_less_set.mzn"; include "fzn_lex_less_set_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than array 'y'. % Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate lex_less_set(array[int] of var set of int: x, array[int] of var set of int: y) = fzn_lex_less_set(x, y); predicate lex_lt_set(array[int] of var set of int: x, array[int] of var set of int: y) = lex_less(x, y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_increasing_bool_opt.mzn0000644000175000017500000000055514536677021023646 0ustar kaolkaolinclude "increasing.mzn"; predicate fzn_increasing_bool(array[int] of var opt bool: x) = let { array [index_set(x)] of var bool: xx; constraint xx[min(index_set(x))] = x[min(index_set(x))] default lb_array(x); constraint forall (i in min(index_set(x)) + 1 .. max(index_set(x))) (xx[i] = x[i] default xx[i - 1]); } in increasing(xx);libminizinc-2.8.2/share/minizinc/std/fzn_lex_chain_lesseq_orbitope.mzn0000644000175000017500000000110114536677021025024 0ustar kaolkaolinclude "lex_lesseq.mzn"; predicate fzn_lex_chain_lesseq_orbitope( array[int, int] of var int: a, int: kind) = let { set of int: is2 = index_set_2of2(a); } in ( forall(j in is2 where j+1 in is2) ( lex_lesseq(col(a, j), col(a, j+1)) ) /\ if 1==kind then forall(i in index_set_1of2(a))( 1 == sum(row(a, i)) ) elseif 2==kind then forall(i in index_set_1of2(a))( 1 >= sum(row(a, i)) ) else true endif ); libminizinc-2.8.2/share/minizinc/std/arg_max_bool.mzn0000644000175000017500000000020214536677021021370 0ustar kaolkaolinclude "fzn_arg_max_bool.mzn"; predicate maximum_arg_bool(array[$$E] of var bool: x, var $$E: i) = fzn_maximum_arg_bool(x, i); libminizinc-2.8.2/share/minizinc/std/fzn_dtree_int_reif.mzn0000644000175000017500000000051414536677021022604 0ustar kaolkaolpredicate fzn_dtree_reif(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: r, array[int] of var bool: ns, array[int] of var bool: es, var bool: b) = abort("Reified dtree constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/nosets.mzn0000644000175000017500000003744714536677021020277 0ustar kaolkaol%%% Inclusion of this file eliminates set variables by converting them into arrays of var bool. % AUTHORS % Guido Tack % Gleb Belov % predicate mzn_reverse_map_var(var set of int: x) = let { array[int] of var bool: b = set2bools(x) } in true; function var set of int: reverse_map_ab2si(array[int] of var bool: b) ::output_only; function set of int: reverse_map_ab2si(array[int] of bool: b) ::promise_total = { i | i in index_set(b) where b[i] }; array[int] of var bool: set2bools(var set of int: x) ::promise_total = if is_fixed(x) then set2bools(fix(x)) elseif ub(x) = {} then [] else let { array[int] of var bool: b = array1d( min(ub(x))..max(ub(x)), [ set2bools_bit( x, i ) | i in min(ub(x))..max(ub(x)) ] ); constraint (x = reverse_map_ab2si(b)) :: is_reverse_map; } in b endif; array[int] of var bool: set2bools(var set of int: x, set of int: ubx) ::promise_total = if is_fixed(x) then set2bools(fix(x), ubx) elseif ub(x) = {} then [] else let { array[int] of var bool: b0 = set2bools( x ); %% Call in any case ?? TODO array[int] of var bool: b = array1d( min(ubx)..max(ubx), [ if i in ubx then set2bools_bit( x, i ) else false endif | i in min(ubx)..max(ubx) ] ); } in b endif; array[int] of bool: set2bools(set of int: x) ::promise_total = if x = {} then [] else array1d(min(x)..max(x),[i in x | i in min(x)..max(x)]) endif; array[int] of bool: set2bools(set of int: x, set of int: ubx) ::promise_total = if ubx = {} then [] else array1d(min(ubx)..max(ubx),[i in x | i in min(ubx)..max(ubx)]) endif; function var bool: set2bools_bit( var set of int: x, int: i ) ::promise_total = if i in ub(x) then let { var bool: bi; } in bi else false endif; predicate set_eq(var set of int: x, var set of int: y) ::promise_total = if not has_ub_set(x) /\ not has_ub_set(y) then assert(false, "set_eq: cannot determine bounds of set variables") elseif not has_ub_set(x) then set_eq(y,x) else let { constraint y subset x, %% Constrain domains first constraint x subset y, } in let { array[int] of var bool: bx = set2bools(x); array[int] of var bool: by = set2bools(y); } in forall (i in index_set(bx) union index_set(by)) ( if not (i in index_set(bx)) then not by[i] %% Should be impossible elseif not (i in index_set(by)) then not bx[i] else bx[i]=by[i] endif ) endif; predicate set_eq_reif(var set of int: x, var set of int: y, var bool: b) ::promise_total = if is_fixed(b) then if true==fix(b) then x==y else x!=y endif else let { array[int] of var bool: bx = set2bools(x); array[int] of var bool: by = set2bools(y); } in b <-> forall (i in index_set(bx) union index_set(by)) ( if not (i in index_set(bx)) then not by[i] elseif not (i in index_set(by)) then not bx[i] else bx[i]=by[i] endif ) endif; predicate set_eq_imp(var set of int: x, var set of int: y, var bool: b) = if is_fixed(b) then if fix(b) then (x = y) else true endif else let { array[int] of var bool: bx = set2bools(x); array[int] of var bool: by = set2bools(y); } in b -> forall (i in index_set(bx) union index_set(by)) ( if not (i in index_set(bx)) then not by[i] elseif not (i in index_set(by)) then not bx[i] else bx[i]=by[i] endif ) endif; predicate set_ne(var set of int: x, var set of int: y) ::promise_total = let { array[int] of var bool: bx = set2bools(x); array[int] of var bool: by = set2bools(y); } in exists (i in index_set(bx) union index_set(by)) ( if not (i in index_set(bx)) then by[i] elseif not (i in index_set(by)) then bx[i] else bx[i]!=by[i] endif ); predicate set_ne_reif(var set of int: x, var set of int: y, var bool: b) ::promise_total = set_eq_reif( x, y, not b ); predicate set_ne_imp(var set of int: x, var set of int: y, var bool: b) = if is_fixed(b) then if fix(b) then (x != y) else true endif else let { array[int] of var bool: bx = set2bools(x); array[int] of var bool: by = set2bools(y); } in b -> exists (i in index_set(bx) union index_set(by)) ( if not (i in index_set(bx)) then by[i] elseif not (i in index_set(by)) then bx[i] else (bx[i] != by[i]) endif ) endif; % Set comparisons are often used just to avoid symmetries. predicate set_le(var set of int: x, var set of int: y) = if ub(x) = {} then true elseif ub(y) = {} then x = {} else let { set of int: U = ub(x) union ub(y); int: l = min(U); int: u = max(U); array[l..u] of var bool: xb = array1d(l..u, [i in x | i in l..u]); var l-1..u: xmax = max(x union {l-1}); array[l..u] of var bool: yb = array1d(l..u, [i in y | i in l..u]); var l-1..u: ymax = max(y union {l-1}); array[l..u] of var bool: b; constraint forall(i in l..u-1) ( b[i] = let {var 1..4: cmp = 2*xb[i] + yb[i] + 1} in [b[i+1], xmax < i, ymax > i, b[i+1]][cmp] ); constraint b[u] = (xb[u] -> yb[u]); } in b[l] endif; predicate set_le_reif(var set of int: x, var set of int: y, var bool: r) = if ub(x) = {} then true elseif ub(y) = {} then set_eq_reif(x, {}, r) else let { set of int: U = ub(x) union ub(y); int: l = min(U); int: u = max(U); array[l..u] of var bool: xb = array1d(l..u, [i in x | i in l..u]); var l-1..u: xmax = max(x union {l-1}); array[l..u] of var bool: yb = array1d(l..u, [i in y | i in l..u]); var l-1..u: ymax = max(y union {l-1}); array[l..u] of var bool: b; constraint forall(i in l..u-1) ( b[i] = let {var 1..4: cmp = 2*xb[i] + yb[i] + 1} in [b[i+1], xmax < i, ymax > i, b[i+1]][cmp] ); constraint b[u] = (xb[u] -> yb[u]); } in r <-> b[l] endif; predicate set_le_imp(var set of int: x, var set of int: y, var bool: r) = if ub(x) = {} then true elseif ub(y) = {} then set_eq_imp(x, {}, r) else let { set of int: U = ub(x) union ub(y); int: l = min(U); int: u = max(U); array[l..u] of var bool: xb = array1d(l..u, [i in x | i in l..u]); var l-1..u: xmax = max(x union {l-1}); array[l..u] of var bool: yb = array1d(l..u, [i in y | i in l..u]); var l-1..u: ymax = max(y union {l-1}); array[l..u] of var bool: b; constraint forall(i in l..u-1) ( b[i] = let {var 1..4: cmp = 2*xb[i] + yb[i] + 1} in [b[i+1], xmax < i, ymax > i, b[i+1]][cmp] ); constraint b[u] = (xb[u] -> yb[u]); } in r -> b[l] endif; predicate set_lt(var set of int: x, var set of int: y) ::promise_total = if ub(x) = {} then card(y) >= 1 elseif ub(y) = {} then false else let { set of int: U = ub(x) union ub(y); int: l = min(U); int: u = max(U); array[l..u] of var bool: xb = array1d(l..u, [i in x | i in l..u]); var l-1..u: xmax = max(x union {l-1}); array[l..u] of var bool: yb = array1d(l..u, [i in y | i in l..u]); var l-1..u: ymax = max(y union {l-1}); array[l..u] of var bool: b; constraint forall(i in l..u-1) ( b[i] = let {var 1..4: cmp = 2*xb[i] + yb[i] + 1} in [b[i+1], xmax < i, ymax > i, b[i+1]][cmp] ); constraint b[u] = (not xb[u] /\ yb[u]); } in b[l] endif; predicate set_lt_reif(var set of int: x, var set of int: y, var bool: r) ::promise_total = if ub(x) = {} then r = (card(y) >= 1) elseif ub(y) = {} then not r else let { set of int: U = ub(x) union ub(y); int: l = min(U); int: u = max(U); array[l..u] of var bool: xb = array1d(l..u, [i in x | i in l..u]); var l-1..u: xmax = max(x union {l-1}); array[l..u] of var bool: yb = array1d(l..u, [i in y | i in l..u]); var l-1..u: ymax = max(y union {l-1}); array[l..u] of var bool: b; constraint forall(i in l..u-1) ( b[i] = let {var 1..4: cmp = 2*xb[i] + yb[i] + 1} in [b[i+1], xmax < i, ymax > i, b[i+1]][cmp] ); constraint b[u] = (not xb[u] /\ yb[u]); } in r <-> b[l] endif; predicate set_lt_imp(var set of int: x, var set of int: y, var bool: r) ::promise_total = if ub(x) = {} then r -> (card(y) >= 1) elseif ub(y) = {} then not r else let { set of int: U = ub(x) union ub(y); int: l = min(U); int: u = max(U); array[l..u] of var bool: xb = array1d(l..u, [i in x | i in l..u]); var l-1..u: xmax = max(x union {l-1}); array[l..u] of var bool: yb = array1d(l..u, [i in y | i in l..u]); var l-1..u: ymax = max(y union {l-1}); array[l..u] of var bool: b; constraint forall(i in l..u-1) ( b[i] = let {var 1..4: cmp = 2*xb[i] + yb[i] + 1} in [b[i+1], xmax < i, ymax > i, b[i+1]][cmp] ); constraint b[u] = (not xb[u] /\ yb[u]); } in r -> b[l] endif; predicate set_subset(var set of int: x, var set of int: y) ::promise_total = let { array[int] of var bool: bx = set2bools(x); array[int] of var bool: by = set2bools(y); } in forall (i in index_set(bx)) ( if not (i in index_set(by)) then not bx[i] else bx[i] -> by[i] endif ); predicate set_subset_reif(var set of int: x, var set of int: y, var bool: b) ::promise_total = let { array[int] of var bool: bx = set2bools(x); array[int] of var bool: by = set2bools(y); } in b <-> forall (i in index_set(bx)) ( if not (i in index_set(by)) then not bx[i] else bx[i] -> by[i] endif ); predicate set_subset_imp(var set of int: x, var set of int: y, var bool: b) = let { array[int] of var bool: bx = set2bools(x); array[int] of var bool: by = set2bools(y); } in b -> forall (i in index_set(bx)) ( if not (i in index_set(by)) then not bx[i] else bx[i] -> by[i] endif ); %%% Map the subset operation to superset predicate set_superset(var set of int: x, var set of int: y) ::promise_total = set_subset( y, x ); predicate set_superset_reif(var set of int: x, var set of int: y, var bool: b) ::promise_total = set_subset_reif( y, x, b ); predicate set_superset_imp(var set of int: x, var set of int: y, var bool: b) = set_subset_imp(y,x,b); function var set of int: set_intersect(var set of int: x, var set of int: y) ::promise_total ::promise_commutative = let { array[int] of var bool: bx = set2bools(x); array[int] of var bool: by = set2bools(y); var set of (index_set(bx) intersect index_set(by)): z; array[int] of var bool: bz = set2bools(z); constraint forall (i in index_set(bz)) ( bz[i] = (bx[i] /\ by[i]) ); } in z; function var set of int: set_union(var set of int: x, var set of int: y) ::promise_total ::promise_commutative = let { array[int] of var bool: bx = set2bools(x); array[int] of var bool: by = set2bools(y); var set of (index_set(bx) union index_set(by)): z; array[int] of var bool: bz = set2bools(z); constraint forall (i in index_set(bx) union index_set(by)) ( if (i in index_set(bx)) then if (i in index_set(by)) then bz[i] = (bx[i] \/ by[i]) else bz[i] = bx[i] endif else bz[i] = by[i] endif ); } in z; function var set of int: set_diff(var set of int: x, var set of int: y) ::promise_total = let { array[int] of var bool: bx = set2bools(x); array[int] of var bool: by = set2bools(y); var set of ub(x) diff lb(y): z; array[int] of var bool: bz = set2bools(z); constraint forall (i in ub(z)) ( bz[i] = (bx[i] /\ (not by[i])) ); } in z; function var set of int: set_symdiff(var set of int: x, var set of int: y) ::promise_total ::promise_commutative = let { array[int] of var bool: bx = set2bools(x); array[int] of var bool: by = set2bools(y); var set of (ub(x) diff lb(y)) union (ub(y) diff lb(x)): z; array[int] of var bool: bz = set2bools(z); constraint forall (i in ub(z)) ( bz[i] = ((bx[i]::maybe_partial) xor (by[i]::maybe_partial)) ); } in z; predicate set_card(var set of int: x, var int: c) = let { array[int] of var bool: bx = set2bools(x); } in bool_lin_eq([1 | i in index_set(bx)],[bx[i] | i in index_set(bx)],c); predicate set_in(int: x, var set of int: y) ::promise_total = let { array[int] of var bool: by = set2bools(y); } in by[x]; predicate set_in(var int: x, var set of int: y) ::promise_total = let { array[int] of var bool: by = set2bools(y); } in by[x]; predicate set_in_reif(int: x, var set of int: y, var bool: b) ::promise_total = if x in ub(y) then b <-> set2bools(y)[x] else not b endif; predicate set_in_reif(var int: x, var set of int: y, var bool: b) ::promise_total = b <-> set2bools(y)[x]; predicate set_in_imp(int: x, var set of int: y, var bool: b) = if x in ub(y) then b -> set2bools(y)[x] else not b endif; predicate set_in_imp(var int: x, var set of int: y, var bool: b) = b -> set2bools(y)[x]; function array[int] of var bool: setarray2bools(array[int] of var set of int: x) = if length(x)=0 then [] else set2bools(x[1])++setarray2bools([x[i]|i in 2..length(x)]) endif; %% Par version no sense predicate array_var_set_element(var int: x, array[int] of var set of int: y, var set of int: z) ::promise_total = let { constraint x in { i | i in index_set( y ) where lb(y[i]) subset ub(z) /\ lb(z) subset ub(y[i]) }; set of int: sUB = array_union( [ ub(y[i]) | i in dom(x) ] ); set of int: sLB = array_intersect( [ lb(y[i]) | i in dom(x) ] ); constraint z subset sUB, constraint sLB subset z, } in forall (k in ub(z)) ( set2bools(z)[k] == if k in sUB then if k in sLB then true else array1d( lb(x)..ub(x), [ if k in ub(y[i]) then set2bools(y[i])[k] else false endif | i in lb(x)..ub(x) ] )[x] endif else false endif ) /\ forall (k in sUB diff ub(z))( if k in sLB then false %% fail the constraint else not array1d( lb(x)..ub(x), [ if k in ub(y[i]) then set2bools(y[i])[k] else false endif | i in lb(x)..ub(x) ] )[x] endif ); predicate array_set_element(var int: x, array[int] of set of int: y, var set of int: z) ::promise_total = let { constraint x in { i | i in index_set( y ) where y[i] subset ub(z) /\ lb(z) subset y[i] }; set of int: sUB = array_union( [ y[i] | i in dom(x) ] ); set of int: sLB = array_intersect( [ y[i] | i in dom(x) ] ); constraint z subset sUB, constraint sLB subset z, } in forall (k in ub(z)) ( set2bools(z)[k] == if k in sUB then if k in sLB then true else array1d( lb(x)..ub(x), [ if k in ub(y[i]) then set2bools(y[i])[k] else false endif | i in lb(x)..ub(x) ] )[x] endif else false endif ) /\ forall (k in sUB diff ub(z))( if k in sLB then false %% fail the constraint else not array1d( lb(x)..ub(x), [ if k in ub(y[i]) then set2bools(y[i])[k] else false endif | i in lb(x)..ub(x) ] )[x] endif ); annotation set_search(array[int] of var set of int: x, ann: a1, ann: a2, ann: a3) = let { ann: cc = if a2 == indomain_min then indomain_max elseif a2 == indomain_max then indomain_min else a2 endif; } in seq_search([bool_search(set2bools(x[i]), a1, cc, a3) | i in index_set(x)]); annotation warm_start( array[int] of var set of int: x, array[int] of set of int: v ) = warm_start_array( [ let { array[int] of var bool: xb = set2bools(x[i]), set of int: is_var = ub(x[i]) diff lb(x[i]), int: iV = i - min(index_set(x)) + if 0= 0) /\ W >= 0 /\ P >= 0 /\ P = sum(i in index_set(p)) (x[i]*p[i]) /\ W = sum(i in index_set(w)) (x[i]*w[i]); libminizinc-2.8.2/share/minizinc/std/fzn_count_lt_par.mzn0000644000175000017500000000031414536677021022311 0ustar kaolkaolinclude "fzn_count_lt.mzn"; predicate fzn_count_lt_par(array[int] of var int: x, int: y, int: c) = fzn_count_lt(x,y,c); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_table_int.mzn0000644000175000017500000000223014536677021021560 0ustar kaolkaol%-----------------------------------------------------------------------------% % A table constraint table(x, t) represents the constraint x in t where we % consider each row in t to be a tuple and t as a set of tuples. %-----------------------------------------------------------------------------% predicate fzn_table_int(array[int] of var int: x, array[int, int] of int: t) = let { int: l = min(index_set(x)), int: u = max(index_set(x)), int: lt = min(index_set_1of2(t)), int: ut = max(index_set_1of2(t)), var lt..ut: i, array[l..u, lt..ut] of int: t_transposed = array2d(l..u, lt..ut, [ t[k,j] | j in l..u, k in lt..ut ]) } in forall(j in l..u) ( % Having the variable index component at the left position % means that the nD-to-1D array translation during Mzn-to-Fzn % will generate at most an offset constraint, instead of a % scaling + offset constraint. % t_transposed[j,i] = x[j] % % t[i,j] = x[j] ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_value_precede_chain_int_reif.mzn0000644000175000017500000000025614536677021025451 0ustar kaolkaolpredicate fzn_value_precede_chain_int_reif(array[int] of int: T, array[int] of var int: X, var bool: b) = abort("Reified value_precede_chain constraint is not supported"); libminizinc-2.8.2/share/minizinc/std/lex_less_int.mzn.deprecated.mzn0000644000175000017500000000073214536677021024341 0ustar kaolkaolpredicate lex_less_int(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); predicate lex_lt_int(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_dwst_reif.mzn0000644000175000017500000000052214536677021021607 0ustar kaolkaolpredicate fzn_dwst_reif(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, var int: r, array[int] of var bool: es, var int: K, var bool: b) = abort("Reified dwst constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_arg_min_bool_opt.mzn0000644000175000017500000000034714536677021023137 0ustar kaolkaolinclude "arg_min.mzn"; predicate fzn_minimum_arg_bool_opt(array[int] of var opt bool: x, var int: z) = let { array [index_set(x)] of var 0..2: dx = array1d(index_set(x), [xi default 2 | xi in x]); } in minimum_arg(dx, z); libminizinc-2.8.2/share/minizinc/std/fzn_strictly_increasing_int_opt.mzn0000644000175000017500000000125414536677021025437 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in strict increasing order %-----------------------------------------------------------------------------% predicate fzn_strictly_increasing_int_opt(array[int] of var opt int: x) = let { array[int] of var opt int: xx = array1d(x); array[1..length(xx)] of var int: y; constraint forall(i in 1..length(xx)) ( y[i] = if occurs(xx[i]) then deopt(xx[i]) elseif i = 1 then lb_array(xx) - 1 else y[i-1] endif ); } in forall (i in 2..length(y) where occurs(xx[i])) ( deopt(xx[i]) > y[i-1] ); libminizinc-2.8.2/share/minizinc/std/fzn_count_gt_par.mzn0000644000175000017500000000031414536677021022304 0ustar kaolkaolinclude "fzn_count_gt.mzn"; predicate fzn_count_gt_par(array[int] of var int: x, int: y, int: c) = fzn_count_gt(x,y,c); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_alldifferent_except_0.mzn0000644000175000017500000000021114536677021024042 0ustar kaolkaolinclude "alldifferent_except.mzn"; predicate fzn_alldifferent_except_0(array[int] of var int: vs) = alldifferent_except(vs, {0}); libminizinc-2.8.2/share/minizinc/std/fzn_mdd_nondet_reif.mzn0000644000175000017500000000327614536677021022752 0ustar kaolkaolpredicate fzn_mdd_nondet_reif(array[int] of var int: x, % variables constrained by MDD int: N, % number of nodes root is node 1 array[int] of int: level, % level of each node root is level 1, T is level length(x)+1 int: E, % number of edges array[int] of int: from, % edge leaving node 1..N array[int] of set of int: label, % value of variable array[int] of int: to, % edge entering node 0..N where 0 = T node var bool: b % reification value ) = let { set of int: NODE = 1..N; set of int: EDGE = 1..E; int: L = length(x); array[0..N] of var bool: bn; array[EDGE] of var bool: be; set of int: D = dom_array(x); } in bn[0] /\ % true node is true (b <-> bn[1]) /\ % root gives truth value % T1 each node except the root enforces an outgoing edge forall(n in NODE)(bn[n] -> exists(e in EDGE where from[e] = n)(be[e])) /\ % T23 each edge enforces its endpoints forall(e in EDGE)((be[e] -> bn[from[e]]) /\ (be[e] -> bn[to[e]])) /\ % T4 each edge enforces its label forall(e in EDGE)(be[e] -> x[level[from[e]]] in label[e]) /\ % P2 each node except the root enforces an incoming edge exists(e in EDGE where to[e] = 0)(be[e]) /\ forall(n in 2..N)(bn[n] -> exists(e in EDGE where to[e] = n)(be[e])) /\ % P3 each label has a support forall(i in 1..L, d in D) (x[i] = d -> exists(e in EDGE where level[from[e]] = i /\ d in label[e])(be[e])); libminizinc-2.8.2/share/minizinc/std/fzn_reachable_int.mzn0000644000175000017500000000112614536677021022402 0ustar kaolkaolinclude "subgraph.mzn"; predicate fzn_reachable(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: r, array[int] of var bool: ns, array[int] of var bool: es) = let { array[1..2*E] of int: dfrom = from ++ to; array[1..2*E] of int: dto = to ++ from; array[1..2*E] of var bool: des = es ++ es; } in /* duplicate the edges so that the we can use directed graph reachability */ fzn_dreachable(N,2*E,dfrom,dto,r,ns,des); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_set_member_reif.mzn0000644000175000017500000000046314536677021022754 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array or set 'x'. %-----------------------------------------------------------------------------% predicate fzn_set_member_reif(var set of int: x, var int: y, var bool: b) = b <-> y in x; libminizinc-2.8.2/share/minizinc/std/sort.mzn0000644000175000017500000000063014536677021017733 0ustar kaolkaolinclude "fzn_sort.mzn"; include "fzn_sort_reif.mzn"; /** @group globals.sort Requires that the multiset of values in \a x are the same as the multiset of values in \a y but \a y is in sorted order. */ predicate sort(array[int] of var int: x, array[int] of var int: y) = assert(card(index_set(x)) == card(index_set(y)), "sort: x and y must be same sized arrays", fzn_sort(x,y) ); libminizinc-2.8.2/share/minizinc/std/solver_redefinitions.mzn0000644000175000017500000000323214536677021023201 0ustar kaolkaol%-----------------------------------------------------------------------------% % Solver redefinitions %-----------------------------------------------------------------------------% % This file contains all files that can be used by solver libraries to provide % or override redefinitions of FlatZinc builtins. include "redefinitions.mzn"; include "redefinitions-2.0.mzn"; include "redefinitions-2.0.2.mzn"; include "redefinitions-2.1.mzn"; include "redefinitions-2.1.1.mzn"; include "redefinitions-2.2.1.mzn"; include "redefinitions-2.3.3.mzn"; include "redefinitions-2.5.2.mzn"; include "redefinitions-2.7.1.mzn"; % Inclusion of count constraints for internal redefinitions of hidden counting constraints include "count_eq.mzn"; include "count_geq.mzn"; include "count_leq.mzn"; include "count_neq.mzn"; include "count_gt.mzn"; include "count_lt.mzn"; include "count_fn.mzn"; include "fzn_if_then_else_int.mzn"; include "fzn_if_then_else_opt_int.mzn"; include "fzn_if_then_else_var_int.mzn"; include "fzn_if_then_else_var_opt_int.mzn"; include "fzn_if_then_else_bool.mzn"; include "fzn_if_then_else_opt_bool.mzn"; include "fzn_if_then_else_var_bool.mzn"; include "fzn_if_then_else_var_opt_bool.mzn"; include "fzn_if_then_else_float.mzn"; include "fzn_if_then_else_opt_float.mzn"; include "fzn_if_then_else_var_float.mzn"; include "fzn_if_then_else_var_opt_float.mzn"; include "fzn_if_then_else_set.mzn"; include "fzn_if_then_else_var_set.mzn"; include "fzn_if_then_else_partiality.mzn"; include "lex_less.mzn"; include "lex_lesseq.mzn"; include "fzn_array_int_union.mzn"; include "fzn_array_opt_int_union.mzn"; include "fzn_array_set_union.mzn"; include "fzn_array_set_intersect.mzn"; libminizinc-2.8.2/share/minizinc/std/fzn_disjunctive.mzn0000644000175000017500000000043314536677021022151 0ustar kaolkaolpredicate fzn_disjunctive(array[int] of var int: s, array[int] of var int: d) = forall (i in index_set(d)) (d[i] >= 0) /\ forall (i,j in index_set(d) where i to something not y int: def = assert( has_bounds(y), "Unable to decompose count_eq without bounds for the y argument", if 0 in dom(y) then lb(y)-1 else 0 endif ); } in count_eq([i default def | i in x], y, c); /** @group globals.counting Constrains \a c to be the number of occurrences of \a y in \a x. */ predicate count_eq(array[$X] of var $$E: x, $$E: y, int: c) = fzn_count_eq_par(array1d(x), y, c); test count_eq(array[$X] of $$E: x, $$E: y, int: c) = c = count_eq(x, y); /** @group globals.counting Returns the number of occurrences of \a y in \a x. */ function var int: count_eq(array[$X] of var opt $$E: x, var $$E: y) ::promise_total = let { var 0..length(x): c ::is_defined_var; constraint count_eq(x, y, c) ::defines_var(c); } in c; function int: count_eq(array[$X] of opt $$E: x, $$E: y) = sum(v in x where occurs(v))( v = y ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_count_eq_reif.mzn0000644000175000017500000000031114536677021022437 0ustar kaolkaolpredicate fzn_count_eq_reif(array[int] of var int: x, var int: y, var int: c, var bool: b) = b <-> count_eq(x,y)=c; %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/regular_set.mzn0000644000175000017500000000007214536677021021260 0ustar kaolkaolinclude "regular.mzn"; % TODO: File no longer necessary. libminizinc-2.8.2/share/minizinc/std/fzn_sliding_sum.mzn0000644000175000017500000000140114536677021022133 0ustar kaolkaolpredicate fzn_sliding_sum(int: low, int: up, int: seq, array[int] of var int: vs) = /* CS decomposition: see S. Brand, N. Narodytska, C-G. Quimper, P.J. Stuckey, and T. Walsh. Encodings of the sequence constraint. In C. Bessiere, editor, Proceedings of the 13th International Conference on Principles and Practice of Constraint Programming, volume 4741 of LNCS, pages 210–224. Springer-Verlag, 2007. */ let { int: lx = min(index_set(vs)); int: ux = max(index_set(vs)); array[lx-1..ux] of var int: S; } in S[lx-1] = 0 /\ forall (i in lx .. ux) ( S[i] = vs[i] + S[i-1] ) /\ forall (i in lx-1 .. ux - seq) ( S[i] <= S[i+seq] - low /\ S[i+seq] <= S[i] + up ); libminizinc-2.8.2/share/minizinc/std/fzn_writes_reif.mzn0000644000175000017500000000075114536677021022147 0ustar kaolkaolpredicate fzn_writes_reif(array[int] of var int: I, array[int] of var int: P, array[int] of var int: V, array[int] of var int: O, var bool: b) = b <-> ( forall(j in index_set(P))(O[P[j]] = V[j]) /\ forall(i in index_set(I)) (if forall(j in index_set(P))(P[j] != i) then O[i] = I[i] else true endif) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_connected.mzn0000644000175000017500000000052514536677021021566 0ustar kaolkaolinclude "reachable.mzn"; predicate fzn_connected(array[int] of $$N: from, array[int] of $$N: to, array[$$N] of var bool: ns, array[int] of var bool: es) = let { var index_set(ns): r } in reachable(from, to, r, ns, es); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_mdd_reif.mzn0000644000175000017500000000462414536677021021401 0ustar kaolkaolpredicate fzn_mdd_reif(array[int] of var int: x, % variables constrained by MDD int: N, % number of nodes root is node 1 array[int] of int: level, % level of each node root is level 1, T is level length(x)+1 int: E, % number of edges array[int] of int: from, % edge leaving node 1..N array[int] of set of int: label, % value of variable array[int] of int: to, % edge entering node 0..N where 0 = T node var bool: b % reification value ) = let { set of int: NODE = 1..N; set of int: EDGE = 1..E; int: L = length(x); array[0..N] of var bool: bn; array[EDGE] of var bool: be; set of int: D = dom_array(x); } in (b <-> bn[0]) /\ % true node is result bn[1] /\ % root is always true % T1 each node except the true enforces an outgoing edge forall(n in NODE)(bn[n] -> (exists(e in EDGE where from[e] = n)(be[e]) \/ b = 0)) /\ % T23 each edge enforces its endpoints forall(e in EDGE)((be[e] -> bn[from[e]]) /\ (be[e] -> bn[to[e]])) /\ % T4 each edge enforces its label forall(e in EDGE)(be[e] -> x[level[from[e]]] in label[e]) /\ % P1 each node enforces its outgoing edges forall(e in EDGE)(bn[from[e]] /\ x[level[from[e]]] in label[e] -> be[e]) /\ % P2 each node except the root enforces an incoming edge (bn[0] -> exists(e in EDGE where to[e] = 0)(be[e])) /\ forall(n in 2..N)(bn[n] -> exists(e in EDGE where to[e] = n)(be[e])) /\ % P3 each label has a support, either an edge or to give false forall(i in 1..L, d in D) (x[i] = d -> forall(n in NODE where level[n] = i, e in EDGE where from[e] = n /\ d in label[e]) (bn[n] -> be[e]) /\ forall(n in NODE where level[n] = i /\ not exists(e in EDGE where from[e] = n) (d in label[e])) (bn[n] -> b = 0)) /\ % P4 at most one node at every level is true (redundant) forall(i in 1..L) (sum(n in NODE where level[n] = i)(bn[n]) <= 1); libminizinc-2.8.2/share/minizinc/std/lex_greater.mzn0000644000175000017500000000263414536677021021253 0ustar kaolkaolinclude "lex_less.mzn"; /** @group globals.lexicographic Requires that the array \a x is strictly lexicographically greater than array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_greater(array[int] of var bool: x ::promise_ctx_antitone, array[int] of var bool: y ::promise_ctx_antitone) = lex_less(y, x); /** @group globals.lexicographic Requires that the array \a x is strictly lexicographically greater than array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_greater(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_antitone) = lex_less(y, x); /** @group globals.lexicographic Requires that the array \a x is strictly lexicographically greater than array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_greater(array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_antitone) = lex_less(y, x); /** @group globals.lexicographic Requires that the array \a x is strictly lexicographically greater than array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_greater(array[int] of var set of int: x, array[int] of var set of int: y) = lex_less(y, x); libminizinc-2.8.2/share/minizinc/std/lex_less.mzn0000644000175000017500000000562714536677021020575 0ustar kaolkaolinclude "fzn_lex_less_bool.mzn"; include "fzn_lex_less_bool_reif.mzn"; include "fzn_lex_less_float.mzn"; include "fzn_lex_less_float_reif.mzn"; include "fzn_lex_less_int.mzn"; include "fzn_lex_less_int_reif.mzn"; include "fzn_lex_less_set.mzn"; include "fzn_lex_less_set_reif.mzn"; /** @group globals.lexicographic Requires that the array \a x is strictly lexicographically less than array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_less( array[int] of var bool: x ::promise_ctx_antitone, array[int] of var bool: y ::promise_ctx_monotone ) = if length(x)=1 /\ length(y)=1 then x[min(index_set(x))] < y[min(index_set(y))] elseif length(x)=0 then length(y)>0 elseif length(y)=0 then false else fzn_lex_less_bool(array1d(x), array1d(y)) endif; /** @group globals.lexicographic Requires that the array \a x is strictly lexicographically less than array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_less( array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone, ) = if length(x)=1 /\ length(y)=1 then x[min(index_set(x))] < y[min(index_set(y))] elseif length(x)=0 then length(y)>0 elseif length(y)=0 then false else fzn_lex_less_int(array1d(x), array1d(y)) endif; /** @group globals.lexicographic Requires that the array \a x is strictly lexicographically less than array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_less( array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_monotone, ) = if length(x)=1 /\ length(y)=1 then x[min(index_set(x))] < y[min(index_set(y))] elseif length(x)=0 then length(y)>0 elseif length(y)=0 then false else fzn_lex_less_float(array1d(x), array1d(y)) endif; /** @group globals.lexicographic Requires that the array \a x is strictly lexicographically less than array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_less( array[int] of var set of int: x, array[int] of var set of int: y, ) = if length(x)=1 /\ length(y)=1 then x[min(index_set(x))] < y[min(index_set(y))] elseif length(x)=0 then length(y)>0 elseif length(y)=0 then false else fzn_lex_less_set(array1d(x), array1d(y)) endif; % Alternative names for the above. % predicate lex_lt(array[int] of var bool: x ::promise_ctx_antitone, array[int] of var bool: y ::promise_ctx_monotone) = lex_less(x, y); predicate lex_lt(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) = lex_less(x, y); predicate lex_lt(array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_monotone) = lex_less(x, y); predicate lex_lt(array[int] of var set of int: x, array[int] of var set of int: y) = lex_less(x, y); libminizinc-2.8.2/share/minizinc/std/lex_chain_lesseq_orbitope.mzn0000644000175000017500000000122114536677021024152 0ustar kaolkaolinclude "fzn_lex_chain_lesseq_orbitope.mzn"; include "fzn_lex_chain_lesseq_orbitope_reif.mzn"; /** @group globals.lexicographic Requires that the columns of binary matrix \a a are lexicographically sorted, non-decreasing. Moreover, the second parameter \a kind has the following meaning: 0: no further constraints, 1: set-partitioning orbitope, 2: set-packing orbitope */ predicate lex_chain_lesseq_orbitope( array[int, int] of var int: a, int: kind ) = assert( dom_array(a) subset 0..1, "lex_chain_lesseq_orbitope: matrix \(a) is non-binary" ) /\ if card(index_set_2of2(a)) > 1 then fzn_lex_chain_lesseq_orbitope(a, kind) endif; libminizinc-2.8.2/share/minizinc/std/alldifferent_except_0.mzn0000644000175000017500000000026514536677021023176 0ustar kaolkaol% The actual definitions are in all_different.mzn. % This file is used to handle the case where users include % "alldifferent_except_0.mzn"; % include "all_different_except_0.mzn"; libminizinc-2.8.2/share/minizinc/std/disjoint.mzn0000644000175000017500000000034314536677021020570 0ustar kaolkaolinclude "fzn_disjoint.mzn"; include "fzn_disjoint_reif.mzn"; /** @group globals.set Requires that sets \a s1 and \a s2 do not intersect. */ predicate disjoint(var set of $$E: s1, var set of $$E: s2) = fzn_disjoint(s1,s2); libminizinc-2.8.2/share/minizinc/std/fzn_member_set_reif.mzn0000644000175000017500000000055114536677021022752 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array of set 'x'. %-----------------------------------------------------------------------------% predicate fzn_member_set_reif(array[int] of var set of int: x, var set of int: y, var bool: b) = b <-> exists(i in index_set(x)) ( x[i] == y ); libminizinc-2.8.2/share/minizinc/std/fzn_nvalue_reif.mzn0000644000175000017500000000037614536677021022127 0ustar kaolkaolpredicate fzn_nvalue_reif(var int: n, array[int] of var int: x, var bool: b) = let { int: lx = lb_array(x), int: ux = ub_array(x), } in b <-> n == sum(j in lx..ux) ( exists(i in index_set(x)) ( x[i] = j ) ); libminizinc-2.8.2/share/minizinc/std/fzn_exactly_set.mzn0000644000175000017500000000054314536677021022150 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires exactly 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate fzn_exactly_set(int: n, array[int] of var set of int: x, set of int: v) = n == sum(i in index_set(x)) ( x[i] == v ); libminizinc-2.8.2/share/minizinc/std/all_different_int.mzn.deprecated.mzn0000644000175000017500000000022514536677021025316 0ustar kaolkaolpredicate all_different_int(array[int] of var int: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/element_set.mzn.deprecated.mzn0000644000175000017500000000027214536677021024154 0ustar kaolkaolpredicate element_set( var $$E: i, array[$$E] of var set of $$T: x, var set of $$T: y ) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/inverse_fn.mzn0000644000175000017500000000157114536677021021107 0ustar kaolkaolinclude "inverse.mzn"; /** @group globals.channeling Given a function \a f represented as an array, return the inverse function. */ function array[$$E] of var $$F: inverse(array[$$F] of var $$E: f) = let { array[lb_array(f)..ub_array(f)] of var index_set(f): invf ::is_defined_var; constraint inverse(f,invf) ::defines_var(invf); } in invf; /** @group globals.channeling Given a function \a f represented as an array, return the inverse function. */ function array[$$E] of var opt $$F: inverse(array[$$F] of var opt $$E: f) = let { array[lb_array(f)..ub_array(f)] of var opt index_set(f): invf ::is_defined_var; constraint inverse(f, invf) ::defines_var(invf); } in invf; /** @group globals.channeling Given a function \a f represented as an array, return the inverse function. */ function array[$$E] of $$F: inverse(array[$$F] of $$E: f); libminizinc-2.8.2/share/minizinc/std/global_cardinality_closed_fn.mzn0000644000175000017500000000240214536677021024602 0ustar kaolkaolinclude "global_cardinality_closed.mzn"; /** @group globals.counting Returns an array with number of occurrences of \a cover[\p i] in \a x. The elements of \a x must take their values from \a cover. */ function array[$Y] of var int: global_cardinality_closed(array[$X] of var $$E: x, array[$Y] of $$E: cover) :: promise_total = let { array[int] of int: cover1d = array1d(cover); array[index_set(cover1d)] of var 0..length(x): counts ::is_defined_var; constraint global_cardinality_closed(array1d(x), cover1d, counts) ::defines_var(counts); } in arrayXd(cover, counts); /** @group globals.counting Returns an array with number of occurrences of \a cover[\p i] in \a x. The elements of \a x must take their values from \a cover or be absent. */ function array[$Y] of var int: global_cardinality_closed(array[$X] of var opt $$E: x, array[$Y] of $$E: cover) :: promise_total = let { array[int] of int: cover1d = array1d(cover); array[index_set(cover1d)] of var 0..length(x): counts ::is_defined_var; constraint global_cardinality_closed(array1d(x), cover1d, counts) ::defines_var(counts); } in arrayXd(cover, counts); libminizinc-2.8.2/share/minizinc/std/among.mzn0000644000175000017500000000044514536677021020051 0ustar kaolkaolinclude "among_fn.mzn"; include "fzn_among.mzn"; include "fzn_among_reif.mzn"; /** @group globals.counting Requires exactly \a n variables in \a x to take one of the values in \a v. */ predicate among(var int: n, array[$X] of var $$E: x, set of $$E: v) = fzn_among(n, array1d(x), v); libminizinc-2.8.2/share/minizinc/std/fzn_count_geq_par_reif.mzn0000644000175000017500000000035514536677021023460 0ustar kaolkaolinclude "fzn_count_geq_reif.mzn"; predicate fzn_count_geq_par_reif(array[int] of var int: x, int: y, int: c, var bool: b) = fzn_count_geq_reif(x,y,c,b); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_disjoint_reif.mzn0000644000175000017500000000016414536677021022453 0ustar kaolkaolpredicate fzn_disjoint_reif(var set of int: s1, var set of int: s2, var bool: b) = b <-> s1 intersect s2 == {}; libminizinc-2.8.2/share/minizinc/std/redefinitions.mzn0000644000175000017500000000013514536677021021606 0ustar kaolkaol% This file contains redefinitions of standard builtins that can be overridden % by solvers. libminizinc-2.8.2/share/minizinc/std/fzn_alldifferent_except.mzn0000644000175000017500000000104414536677021023630 0ustar kaolkaolinclude "global_cardinality_low_up.mzn"; predicate fzn_alldifferent_except(array[int] of var int: vs, set of int: S) = %% if the variables in vs are bounded then use the gcc decomposition if forall(i in index_set(vs))(has_bounds(vs[i])) then let { set of int: A = dom_array(vs) diff S; } in global_cardinality_low_up(vs, A, [0 | i in A], [1 | i in A]) else %% otherwise use the neq decomposition forall(i, j in index_set(vs) where i < j) ((vs[i] in S /\ vs[j] in S) \/ vs[i] != vs[j]) endif; libminizinc-2.8.2/share/minizinc/std/fzn_dreachable_int_reif.mzn0000644000175000017500000000057114536677021023556 0ustar kaolkaolpredicate fzn_dreachable_reif(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: r, array[int] of var bool: ns, array[int] of var bool: es, var bool: b) = abort("Reified dreachable constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_int_set_channel.mzn0000644000175000017500000000060514536677021022760 0ustar kaolkaolpredicate fzn_int_set_channel(array[int] of var int: x, array[int] of var set of int: y) = forall(i in index_set(x)) (x[i] in index_set(y)) /\ forall(j in index_set(y)) (y[j] subset index_set(x)) /\ forall(i in index_set(x), j in index_set(y)) (x[i] = j <-> i in y[j]); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/output.mzn0000644000175000017500000000033114536677021020302 0ustar kaolkaol/*** @groupdef stdlib.output Stuctured Output These functions provide structured output for common structures modelled in the MiniZinc language. */ include "output/gantt.mzn"; include "output/array2d_bool.mzn"; libminizinc-2.8.2/share/minizinc/std/all_different_set.mzn.deprecated.mzn0000644000175000017500000000023414536677021025317 0ustar kaolkaolpredicate all_different_set(array[int] of var set of int: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/redefinitions-2.0.2.mzn0000644000175000017500000000165114536677021022247 0ustar kaolkaol% This file contains redefinitions of standard builtins for version 2.0.2 % that can be overridden by solvers. predicate symmetry_breaking_constraint(var bool: b) = b; predicate redundant_constraint(var bool: b) = b; predicate array_var_bool_element_nonshifted(var int: idx, array[int] of var bool: x, var bool: c) = array_var_bool_element((idx-(min(index_set(x))-1))::domain,array1d(x),c); predicate array_var_int_element_nonshifted(var int: idx, array[int] of var int: x, var int: c) = array_var_int_element((idx-(min(index_set(x))-1))::domain,array1d(x),c); predicate array_var_float_element_nonshifted(var int: idx, array[int] of var float: x, var float: c) = array_var_float_element((idx-(min(index_set(x))-1))::domain,array1d(x),c); predicate array_var_set_element_nonshifted(var int: idx, array[int] of var set of int: x, var set of int: c) = array_var_set_element((idx-(min(index_set(x))-1))::domain,array1d(x),c); libminizinc-2.8.2/share/minizinc/std/fzn_arg_val_float.mzn0000644000175000017500000000030014536677021022413 0ustar kaolkaolinclude "fzn_arg_max_bool.mzn"; predicate fzn_arg_val_float(array[int] of var float: x, var float: v, var int: i) = fzn_maximum_arg_bool([j: x[j] == v | j in index_set(x)], i) /\ x[i] = v; libminizinc-2.8.2/share/minizinc/std/fzn_at_least_set_reif.mzn0000644000175000017500000000057614536677021023306 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires at least 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate fzn_at_least_set_reif(int: n, array[int] of var set of int: x, set of int: v, var bool: b) = b <-> sum(i in index_set(x)) ( x[i] == v ) >= n; libminizinc-2.8.2/share/minizinc/std/fzn_mdd_nondet.mzn0000644000175000017500000000315014536677021021734 0ustar kaolkaolpredicate fzn_mdd_nondet(array[int] of var int: x, % variables constrained by MDD int: N, % number of nodes root is node 1 array[int] of int: level, % level of each node root is level 1, T is level length(x)+1 int: E, % number of edges array[int] of int: from, % edge leaving node 1..N array[int] of set of int: label, % value of variable array[int] of int: to % edge entering node 0..N where 0 = T node ) = let { set of int: NODE = 1..N; set of int: EDGE = 1..E; int: L = length(x); array[0..N] of var bool: bn; array[EDGE] of var bool: be; set of int: D = dom_array(x); } in bn[0] /\ % true node is true bn[1] /\ % root must hold % T1 each node except the root enforces an outgoing edge forall(n in NODE)(bn[n] -> exists(e in EDGE where from[e] = n)(be[e])) /\ % T23 each edge enforces its endpoints forall(e in EDGE)((be[e] -> bn[from[e]]) /\ (be[e] -> bn[to[e]])) /\ % T4 each edge enforces its label forall(e in EDGE)(be[e] -> x[level[from[e]]] in label[e]) /\ % P2 each node except the root enforces an incoming edge exists(e in EDGE where to[e] = 0)(be[e]) /\ forall(n in 2..N)(bn[n] -> exists(e in EDGE where to[e] = n)(be[e])) /\ % P3 each label has a support forall(i in 1..L, d in D) (x[i] = d -> exists(e in EDGE where level[from[e]] = i /\ d in label[e])(be[e])); libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_low_up_set.mzn0000644000175000017500000000070714536677021025711 0ustar kaolkaolpredicate fzn_global_cardinality_low_up_set(array[int] of var set of int: x, array[int] of int: cover, array[int] of int: lbound, array[int] of int: ubound) = forall (i in index_set(cover)) ( let { var int: sd = count (v in x) (cover[i] in v); } in lbound[i] <= sd /\ sd <= ubound[i] ); libminizinc-2.8.2/share/minizinc/std/fzn_range_reif.mzn0000644000175000017500000000075714536677021021734 0ustar kaolkaolpredicate fzn_range_reif(array[int] of var int: x, var set of int: s, var set of int: t, var bool: b) = b <-> ( % All values in 's' must map to a value in 't'. forall(i in ub(s)) ( i in s -> x[i] in t ) /\ % All values in 't' must be mapped from a value in 's'. forall(i in ub(t)) ( i in t -> exists(j in ub(s)) ( j in s /\ x[j] == i ) ) ); libminizinc-2.8.2/share/minizinc/std/arg_max_float.mzn.deprecated.mzn0000644000175000017500000000024314536677021024451 0ustar kaolkaolpredicate maximum_arg_float(array[$$E] of var float: x, var $$E: i) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/element_float.mzn0000644000175000017500000000047014536677021021564 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' is the ith element of the array 'x'. %-----------------------------------------------------------------------------% predicate element_float(var $$E: i, array[$$E] of var float: x, var float: y) = y = x[i]; libminizinc-2.8.2/share/minizinc/std/fzn_arg_val_int_opt.mzn0000644000175000017500000000051014536677021022765 0ustar kaolkaolinclude "fzn_arg_val_int.mzn"; predicate fzn_arg_val_int_opt(array[int] of var opt int: x, var opt int: v, var int: i) = let { any: values = x ++ [v]; int: def = if not had_zero(values) /\ lb_array(values) > 0 then 0 else lb_array(values) - 1 endif; } in fzn_arg_val_int([xi default def | xi in x], v default def, i); libminizinc-2.8.2/share/minizinc/std/fzn_strictly_increasing_bool.mzn0000644000175000017500000000055314536677021024717 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in strict increasing order %-----------------------------------------------------------------------------% predicate fzn_strictly_increasing_bool(array[int] of var bool: x) = forall(i in index_set(x) diff { min(index_set(x)) }) (x[i-1] < x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_network_flow_cost_reif.mzn0000644000175000017500000000122714536677021024401 0ustar kaolkaolpredicate fzn_network_flow_cost_reif(array[int,1..2] of int: arc, array[int] of int: balance, array[int] of int: weight, array[int] of var int: flow, var int: cost, var bool: b) = let { int: source_node = 1; int: sink_node = 2; set of int: ARCS = index_set_1of2(arc); set of int: NODES = index_set(balance); } in b <-> ( cost = sum(i in ARCS) (flow[i] * weight[i]) /\ forall (i in NODES) ( sum (j in ARCS where i == arc[j,source_node]) (flow[j]) - sum (j in ARCS where i == arc[j,sink_node]) (flow[j]) = balance[i] ) ); libminizinc-2.8.2/share/minizinc/std/arg_max.mzn0000644000175000017500000001574714536677021020401 0ustar kaolkaolinclude "fzn_arg_max_int.mzn"; include "fzn_arg_max_int_opt.mzn"; include "fzn_arg_max_bool.mzn"; include "fzn_arg_max_bool_opt.mzn"; include "fzn_arg_max_float.mzn"; include "fzn_arg_max_float_opt.mzn"; /** @group globals.math Returns the index of the maximum value in the array \a x. When breaking ties the least index is returned. */ function var $$E: arg_max(array[$$E] of var int: x) = let { constraint length(x) > 0; } in arg_max_total(x); /** @group globals.math Returns the index of the maximum value in the array \a x. When breaking ties the least index is returned. */ function var $$E: arg_max(array[$$E] of var bool: x) = let { constraint length(x) > 0; } in arg_max_total(x); /** @group globals.math Returns the index of the maximum value in the array \a x. When breaking ties the least index is returned. */ function var $$E: arg_max(array[$$E] of var float: x) = let { constraint length(x) > 0; } in arg_max_total(x); /** @group globals.math Returns the index of the maximum non-absent value in the array \a x. When breaking ties the least index is returned. */ function var $$E: arg_max(array[$$E] of var opt int: x) = let { constraint length(x) > 0; } in arg_max_total(x); /** @group globals.math Returns the index of the maximum non-absent value in the array \a x. When breaking ties the least index is returned. Returns absent when all elements are absent. */ function var opt $$E: arg_max_weak(array[$$E] of var opt int: x) :: promise_total = if length(x) = 0 then <> elseif exists (xi in x) (is_fixed(occurs(xi)) /\ fix(occurs(xi))) then let { var index_set(x): i; constraint fzn_maximum_arg_int_opt(x, i); } in i else let { set of int: idx = min(index_set(x)) .. max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [lb_array(x)]); var idx: i; var opt index_set(x): ii = if i in index_set(x) then i else <> endif; constraint fzn_maximum_arg_int_opt(xx, i); } in ii endif; /** @group globals.math Returns the index of the maximum non-absent value in the array \a x. When breaking ties the least index is returned. */ function var $$E: arg_max(array[$$E] of var opt bool: x) = let { constraint length(x) > 0; } in arg_max_total(x); /** @group globals.math Returns the index of the maximum non-absent value in the array \a x. When breaking ties the least index is returned. Returns absent when all elements are absent. */ function var opt $$E: arg_max_weak(array[$$E] of var opt bool: x) :: promise_total = if length(x) = 0 then <> elseif exists (xi in x) (is_fixed(occurs(xi)) /\ fix(occurs(xi))) then let { var index_set(x): i; constraint fzn_maximum_arg_bool_opt(x, i); } in i else let { set of int: idx = min(index_set(x)) .. max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [false]); var idx: i; var opt index_set(x): ii = if i in index_set(x) then i else <> endif; constraint fzn_maximum_arg_bool_opt(xx, i); } in ii endif; /** @group globals.math Returns the index of the maximum non-absent value in the array \a x. When breaking ties the least index is returned. */ function var $$E: arg_max(array[$$E] of var opt float: x) = let { constraint length(x) > 0; } in arg_max_total(x); /** @group globals.math Returns the index of the maximum non-absent value in the array \a x. When breaking ties the least index is returned. Returns absent when all elements are absent. */ function var opt $$E: arg_max_weak(array[$$E] of var opt float: x) :: promise_total = if length(x) = 0 then <> elseif exists (xi in x) (is_fixed(occurs(xi)) /\ fix(occurs(xi))) then let { var index_set(x): i; constraint fzn_maximum_arg_float_opt(x, i); } in i else let { set of int: idx = min(index_set(x)) .. max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [lb_array(x)]); var idx: i; var opt index_set(x): ii = if i in index_set(x) then i else <> endif; constraint fzn_maximum_arg_float_opt(xx, i); } in ii endif; function var $$E: arg_max_total(array[$$E] of var int: x) :: promise_total = if length(x) = 0 then 0 else let { var min(index_set(x)) .. max(index_set(x)): i; constraint fzn_maximum_arg_int(x, i); } in i endif; function var $$E: arg_max_total(array[$$E] of var bool: x) :: promise_total = if length(x) = 0 then 0 else let { var min(index_set(x)) .. max(index_set(x)): i; constraint fzn_maximum_arg_bool(x, i); } in i endif; function var $$E: arg_max_total(array[$$E] of var float: x) :: promise_total = if length(x) = 0 then 0 else let { var min(index_set(x))..max(index_set(x)): i; constraint fzn_maximum_arg_float(x, i); } in i endif; function var $$E: arg_max_total(array[$$E] of var opt int: x) :: promise_total = if length(x) = 0 then 0 elseif exists (xi in x) (is_fixed(occurs(xi)) /\ fix(occurs(xi))) then let { var index_set(x): i; constraint fzn_maximum_arg_int_opt(x, i); } in i else let { set of int: idx = min(index_set(x)) .. max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [lb_array(x)]); var idx: i; var index_set(x): ii = if i in index_set(x) then i else min(index_set(x)) endif; constraint fzn_maximum_arg_int_opt(xx, i); } in ii endif; function var $$E: arg_max_total(array[$$E] of var opt bool: x) :: promise_total = if length(x) = 0 then 0 elseif exists (xi in x) (is_fixed(occurs(xi)) /\ fix(occurs(xi))) then let { var index_set(x): i; constraint fzn_maximum_arg_bool_opt(x, i); } in i else let { set of int: idx = min(index_set(x)) .. max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [false]); var idx: i; var index_set(x): ii = if i in index_set(x) then i else min(index_set(x)) endif; constraint fzn_maximum_arg_bool_opt(xx, i); } in ii endif; function var $$E: arg_max_total(array[$$E] of var opt float: x) :: promise_total = if length(x) = 0 then 0 elseif exists (xi in x) (is_fixed(occurs(xi)) /\ fix(occurs(xi))) then let { var index_set(x): i; constraint fzn_maximum_arg_float_opt(x, i); } in i else let { set of int: idx = min(index_set(x)) .. max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [lb_array(x)]); var idx: i; var index_set(x): ii = if i in index_set(x) then i else min(index_set(x)) endif; constraint fzn_maximum_arg_float_opt(xx, i); } in ii endif; /** @group globals.math Constrain \a i to be the index of the maximum value in the array \a x. When breaking ties the least index is returned. Assumption: |\a x| > 0 */ predicate maximum_arg(array[int] of var int: x, var int: i) = fzn_maximum_arg_int(x, i); /** @group globals.math Constrain \a i to be the index of the maximum value in the array \a x. When breaking ties the least index is returned. Assumption: |\a x| > 0 */ predicate maximum_arg(array[$$E] of var bool: x, var $$E: i) = fzn_maximum_arg_bool(x, i); /** @group globals.math Constrain \a i to be the index of the maximum value in the array \a x. When breaking ties the least index is returned. Assumption: |\a x| > 0 */ predicate maximum_arg(array[$$E] of var float: x, var $$E: i) = fzn_maximum_arg_float(x, i); libminizinc-2.8.2/share/minizinc/std/fzn_count_geq.mzn0000644000175000017500000000055114536677021021607 0ustar kaolkaolinclude "count_fn.mzn"; predicate fzn_count_geq(array[int] of var int: x, var int: y, var int: c) = let { var int: z = count(x,y) } in z <= c; % This needs to be written with a let rather than count(x,y) <= c % so that the automatic rewriting of the latter doesn't kick in %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_alldifferent_except_reif.mzn0000644000175000017500000000032114536677021024632 0ustar kaolkaolpredicate fzn_alldifferent_except_reif(array[int] of var int: vs,set of int: S, var bool: b) = b <-> forall(i, j in index_set(vs) where i < j) ( (vs[i] in S /\ vs[j] in S) \/ vs[i] != vs[j] ); libminizinc-2.8.2/share/minizinc/std/arg_max_bool.mzn.deprecated.mzn0000644000175000017500000000024114536677021024275 0ustar kaolkaolpredicate maximum_arg_bool(array[$$E] of var bool: x, var $$E: i) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_array_set_intersect.mzn0000644000175000017500000000102014536677021023664 0ustar kaolkaol/* Constrain z to be the intersection of the elements in x. False if x is empty. */ predicate fzn_array_set_intersect(array[int] of var set of int: x, var set of int: z) = if length(x)=0 then false elseif length(x)=1 then z=x[min(index_set(x))] else let { int: l=min(index_set(x)); int: u=max(index_set(x)); array[l..u-1] of var set of ub_array(x): y; } in y[l]=x[l] intersect x[l+1] /\ forall (i in l+2..u) (y[i-1]=y[i-2] intersect x[i]) /\ z=y[u-1] endif; libminizinc-2.8.2/share/minizinc/std/strictly_decreasing.mzn0000644000175000017500000000130714536677021023007 0ustar kaolkaolinclude "strictly_increasing.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is in strict decreasing order %-----------------------------------------------------------------------------% /** @group globals.sort Requires that the array \a x is in a stricly decreasing order (duplicates are *not* allowed). */ predicate strictly_decreasing(array[$X] of var bool: x) = strictly_increasing(reverse(array1d(x))); /** @group globals.sort Requires that the array \a x is in a stricly decreasing order (duplicates are *not* allowed). */ predicate strictly_decreasing(array[$X] of var opt int: x) = strictly_increasing(reverse(array1d(x))); libminizinc-2.8.2/share/minizinc/std/fzn_diffn_k.mzn0000644000175000017500000000150714536677021021225 0ustar kaolkaolpredicate fzn_diffn_k(array[int,int] of var int: box_posn, array[int,int] of var int: box_size) = let { set of int: DIMS= index_set_2of2(box_posn) } in forall(b1, b2 in index_set_1of2(box_posn) where b1 < b2) (fzn_diffn_nonoverlap_k([ box_posn[b1,j] | j in DIMS ], [ box_size[b1,j] | j in DIMS ], [ box_posn[b2,j] | j in DIMS ], [ box_size[b2,j] | j in DIMS ] ) ); predicate fzn_diffn_nonoverlap_k(array[int] of var int: x1, array[int] of var int: w1, array[int] of var int: x2, array[int] of var int: w2) = exists(j in index_set(x1)) (x1[j] + w1[j] <= x2[j] \/ x2[j] + w2[j] <= x1[j]); libminizinc-2.8.2/share/minizinc/std/count_fn.mzn0000644000175000017500000000041114536677021020554 0ustar kaolkaolinclude "count_eq.mzn"; /** @group globals.counting Returns the number of occurrences of \a y in \a x. */ function var int: count(array[$X] of var opt $$E: x, var $$E: y) = count_eq(x, y); function int: count(array[$X] of opt $$E: x, $$E: y) = count_eq(x, y); libminizinc-2.8.2/share/minizinc/std/increasing_int.mzn.deprecated.mzn0000644000175000017500000000022114536677021024636 0ustar kaolkaolpredicate increasing_int(array[$X] of var int: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_all_equal_int.mzn0000644000175000017500000000051314536677021022432 0ustar kaolkaol%-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all equal. %-----------------------------------------------------------------------------% predicate fzn_all_equal_int(array[int] of var int: x) = forall(i, j in index_set(x) where i < j) ( x[i] = x[j] ); libminizinc-2.8.2/share/minizinc/std/fzn_bounded_path_enum.mzn0000644000175000017500000000046614536677021023310 0ustar kaolkaolinclude "path.mzn"; predicate fzn_bounded_path(array[int] of $$N: from, array[int] of $$N: to, array[int] of int: w, var $$N: s, var $$N: t, array[$$N] of var bool: ns, array[int] of var bool: es, var int: K) = path(from,to,s,t,ns,es) /\ K = sum(e in index_set(es))(es[e]*w[e]); libminizinc-2.8.2/share/minizinc/std/fzn_lex_chain_lesseq_bool.mzn0000644000175000017500000000041714536677021024145 0ustar kaolkaolinclude "lex_lesseq.mzn"; predicate fzn_lex_chain_lesseq_bool(array[int, int] of var bool: a) = let { set of int: is2 = index_set_2of2(a); } in ( forall(j in is2 where j+1 in is2) ( lex_lesseq(col(a, j), col(a, j+1)) ) ); libminizinc-2.8.2/share/minizinc/std/lex_lesseq_int.mzn.deprecated.mzn0000644000175000017500000000074014536677021024666 0ustar kaolkaolpredicate lex_lesseq_int(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); predicate lex_leq_int(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_among.mzn0000644000175000017500000000017314536677021020724 0ustar kaolkaolpredicate fzn_among(var int: n, array[int] of var int: x, set of int: v) = n == sum(i in index_set(x)) ( x[i] in v ); libminizinc-2.8.2/share/minizinc/std/at_least.mzn.deprecated.mzn0000644000175000017500000000023314536677021023441 0ustar kaolkaolpredicate at_least(int: n, array[$X] of var $$E: x, $$E: v) ::mzn_deprecated("2.4.0","https://www.minizinc.org/doc-2.4.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_path_int.mzn0000644000175000017500000000134114536677021021427 0ustar kaolkaolinclude "tree.mzn"; include "subgraph.mzn"; predicate fzn_path(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: s, var int: t, array[int] of var bool: ns, array[int] of var bool: es) = let { array[1..2*E] of int: dfrom = from ++ to; array[1..2*E] of int: dto = to ++ from; array[1..2*E] of var bool: des; } in /* ensure that the directed edges selected agree with undirected edges */ forall(e in 1..E)(es[e] <-> (des[e] \/ des[e+E])) /\ /* duplicate the edges so that the we can use directed graph path */ fzn_dpath(N,2*E,dfrom,dto,s,t,ns,des); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/exactly.mzn.deprecated.mzn0000644000175000017500000000023214536677021023315 0ustar kaolkaolpredicate exactly(int: n, array[$X] of var $$E: x, $$E: v) ::mzn_deprecated("2.4.0","https://www.minizinc.org/doc-2.4.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/all_different_int.mzn0000644000175000017500000000060214536677021022413 0ustar kaolkaolinclude "fzn_all_different_int.mzn"; include "fzn_all_different_int_reif.mzn"; %-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all different. %-----------------------------------------------------------------------------% predicate all_different_int(array[int] of var int: x) = fzn_all_different_int(x); libminizinc-2.8.2/share/minizinc/std/fzn_writes.mzn0000644000175000017500000000063314536677021021141 0ustar kaolkaolpredicate fzn_writes(array[int] of var int: I, array[int] of var int: P, array[int] of var int: V, array[int] of var int: O) = forall(j in index_set(P))(O[P[j]] = V[j]) /\ forall(i in index_set(I)) (if forall(j in index_set(P))(P[j] != i) then O[i] = I[i] else true endif); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_lex_lesseq_int.mzn0000644000175000017500000000111414536677021022635 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_lesseq_int(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) = lex_lesseq_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/experimental.mzn0000644000175000017500000000241114536677021021440 0ustar kaolkaol%-----------------------------------------------------------------------------% % MiniZinc standard library. % Experimental stuff. %-----------------------------------------------------------------------------% % This file contains declarations of all functions, predicates and annotations % available in the base MiniZinc language. /*** @groupdef MAIN The MiniZinc library */ /*** @groupdef annotations.multiobj-experimental Multiobjective annotations */ /** @group annotations.multiobj-experimental Sequentially (lexicographically) optimize objectives specified in array \a s. The \a goal_hierarchy annotation is to be attached to the solve item, for example: \code solve :: goal_hierarchy([int_min_goal(load[1]), int_min_goal(load[2]), int_min_goal(load[3])]) satisfy; \endcode */ annotation goal_hierarchy(array[int] of ann); /** @group annotations.multiobj-experimental Possible arguments of the \a goal_hierarchy annotation */ annotation min_goal(var int: x); annotation min_goal(var float: x); annotation int_min_goal(var int: x); annotation float_min_goal(var float: x); annotation max_goal(var int: x); annotation max_goal(var float: x); annotation int_max_goal(var int: x); annotation float_max_goal(var float: x); annotation sat_goal(var bool: b); libminizinc-2.8.2/share/minizinc/std/fzn_int_set_channel_reif.mzn0000644000175000017500000000073314536677021023767 0ustar kaolkaolpredicate fzn_int_set_channel_reif(array[int] of var int: x, array[int] of var set of int: y, var bool: b) = b <-> ( forall(i in index_set(x)) (x[i] in index_set(y)) /\ forall(j in index_set(y)) (y[j] subset index_set(x)) /\ forall(i in index_set(x), j in index_set(y)) (x[i] = j <-> i in y[j]) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_roots_reif.mzn0000644000175000017500000000056514536677021022003 0ustar kaolkaolpredicate fzn_roots_reif(array[int] of var int: x, var set of int: s, var set of int: t, var bool: b) = b <-> ( % All values in 's' must map to a value in 't'. forall(i in ub(s)) ( i in s -> x[i] in t ) /\ forall(i in ub(t)) ( i in t -> forall(j in index_set(x)) (x[j] = i -> j in s ) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_arg_min_float_opt.mzn0000644000175000017500000000033614536677021023307 0ustar kaolkaolinclude "arg_min.mzn"; predicate fzn_minimum_arg_float_opt(array[int] of var opt float: x, var int: z) = let { float: def = ub_array(x) + 1; } in minimum_arg(array1d(index_set(x), [xi default def | xi in x]), z); libminizinc-2.8.2/share/minizinc/std/fzn_seq_precede_chain_set.mzn0000644000175000017500000000110514536677021024113 0ustar kaolkaolpredicate fzn_seq_precede_chain_set(array[int] of var set of int: X) = if length(X) = 0 then true else let { set of int: S = ub_array(X); % set of possible values int : l = min (S) ; % least possible value int : u = max (S) ; % greatest possible value int : f = min ( index_set (X )); array [ index_set (X) ] of var l .. u: H; } in H[f] <= 1 /\ H[f] = max (X[f] union {0}) /\ forall ( i in index_set (X) diff {f} ) ( H[i] <= H[i-1] + 1 /\ H[i] = max (max(X[i]), H[i-1]) ) endif; libminizinc-2.8.2/share/minizinc/std/strict_lex2.mzn0000644000175000017500000000051414536677021021207 0ustar kaolkaolinclude "fzn_strict_lex2.mzn"; include "fzn_strict_lex2_reif.mzn"; /** @group globals.lexicographic Requires adjacent rows and adjacent columns in the array \a x to be lexicographically ordered. Adjacent rows and adjacent columns cannot be equal. */ predicate strict_lex2(array[int, int] of var int: x) = fzn_strict_lex2(x); libminizinc-2.8.2/share/minizinc/std/fzn_dag.mzn0000644000175000017500000000116314536677021020356 0ustar kaolkaolpredicate fzn_dag(array[int] of $$N: from, array[int] of $$N: to, array[$$N] of var bool: ns, array[int] of var bool: es) = let { set of int: EDGE = index_set(es); array[index_set(ns)] of var 0..length(ns)-1: dist; /* distance of longest path */ } in forall(n in index_set(ns))(not ns[n] -> dist[n] = 0) /\ forall(e in EDGE) (es[e] -> dist[from[e]] + 1 <= dist[to[e]]) /\ % redundant constraint to ensure all distances are fixed forall(n in index_set(ns)) (dist[n] = max( [0] ++ [ (dist[from[e]] + 1)*es[e] | e in EDGE where to[e] = n ])) ; libminizinc-2.8.2/share/minizinc/std/fzn_count_eq_par_reif.mzn0000644000175000017500000000035414536677021023310 0ustar kaolkaolinclude "fzn_count_eq_reif.mzn"; predicate fzn_count_eq_par_reif(array[int] of var int: x, int: y, int: c, var bool: b) = fzn_count_eq_reif(x,y,c,b); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_strictly_increasing_bool_reif.mzn0000644000175000017500000000060314536677021025720 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in strict increasing order %-----------------------------------------------------------------------------% predicate fzn_strictly_increasing_bool_reif(array[int] of var bool: x, var bool: b) = b <-> forall(i in index_set(x) diff { min(index_set(x)) }) (x[i-1] < x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_tree_int.mzn0000644000175000017500000000130614536677021021433 0ustar kaolkaolinclude "subgraph.mzn"; predicate fzn_tree(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: r, array[int] of var bool: ns, array[int] of var bool: es) = let { array[1..2*E] of int: dfrom = from ++ to; array[1..2*E] of int: dto = to ++ from; array[1..2*E] of var bool: des; } in /* ensure that the directed edges selected agree with undirected edges */ forall(e in 1..E)(es[e] <-> (des[e] \/ des[e+E])) /\ /* duplicate the edges so that the we can use directed graph reachability */ fzn_dtree(N,2*E,dfrom,dto,r,ns,des); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_bin_packing.mzn0000644000175000017500000000063614536677021022073 0ustar kaolkaolpredicate fzn_bin_packing(int: c, array[int] of var int: bin, array[int] of int: w) = let { int: all_weight = sum(w) } in forall( b in lb_array(bin)..ub_array(bin) ) ( sum(i in index_set(bin)) ( w[i] * (bin[i] != b) ) >= (all_weight - c) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/at_most_set.mzn0000644000175000017500000000062714536677021021273 0ustar kaolkaolinclude "fzn_at_most_set.mzn"; include "fzn_at_most_set_reif.mzn"; %-----------------------------------------------------------------------------% % Requires at most 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate at_most_set(int: n, array[$X] of var set of $$E: x, set of $$E: v) = fzn_at_most_set(n, array1d(x), v); libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_low_up_opt.mzn0000644000175000017500000000100614536677021025711 0ustar kaolkaolinclude "global_cardinality.mzn"; predicate fzn_global_cardinality_low_up_opt(array[int] of var opt int: x, array[int] of int: cover, array[int] of int: lbound, array[int] of int: ubound) = let { % Set <> to something outside the cover int: def = if 0 in cover then min(cover) - 1 else 0 endif; } in global_cardinality([x_i default def | x_i in x], cover, lbound, ubound); libminizinc-2.8.2/share/minizinc/std/decreasing_int.mzn.deprecated.mzn0000644000175000017500000000022114536677021024620 0ustar kaolkaolpredicate decreasing_int(array[$X] of var int: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_dwst.mzn0000644000175000017500000000064114536677021020604 0ustar kaolkaolinclude "tree.mzn"; predicate fzn_dwst(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, var int: r, array[int] of var bool: es, var int: K) = let { array[1..N] of bool: ns = [true | n in 1..N]; } in dtree(N,E,from,to,r,ns,es) /\ K = sum(e in 1..E)(es[e]*w[e]); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/decreasing_float.mzn0000644000175000017500000000063114536677021022236 0ustar kaolkaolinclude "fzn_decreasing_float.mzn"; include "fzn_decreasing_float_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is in decreasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate decreasing_float(array[$X] of var float: x) = fzn_decreasing_float(array1d(x)); libminizinc-2.8.2/share/minizinc/std/fzn_count_lt_par_reif.mzn0000644000175000017500000000035214536677021023320 0ustar kaolkaolinclude "fzn_count_lt_reif.mzn"; predicate fzn_count_lt_par_reif(array[int] of var int: x, int: y, int: c, var bool: b) = fzn_count_lt_reif(x,y,c,b); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/value_precede_chain_int.mzn0000644000175000017500000000032714536677021023566 0ustar kaolkaolinclude "fzn_value_precede_chain_int.mzn"; include "fzn_value_precede_chain_int_reif.mzn"; predicate value_precede_chain_int(array[int] of int: c, array[int] of var int: x) = fzn_value_precede_chain_int(c, x); libminizinc-2.8.2/share/minizinc/std/lex2_strict.mzn0000644000175000017500000000051314536677021021206 0ustar kaolkaolinclude "fzn_strict_lex2.mzn"; include "fzn_strict_lex2_reif.mzn"; /** @group globals.lexicographic Require adjacent rows and adjacent columns in the array \a x to be lexicographically ordered. Adjacent rows and adjacent columns cannot be equal. */ predicate lex2_strict(array[int, int] of var int: x) = fzn_strict_lex2(x); libminizinc-2.8.2/share/minizinc/std/arg_val.mzn0000644000175000017500000001571214536677021020366 0ustar kaolkaolinclude "fzn_arg_val_bool.mzn"; include "fzn_arg_val_bool_opt.mzn"; include "fzn_arg_val_float.mzn"; include "fzn_arg_val_float_opt.mzn"; include "fzn_arg_val_int.mzn"; include "fzn_arg_val_int_opt.mzn"; /** @group globals.math Returns the index of the value \a v in the array \a x. When breaking ties the least index is returned. Note that this function forces the value \a v to occur in \a x. */ function var $$E: arg_val(array [$$E] of var bool: x, var bool: v) = let { constraint length(x) > 0; } in arg_val_total(x, v); function var $$E: arg_val_total(array [$$E] of var bool: x, var bool: v) :: promise_total = if length(x) = 0 then min(index_set(x)) else let { var index_set(x): i; constraint fzn_arg_val_bool(x, v, i); } in i endif; /** @group globals.math Returns the index of the value \a v in the array \a x when \a v. When breaking ties the least index is returned. Returns absent when \a v does not occur in \a x. */ function var opt $$E: arg_val_weak(array[$$E] of var bool: x, var bool: v) :: promise_total = if length(x) = 0 then <> else let { set of int: idx = min(index_set(x))..max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [v]); var idx: i; var opt index_set(x): ii = if i in index_set(x) then i else <> endif; constraint fzn_arg_val_bool(xx, v, i); } in ii endif; /** @group globals.math Returns the index of the value \a v in the array \a x. When breaking ties the least index is returned. Note that this function forces the value \a v to occur in \a x. */ function var $$E: arg_val(array [$$E] of var opt bool: x, var opt bool: v) = let { constraint length(x) > 0; } in arg_val_total(x, v); function var $$E: arg_val_total(array [$$E] of var opt bool: x, var opt bool: v) :: promise_total = if length(x) = 0 then min(index_set(x)) else let { var index_set(x): i; constraint fzn_arg_val_bool_opt(x, v, i); } in i endif; /** @group globals.math Returns the index of the value \a v in the array \a x when \a v. When breaking ties the least index is returned. Returns absent when \a v does not occur in \a x. */ function var opt $$E: arg_val_weak(array[$$E] of var opt bool: x, var opt bool: v) :: promise_total = if length(x) = 0 then <> else let { set of int: idx = min(index_set(x))..max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [v]); var idx: i; var opt index_set(x): ii = if i in index_set(x) then i else <> endif; constraint fzn_arg_val_bool_opt(xx, v, i); } in ii endif; /** @group globals.math Returns the index of the value \a v in the array \a x. When breaking ties the least index is returned. Note that this function forces the value \a v to occur in \a x. */ function var $$E: arg_val(array [$$E] of var float: x, var float: v) = let { constraint length(x) > 0; } in arg_val_total(x, v); function var $$E: arg_val_total(array [$$E] of var float: x, var float: v) :: promise_total = if length(x) = 0 then min(index_set(x)) else let { var index_set(x): i; constraint fzn_arg_val_float(x, v, i); } in i endif; /** @group globals.math Returns the index of the value \a v in the array \a x when \a v. When breaking ties the least index is returned. Returns absent when \a v does not occur in \a x. */ function var opt $$E: arg_val_weak(array[$$E] of var float: x, var float: v) :: promise_total = if length(x) = 0 then <> else let { set of int: idx = min(index_set(x))..max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [v]); var idx: i; var opt index_set(x): ii = if i in index_set(x) then i else <> endif; constraint fzn_arg_val_float(xx, v, i); } in ii endif; /** @group globals.math Returns the index of the value \a v in the array \a x. When breaking ties the least index is returned. Note that this function forces the value \a v to occur in \a x. */ function var $$E: arg_val(array [$$E] of var opt float: x, var float: v) = let { constraint length(x) > 0; } in arg_val_total(x, v); function var $$E: arg_val_total(array [$$E] of var opt float: x, var opt float: v) :: promise_total = if length(x) = 0 then min(index_set(x)) else let { var index_set(x): i; constraint fzn_arg_val_float_opt(x, v, i); } in i endif; /** @group globals.math Returns the index of the value \a v in the array \a x when \a v. When breaking ties the least index is returned. Returns absent when \a v does not occur in \a x. */ function var opt $$E: arg_val_weak(array[$$E] of var opt float: x, var opt float: v) :: promise_total = if length(x) = 0 then <> else let { set of int: idx = min(index_set(x))..max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [v]); var idx: i; var opt index_set(x): ii = if i in index_set(x) then i else <> endif; constraint fzn_arg_val_float_opt(xx, v, i); } in ii endif; /** @group globals.math Returns the index of the value \a v in the array \a x. When breaking ties the least index is returned. Note that this function forces the value \a v to occur in \a x. */ function var $$E: arg_val(array [$$E] of var $$V: x, var $$V: v) = let { constraint length(x) > 0; } in arg_val_total(x, v); function var $$E: arg_val_total(array [$$E] of var $$V: x, var $$V: v) :: promise_total = if length(x) = 0 then min(index_set(x)) else let { var index_set(x): i; constraint fzn_arg_val_int(x, v, i); } in i endif; /** @group globals.math Returns the index of the value \a v in the array \a x when \a v. When breaking ties the least index is returned. Returns absent when \a v does not occur in \a x. */ function var opt $$E: arg_val_weak(array [$$E] of var $$V: x, var $$V: v) :: promise_total = if length(x) = 0 then <> else let { set of int: idx = min(index_set(x))..max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [v]); var idx: i; var opt index_set(x): ii = if i in index_set(x) then i else <> endif; constraint fzn_arg_val_int(xx, v, i); } in ii endif; /** @group globals.math Returns the index of the value \a v in the array \a x. When breaking ties the least index is returned. Note that this function forces the value \a v to occur in \a x. */ function var $$E: arg_val(array [$$E] of var opt $$V: x, var opt $$V: v) = let { constraint length(x) > 0; } in arg_val_total(x, v); function var $$E: arg_val_total(array [$$E] of var opt $$V: x, var opt $$V: v) :: promise_total = if length(x) = 0 then min(index_set(x)) else let { var index_set(x): i; constraint fzn_arg_val_int_opt(x, v, i); } in i endif; /** @group globals.math Returns the index of the value \a v in the array \a x when \a v. When breaking ties the least index is returned. Returns absent when \a v does not occur in \a x. */ function var opt $$E: arg_val_weak(array [$$E] of var opt $$V: x, var opt $$V: v) :: promise_total = if length(x) = 0 then <> else let { set of int: idx = min(index_set(x))..max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [v]); var idx: i; var opt index_set(x): ii = if i in index_set(x) then i else <> endif; constraint fzn_arg_val_int_opt(xx, v, i); } in ii endif; libminizinc-2.8.2/share/minizinc/std/fzn_arg_val_bool.mzn0000644000175000017500000000036214536677021022251 0ustar kaolkaolinclude "fzn_arg_max_bool.mzn"; include "fzn_arg_min_bool.mzn"; predicate fzn_arg_val_bool(array[int] of var bool: x, var bool: v, var int: i) = if v then fzn_maximum_arg_bool(x, i) else fzn_minimum_arg_bool(x, i) endif /\ x[i] = v; libminizinc-2.8.2/share/minizinc/std/table_int.mzn0000644000175000017500000000104214536677021020703 0ustar kaolkaolinclude "fzn_table_int.mzn"; include "fzn_table_int_reif.mzn"; %-----------------------------------------------------------------------------% % A table constraint table(x, t) represents the constraint x in t where we % consider each row in t to be a tuple and t as a set of tuples. %-----------------------------------------------------------------------------% predicate table_int( array[$$E] of var int: x, array[int, $$E] of int: t ) = fzn_table_int(x, t); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_low_up_closed_set.mzn0000644000175000017500000000071114536677021027235 0ustar kaolkaolinclude "global_cardinality.mzn"; predicate fzn_global_cardinality_low_up_closed_set(array[int] of var set of int: x, array[int] of int: cover, array[int] of int: lbound, array[int] of int: ubound) = global_cardinality(x, cover, lbound, ubound) /\ forall (v in x) (v subset { d | d in cover }); libminizinc-2.8.2/share/minizinc/std/fzn_cost_mdd.mzn0000644000175000017500000000573614536677021021431 0ustar kaolkaolpredicate fzn_cost_mdd(array[int] of var int: x, % variables constrained by MDD int: N, % number of nodes root is node 1 array[int] of int: level, % level of each node root is level 1, T is level length(x)+1 int: E, % number of edges array[int] of int: from, % edge leaving node 1..N array[int] of set of int: label, % values of variable on edge array[int] of int: cost, % cost of using edge array[int] of int: to, % edge entering node 0..N where 0 = T node var int: totalcost % total cost of path ) = let { set of int: NODE = 1..N; set of int: EDGE = 1..E; int: L = length(x); array[1..L] of int: maxlevelcost = [ max(e in EDGE where level[from[e]] = l)(cost[e]) | l in 1..L]; array[1..L] of int: minlevelcost = [ min([0] ++ [ cost[e] | e in EDGE where level[from[e]] = l /\ cost[e] < 0])| l in 1..L] ; int: maxcost = sum(maxlevelcost); set of int: COST = sum(minlevelcost)..L*(maxcost+1); array[0..N] of var bool: bn; array[EDGE] of var bool: be; array[0..N] of var COST: ln; % distance from T array[0..N] of var COST: un; % distance from root } in bn[0] /\ % true node is true bn[1] /\ % root must hold % T1 each node except the root enforces an outgoing edge forall(n in NODE)(bn[n] -> exists(e in EDGE where from[e] = n)(be[e])) /\ % T23 each edge enforces its endpoints forall(e in EDGE)((be[e] -> bn[to[e]]) /\ (be[e] -> bn[to[e]])) /\ % T4 each edge enforces its label forall(e in EDGE)(be[e] -> x[level[from[e]]] in label[e]) /\ % P1 each node enforces its outgoing edges forall(e in EDGE)(bn[from[e]] /\ x[level[from[e]]] in label[e] -> be[e]) /\ % P2 each node except the root enforces an incoming edge exists(e in EDGE where to[e] = 0)(be[e]) /\ forall(n in 2..N)(bn[n] -> exists(e in EDGE where to[e] = n)(be[e])) /\ % P3 each label has a support forall(i in 1..L, d in dom(x[i])) (x[i] = d -> exists(e in EDGE where level[from[e]] = i /\ d in label[e])(be[e])) /\ % P4 exactly one node at each level forall(i in 1..L) (sum(n in NODE where level[n] = i)(bn[n]) = 1) /\ ln[0] = 0 /\ un[1] = 0 /\ forall(n in NODE) (ln[n] = min(e in EDGE where from[e] = n)(ln[to[e]] + cost[e] + (not be[e])*(maxcost+1 - cost[e]))) /\ forall(n in 2..N) (un[n] = min(e in EDGE where to[e] = n)(un[from[e]] + cost[e] + (not be[e])*(maxcost+1 - cost[e]))) /\ forall(e in EDGE)(be[e] -> un[from[e]] + cost[e] + ln[to[e]] <= maxcost) /\ totalcost = ln[1]; libminizinc-2.8.2/share/minizinc/std/fzn_count_lt.mzn0000644000175000017500000000054614536677021021456 0ustar kaolkaolinclude "count_fn.mzn"; predicate fzn_count_lt(array[int] of var int: x, var int: y, var int: c) = let { var int: z = count(x,y) } in z > c; % This needs to be written with a let rather than count(x,y) > c % so that the automatic rewriting of the latter doesn't kick in %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/all_different_except.mzn0000644000175000017500000000076714536677021023125 0ustar kaolkaolinclude "fzn_alldifferent_except.mzn"; include "fzn_alldifferent_except_reif.mzn"; /** @group globals.alldifferent Constrain the elements of the array of integers \a vs to be pairwise different except for those values that appear in the set \a S. */ predicate all_different_except(array[$X] of var int: vs, set of int: S) = fzn_alldifferent_except(array1d(vs),S); % Synonym for the above. predicate alldifferent_except(array[$X] of var int: vs, set of int: S) = all_different_except(vs, S); libminizinc-2.8.2/share/minizinc/std/fzn_sum_pred.mzn0000644000175000017500000000040014536677021021432 0ustar kaolkaolpredicate fzn_sum_pred(var int: i, array[int] of set of int: sets, array[int] of int: cs, var int: s) = let { array[index_set(sets)] of int: sums = [ sum(k in sets[j])(cs[k]) | j in index_set(sets) ]; } in sums[i] = s; libminizinc-2.8.2/share/minizinc/std/span.mzn0000644000175000017500000000072314536677021017710 0ustar kaolkaolinclude "fzn_span.mzn"; include "fzn_span_reif.mzn"; /** @group globals.scheduling Span constraint for optional tasks. Task (\a s0,\a d0) spans the optional tasks (\a s[\p i],\a d[\p i]) in the array arguments. */ predicate span( var opt int: s0, var int: d0, array[$$E] of var opt int: s, array[$$E] of var int: d ) = assert( index_set(s) = index_set(d), "span: index sets of third and fourth argument must be identical", ) /\ fzn_span(s0, d0, s, d); libminizinc-2.8.2/share/minizinc/std/fzn_arg_sort_float.mzn0000644000175000017500000000041614536677021022630 0ustar kaolkaolinclude "all_different.mzn"; predicate fzn_arg_sort_float(array[int] of var float:x, array[int] of var int:p) = all_different(p) /\ forall(j in 1..length(x)-1) (x[p[j]] <= x[p[j+1]] /\ (x[p[j]] == x[p[j+1]] -> p[j] < p[j+1])); libminizinc-2.8.2/share/minizinc/std/lex_lesseq_bool.mzn.deprecated.mzn0000644000175000017500000000075114536677021025031 0ustar kaolkaol predicate lex_lesseq_bool(array[int] of var bool: x ::promise_ctx_antitone, array[int] of var bool: y ::promise_ctx_monotone) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); predicate lex_leq_bool(array[int] of var bool: x ::promise_ctx_antitone, array[int] of var bool: y ::promise_ctx_monotone) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_disjunctive_strict_reif.mzn0000644000175000017500000000054514536677021024552 0ustar kaolkaolpredicate fzn_disjunctive_strict_reif(array[int] of var int: s, array[int] of var int: d, var bool: b) = b <-> ( forall (i in index_set(d)) (d[i] >= 0) /\ forall (i,j in index_set(d) where i.mzn include "flatzinc_builtins.mzn"; /*** @groupdef stdlib Standard Library These functions and predicates define built-in operations of the MiniZinc language. */ /*** @groupdef stdlib.builtins Built-in functions and operators These functions and operators provide the core of the MiniZinc expression language. */ include "stdlib/stdlib_compare.mzn"; include "stdlib/stdlib_math.mzn"; include "stdlib/stdlib_coercion.mzn"; include "stdlib/stdlib_array.mzn"; include "stdlib/stdlib_logic.mzn"; include "stdlib/stdlib_set.mzn"; include "stdlib/stdlib_string.mzn"; include "stdlib/stdlib_enum.mzn"; include "stdlib/stdlib_ann.mzn"; include "stdlib/stdlib_opt.mzn"; include "stdlib/stdlib_sort.mzn"; include "stdlib/stdlib_language.mzn"; include "stdlib/stdlib_ite.mzn"; include "stdlib/stdlib_reflect.mzn"; include "stdlib/stdlib_debug.mzn"; include "stdlib/stdlib_random.mzn"; include "output.mzn"; /*** @groupdef globals Global constraints These constraints represent high-level modelling abstractions. Many solvers implement dedicated, efficient inference algorithms for these constraints, or provide a MiniZinc library decomposition that is better suited to the particular solving technology than the standard library decomposition. */ % Undocumented internal implementation used during compilation include "stdlib/stdlib_internal.mzn"; libminizinc-2.8.2/share/minizinc/std/connected.mzn0000644000175000017500000000406414536677021020713 0ustar kaolkaolinclude "fzn_connected.mzn"; include "fzn_connected_reif.mzn"; include "fzn_dconnected.mzn"; include "fzn_dconnected_reif.mzn"; /** @group globals.graph Constrains the subgraph \a ns and \a es of a given directed graph to be connected. @param from: the leaving node for each edge @param to: the entering node for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate dconnected(array[$$E] of $$N: from, array[$$E] of $$N: to, array[$$N] of var bool: ns, array[$$E] of var bool: es) = assert(index_set(from) = index_set(to),"dconnected: index set of from and to must be identical") /\ assert(index_set(from) = index_set(es),"dconnected: index set of from and es must be identical") /\ assert(dom_array(from) subset index_set(ns),"dconnected: nodes in from must be in index set of ns") /\ assert(dom_array(to) subset index_set(ns),"dconnected: nodes in to must be in index set of ns") /\ fzn_dconnected(from,to,ns,es); %-----------------------------------------------------------------------------% /** @group globals.graph Constrains the subgraph \a ns and \a es of a given undirected graph to be connected. @param from: is the leaving node for each edge @param to: is the entering node for each edge @param ns: is a Boolean for each node whether it is in the subgraph @param es: is a Boolean for each edge whether it is in the subgraph */ predicate connected(array[$$E] of $$N: from, array[$$E] of $$N: to, array[$$N] of var bool: ns, array[$$E] of var bool: es) = assert(index_set(from) = index_set(to),"connected: index set of from and to must be identical") /\ assert(index_set(from) = index_set(es),"connected: index set of from and es must be identical") /\ assert(dom_array(from) subset index_set(ns),"connected: nodes in from must be in index set of ns") /\ assert(dom_array(to) subset index_set(ns),"connected: nodes in to must be in index set of ns") /\ fzn_connected(from,to,ns,es); libminizinc-2.8.2/share/minizinc/std/fzn_lex_less_set.mzn0000644000175000017500000000104214536677021022310 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than array 'y'. % Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_less_set(array[int] of var set of int: x, array[int] of var set of int: y) = lex_less_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_int.mzn0000644000175000017500000000055414536677021023124 0ustar kaolkaolpredicate fzn_if_then_else_int(array[int] of var bool: c, array[int] of int: x, var int: y) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_regular_set.mzn.deprecated.mzn0000644000175000017500000000034014536677021025035 0ustar kaolkaolpredicate fzn_regular( array[int] of var int: x, int: Q, set of int: S, array[int,int] of int: d, int: q0, set of int: F ) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_value_precede_int_opt.mzn0000644000175000017500000000035714536677021024166 0ustar kaolkaolinclude "value_precede.mzn"; predicate fzn_value_precede_int_opt(int: s, int: t, array[int] of var opt int: x) = let { int: def = if had_zero(x) then max(s, t) + 1 else 0 endif; } in value_precede(s, t, [y default def | y in x]); libminizinc-2.8.2/share/minizinc/std/fzn_strictly_increasing_int.mzn0000644000175000017500000000055114536677021024554 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in strict increasing order %-----------------------------------------------------------------------------% predicate fzn_strictly_increasing_int(array[int] of var int: x) = forall(i in index_set(x) diff { min(index_set(x)) }) (x[i-1] < x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_increasing_float_opt_reif.mzn0000644000175000017500000000130714536677021025021 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order iff b is true %-----------------------------------------------------------------------------% predicate fzn_increasing_float_opt_reif(array[int] of var opt float: x, var bool: b) = let { array[int] of var opt float: xx = array1d(x); array[1..length(xx)] of var float: y; constraint forall(i in 1..length(xx)) ( y[i] = if occurs(xx[i]) then deopt(xx[i]) elseif i = 1 then lb_array(xx) else y[i-1] endif ); } in b <-> forall (i in 2..length(y) where occurs(xx[i])) ( deopt(xx[i]) >= y[i-1] ); libminizinc-2.8.2/share/minizinc/std/range_fn.mzn0000644000175000017500000000071414536677021020526 0ustar kaolkaolinclude "range.mzn"; /** @group globals.math Returns the image of function \a x (represented as an array) on set of values \a s. ub(\a s) must be a subset of index_set(\a x) otherwise an assertion failure will occur. */ function var set of int: range(array[int] of var int: x, var set of int: s) ::promise_total = let { var set of lb_array(x)..ub_array(x): t ::is_defined_var; constraint range(x,s,t) ::defines_var(t); } in t; libminizinc-2.8.2/share/minizinc/std/lex_lesseq_set.mzn.deprecated.mzn0000644000175000017500000000064014536677021024666 0ustar kaolkaolpredicate lex_lesseq_set(array[int] of var set of int: x, array[int] of var set of int: y) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); predicate lex_leq_set(array[int] of var set of int: x, array[int] of var set of int: y) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/disjunctive.mzn0000644000175000017500000000132314536677021021273 0ustar kaolkaolinclude "disjunctive_strict.mzn"; include "fzn_disjunctive.mzn"; include "fzn_disjunctive_reif.mzn"; /** @group globals.scheduling Requires that a set of tasks given by start times \a s and durations \a d do not overlap in time. Tasks with duration 0 can be scheduled at any time, even in the middle of other tasks. Assumptions: - forall \p i, \a d[\p i] >= 0 */ predicate disjunctive(array[$$T] of var int: s, array[$$T] of var int: d) = assert(index_set(s) == index_set(d), "disjunctive: the array arguments must have identical index sets", if (lb_array(d) > 0) then disjunctive_strict(s,d) else fzn_disjunctive(s,d) endif ); libminizinc-2.8.2/share/minizinc/std/increasing_float.mzn.deprecated.mzn0000644000175000017500000000022514536677021025155 0ustar kaolkaolpredicate increasing_float(array[$X] of var float: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/arg_max_float.mzn0000644000175000017500000000020614536677021021546 0ustar kaolkaolinclude "fzn_arg_max_float.mzn"; predicate maximum_arg_float(array[$$E] of var float: x, var $$E: i) = fzn_maximum_arg_float(x, i); libminizinc-2.8.2/share/minizinc/std/inverse.mzn0000644000175000017500000000126714536677021020426 0ustar kaolkaolinclude "fzn_inverse.mzn"; include "fzn_inverse_opt.mzn"; include "fzn_inverse_reif.mzn"; include "analyse_all_different.mzn"; /** @group globals.channeling Constrains two arrays of int variables, \a f and \a invf, to represent inverse functions. All the values in each array must be within the index set of the other array. */ predicate inverse( array[$$X] of var $$Y: f, array[$$Y] of var $$X: invf ) = analyse_all_different(f) /\ analyse_all_different(invf) /\ fzn_inverse(f, invf); predicate inverse(array[$$X] of var opt $$Y: f, array[$$Y] of var opt $$X: invf ) = analyse_all_different(f) /\ analyse_all_different(invf) /\ fzn_inverse_opt(f, invf); libminizinc-2.8.2/share/minizinc/std/disjunctive_opt.mzn0000644000175000017500000000156214536677021022162 0ustar kaolkaolinclude "disjunctive_strict_opt.mzn"; include "fzn_disjunctive_opt.mzn"; include "fzn_disjunctive_opt_reif.mzn"; /** @group globals.scheduling Requires that a set of tasks given by start times \a s and durations \a d do not overlap in time. Tasks with duration 0 can be scheduled at any time, even in the middle of other tasks. Start times are optional variables, so that absent tasks do not need to be scheduled. Assumptions: - forall \p i, \a d[\p i] >= 0 */ predicate disjunctive(array[$$T] of var opt int: s, array[$$T] of var int: d) = assert(index_set(s) == index_set(d), "disjunctive: the array arguments must have identical index sets", forall (i in index_set(d)) (d[i] >= 0) /\ if (lb_array(d) > 0) then disjunctive_strict(s,d) else fzn_disjunctive_opt(s, d) endif ); libminizinc-2.8.2/share/minizinc/std/fzn_geost_nonoverlap_k_reif.mzn0000644000175000017500000000050214536677021024522 0ustar kaolkaolpredicate fzn_geost_nonoverlap_k_reif( array[int] of var int : x1, array[int] of int : w1, array[int] of var int : x2, array[int] of int : w2, var bool: b ) = % Non-overlap constraint b <-> exists(j in index_set(x1))( x1[j] + w1[j] <= x2[j] \/ x2[j] + w2[j] <= x1[j] ); libminizinc-2.8.2/share/minizinc/std/steiner.mzn0000644000175000017500000000572114536677021020423 0ustar kaolkaolinclude "fzn_steiner.mzn"; include "fzn_steiner_reif.mzn"; include "fzn_dsteiner.mzn"; include "fzn_dsteiner_reif.mzn"; include "weighted_spanning_tree.mzn"; /** @group globals.graph Constrains the subgraph \a ns and \a es of a given directed graph to be a weighted spanning tree rooted at \a r of weight \a W. @param N: the number of nodes in the given graph @param E: the number of edges in the given graph @param from: the leaving node 1..\a N for each edge @param to: the entering node 1..\a N for each edge @param w: the weight of each edge @param r: the root node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph @param K: the weight of the tree */ predicate dsteiner(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, var int: r, array[int] of var bool: ns, array[int] of var bool: es, var int: K) = assert(index_set(from) = 1..E,"dsteiner: index set of from must be 1..\(E)") /\ assert(index_set(to) = 1..E,"dsteiner: index set of to must be 1..\(E)") /\ assert(index_set(ns) = 1..N,"dsteiner: index set of ns must be 1..\(N)") /\ assert(index_set(es) = 1..E,"dsteiner: index set of es must be 1..\(E)") /\ assert(index_set(w) = 1..E,"dsteiner: index set of w must be 1..\(E)") /\ if forall(n in 1..N)(is_fixed(ns[n]) /\ fix(ns[n])) then d_weighted_spanning_tree(N,E,from,to,w,r,es,K) else fzn_dsteiner(N,E,from,to,w,r,ns,es,K) endif; /** @group globals.graph Constrains the set of edges \a es of a given undirected graph to be a weighted spanning tree of weight \a W. @param N: the number of nodes in the given graph @param E: the number of edges in the given graph @param from: the leaving node 1..\a N for each edge @param to: the entering node 1..\a N for each edge @param w: the weight of each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph @param K: the weight of the tree **/ predicate steiner(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, array[int] of var bool: ns, array[int] of var bool: es, var int: K) = assert(index_set(from) = 1..E,"steiner: index set of from must be 1..\(E)") /\ assert(index_set(to) = 1..E,"steiner: index set of to must be 1..\(E)") /\ assert(index_set(ns) = 1..N,"steiner: index set of ns must be 1..\(N)") /\ assert(index_set(es) = 1..E,"steiner: index set of es must be 1..\(E)") /\ assert(index_set(w) = 1..E,"steiner: index set of w must be 1..\(E)") /\ if forall(n in 1..N)(is_fixed(ns[n]) /\ fix(ns[n])) then weighted_spanning_tree(N,E,from,to,w,es,K) else fzn_steiner(N,E,from,to,w,ns,es,K) endif; %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/increasing_set.mzn0000644000175000017500000000062614536677021021746 0ustar kaolkaolinclude "fzn_increasing_set.mzn"; include "fzn_increasing_set_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate increasing_set(array[$X] of var set of int: x) = fzn_increasing_set(array1d(x)); libminizinc-2.8.2/share/minizinc/std/fzn_arg_val_bool_opt.mzn0000644000175000017500000000027114536677021023132 0ustar kaolkaolinclude "fzn_arg_val_int.mzn"; predicate fzn_arg_val_bool_opt(array[int] of var opt bool: x, var opt bool: v, var int: i) = fzn_arg_val_int([xi default 2 | xi in x], v default 2, i); libminizinc-2.8.2/share/minizinc/std/fzn_count_eq.mzn0000644000175000017500000000031214536677021021433 0ustar kaolkaolpredicate fzn_count_eq(array[int] of var int: x, var int: y, var int: c) = c = sum(i in index_set(x)) ( x[i] == y ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/arg_sort.mzn0000644000175000017500000000362014536677021020566 0ustar kaolkaolinclude "fzn_arg_sort_int.mzn"; include "fzn_arg_sort_float.mzn"; include "analyse_all_different.mzn"; /** @group globals.sort Constrains \a p to be the permutation which causes \a x to be in sorted order hence \a x[\a p[\p i]] <= \a x[\a p[\p i+1]]. The permutation is the stable sort hence \a x[\a p[\p i]] = \a x[\a p[\p i+1]] \(\rightarrow\) \a p[\p i] < \a p[\p i+1]. */ predicate arg_sort( array[$$E] of var int:x, array[int] of var $$E:p, ) = fzn_arg_sort_int(x, p); /** @group globals.sort Constrains \a p to be the permutation which causes \a x to be in sorted order hence \a x[\a p[\p i]] <= \a x[\a p[\p i+1]]. The permutation is the stable sort hence \a x[\a p[\p i]] = \a x[\a p[\p i+1]] \(\rightarrow\) \a p[\p i] < \a p[\p i+1]. */ predicate arg_sort( array[$$E] of var float:x, array[int] of var $$E: p, ) = fzn_arg_sort_float(x, p); /** @group globals.sort Returns the permutation \a p which causes \a x to be in sorted order hence \a x[\a p[\p i]] <= \a x[\a p[\p i+1]]. The permutation is the stable sort hence \a x[\a p[\p i]] = \a x[\a p[\p i+1]] \(\rightarrow\) \a p[\p i] < \a p[\p i+1]. */ function array[int] of var $$E: arg_sort(array[$$E] of var int:x) :: promise_total = if length(x) = 0 then [] else let { array[1..length(x)] of var index_set(x): p; constraint analyse_all_different(p); constraint fzn_arg_sort_int(x, p); } in p endif; /** @group globals.sort Returns the permutation \a p which causes \a x to be in sorted order hence \a x[\a p[\p i]] <= \a x[\a p[\p i+1]]. The permutation is the stable sort hence \a x[\a p[\p i]] = \a x[\a p[\p i+1]] \(\rightarrow\) \a p[\p i] < \a p[\p i+1]. */ function array[int] of var $$E: arg_sort(array[$$E] of var float: x) :: promise_total = if length(x) = 0 then [] else let { array[1..length(x)] of var index_set(x): p; constraint analyse_all_different(p); constraint fzn_arg_sort_float(x, p); } in p endif; libminizinc-2.8.2/share/minizinc/std/fzn_bin_packing_capa.mzn0000644000175000017500000000077714536677021023065 0ustar kaolkaolpredicate fzn_bin_packing_capa(array[int] of int: c, array[int] of var int: bin, array[int] of int: w) = forall( i in index_set(bin) ) ( min(index_set(c)) <= bin[i] /\ bin[i] <= max(index_set(c)) ) /\ forall( b in index_set(c) ) ( c[b] >= sum ( i in index_set(bin) ) ( w[i] * ( bin[i] = b ) ) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_dreachable_enum.mzn0000644000175000017500000000274614536677021022731 0ustar kaolkaolinclude "subgraph.mzn"; predicate fzn_dreachable(array[int] of $$N: from, array[int] of $$N: to, var $$N: r, array[$$N] of var bool: ns, array[int] of var bool: es) = let { array[index_set(ns)] of var 0..card(index_set(ns))-1: dist; /* distance from root */ array[index_set(ns)] of var index_set(ns): parent; /* parent */ } in ns[r] /\ % the root must be chosen dist[r] = 0 /\ % root is at distance 0 parent[r] = r /\ % root is its own parent forall(n in index_set(ns)) % nonselected nodes have parent 0 (not ns[n] -> parent[n] = n) /\ forall(n in index_set(ns)) % nonselected nodes have distance 0 (not ns[n] -> dist[n] = 0) /\ forall(n in index_set(ns)) % each in node except root must have a parent (ns[n] -> (n = r \/ parent[n] != n)) /\ forall(n in index_set(ns)) % each in node with a parent must be in and also its parent (parent[n] != n -> (ns[n] /\ ns[parent[n]])) /\ forall(n in index_set(ns)) % each except with a parent is one more than its parent (parent[n] != n -> dist[n] = dist[parent[n]] + 1) /\ forall(n in index_set(ns)) % each node with a parent must have that edge in (parent[n] != n -> exists(e in index_set(from) where to[e] = n)(es[e] /\ from[e] = parent[n])) /\ subgraph(from,to,ns,es); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_disjunctive_strict_opt_decomp.mzn0000644000175000017500000000060114536677021025747 0ustar kaolkaolpredicate fzn_disjunctive_strict_opt_decomp(array[int] of var opt int: s, array[int] of var int: d) = forall (i in index_set(d)) (d[i] >= 0) /\ forall (i,j in index_set(d) where i min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_partition_set.mzn0000644000175000017500000000033314536677021022505 0ustar kaolkaolinclude "all_disjoint.mzn"; predicate fzn_partition_set(array[int] of var set of int: S, set of int: universe) = all_disjoint(S) /\ universe == array_union(i in index_set(S)) ( S[i] ); libminizinc-2.8.2/share/minizinc/std/diffn_nonstrict.mzn0000644000175000017500000000132014536677021022132 0ustar kaolkaolinclude "fzn_diffn_nonstrict.mzn"; include "fzn_diffn_nonstrict_reif.mzn"; /** @group globals.packing Constrains rectangles \p i, given by their origins (\a x[\p i], \a y[\p i]) and sizes (\a dx[\p i], \a dy[\p i]), to be non-overlapping. Zero-width rectangles can be packed anywhere. */ predicate diffn_nonstrict(array[int] of var int: x, array[int] of var int: y, array[int] of var int: dx, array[int] of var int: dy) = assert( index_set(x) = index_set(y) /\ index_set(x) = index_set(dx) /\ index_set(x) = index_set(dy), "diffn: index set mismatch", fzn_diffn_nonstrict(x,y,dx,dy) ); libminizinc-2.8.2/share/minizinc/std/count_leq.mzn0000644000175000017500000000176614536677021020750 0ustar kaolkaolinclude "fzn_count_leq_par.mzn"; include "fzn_count_leq.mzn"; include "fzn_count_leq_par_reif.mzn"; include "fzn_count_leq_reif.mzn"; /** @group globals.counting Constrains \a c to be less than or equal to the number of occurrences of \a y in \a x. */ predicate count_leq(array[$X] of var $$E: x, var $$E: y, var int: c) = fzn_count_leq(array1d(x), y, c); /** @group globals.counting Constrains \a c to be less than or equal to the number of occurrences of \a y in \a x. */ predicate count_leq(array[$X] of var opt $$E: x, var $$E: y, var int: c) =let { % Set <> to something not y int: def = if 0 in dom(y) then lb(y)-1 else 0 endif; } in count_leq([i default def | i in x], y, c); /** @group globals.counting Constrains \a c to be less than or equal to the number of occurrences of \a y in \a x. */ predicate count_leq(array[$X] of var $$E: x, $$E: y, int: c) = fzn_count_leq_par(array1d(x), y, c); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/diffn_nonstrict_k.mzn0000644000175000017500000000150514536677021022451 0ustar kaolkaolinclude "fzn_diffn_nonstrict_k.mzn"; include "fzn_diffn_nonstrict_k_reif.mzn"; /** @group globals.packing Constrains \p k-dimensional boxes to be non-overlapping. For each box \p i and dimension \p j, \a box_posn[\p i, \p j] is the base position of the box in dimension \p j, and \a box_size[\p i, \p j] is the size in that dimension. Boxes whose size is 0 in at least one dimension can be packed anywhere. */ predicate diffn_nonstrict_k(array[int,int] of var int: box_posn, array[int,int] of var int: box_size) = let { set of int: DIMS= index_set_2of2(box_posn) } in assert(index_set_2of2(box_size) = DIMS /\ index_set_1of2(box_posn) = index_set_1of2(box_size), "diffn: index sets of arguments are incorrect", fzn_diffn_nonstrict_k(box_posn, box_size) ) libminizinc-2.8.2/share/minizinc/std/symmetric_all_different.mzn0000644000175000017500000000064514536677021023644 0ustar kaolkaolinclude "analyse_all_different.mzn"; include "fzn_symmetric_all_different.mzn"; include "fzn_symmetric_all_different_reif.mzn"; /** @group globals.alldifferent Requires the array of integers \a x to be all different, and for all \p i, \a x[\p i]=\p j \(\rightarrow\) \a x[\p j]=\p i. */ predicate symmetric_all_different(array[int] of var int:x) = analyse_all_different(x) /\ fzn_symmetric_all_different(x); libminizinc-2.8.2/share/minizinc/std/all_different_set.mzn0000644000175000017500000000061114536677021022414 0ustar kaolkaolinclude "fzn_all_different_set.mzn"; include "fzn_all_different_set_reif.mzn"; %-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all different. %-----------------------------------------------------------------------------% predicate all_different_set(array[int] of var set of int: x) = fzn_all_different_set(x); libminizinc-2.8.2/share/minizinc/std/fzn_cost_mdd_reif.mzn0000644000175000017500000000156714536677021022434 0ustar kaolkaolpredicate fzn_cost_mdd_reif(array[int] of var int: x, % variables constrained by MDD int: N, % number of nodes root is node 1 array[int] of int: level, % level of each node root is level 1, T is level length(x)+1 int: E, % number of edges array[int] of int: from, % edge leaving node 1..N array[int] of set of int: label, % values of variable on edge array[int] of int: cost, % cost of using edge array[int] of int: to, % edge entering node 0..N where 0 = T node var int: totalcost, % total cost of path var bool: b % reification variable ) = abort("Reified cost_mdd/9 is not supported."); libminizinc-2.8.2/share/minizinc/std/fzn_bounded_path_enum_reif.mzn0000644000175000017500000000053214536677021024307 0ustar kaolkaolinclude "path.mzn"; predicate fzn_bounded_path_reif(array[int] of $$N: from, array[int] of $$N: to, array[int] of int: w, var $$N: s, var $$N: t, array[$$N] of var bool: ns, array[int] of var bool: es, var int: K, var bool: b) = b <-> ( path(from,to,s,t,ns,es) /\ K = sum(e in index_set(es))(es[e]*w[e]) ); libminizinc-2.8.2/share/minizinc/std/disjunctive_strict.mzn0000644000175000017500000000117414536677021022667 0ustar kaolkaolinclude "fzn_disjunctive_strict.mzn"; include "fzn_disjunctive_strict_reif.mzn"; /** @group globals.scheduling Requires that a set of tasks given by start times \a s and durations \a d do not overlap in time. Tasks with duration 0 CANNOT be scheduled at any time, but only when no other task is running. Assumptions: - forall \p i, \a d[\p i] >= 0 */ predicate disjunctive_strict(array[$$T] of var int: s, array[$$T] of var int: d) = assert(index_set(s) == index_set(d), "disjunctive: the array arguments must have identical index sets", fzn_disjunctive_strict(s,d) ); libminizinc-2.8.2/share/minizinc/std/fzn_dconnected_reif.mzn0000644000175000017500000000051614536677021022737 0ustar kaolkaolpredicate fzn_dconnected_reif(array[int] of $$N: from, array[int] of $$N: to, array[$$N] of var bool: ns, array[int] of var bool: es, var bool: b) = abort("Reified dconnected is not supported."); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_tree_enum.mzn0000644000175000017500000000131414536677021021604 0ustar kaolkaolpredicate fzn_tree(array[int] of $$N: from, array[int] of $$N: to, var $$N: r, array[$$N] of var bool: ns, array[int] of var bool: es) = let { int: E = length(es); array[1..2*E] of int: dfrom = from ++ to; array[1..2*E] of int: dto = to ++ from; array[1..2*E] of var bool: des; } in /* ensure that the directed edges selected agree with undirected edges */ forall(e in 1..E)(es[e-1+min(index_set(es))] <-> (des[e] \/ des[e+E])) /\ /* duplicate the edges so that the we can use directed graph reachability */ fzn_dtree(dfrom,dto,r,ns,des); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_tree_int_reif.mzn0000644000175000017500000000051414536677021022440 0ustar kaolkaolpredicate fzn_tree_reif(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: r, array[int] of var bool: ns, array[int] of var bool: es, var bool: b) = abort("Reified tree constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/global_cardinality_low_up.deprecated.mzn0000644000175000017500000000054014536677021026253 0ustar kaolkaolpredicate global_cardinality_low_up(array[$X] of var int: x, array[$Y] of int: cover, array[$Y] of int: lbound, array[$Y] of int: ubound) :: mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_steiner_reif.mzn0000644000175000017500000000060614536677021022302 0ustar kaolkaolpredicate fzn_steiner_reif(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, array[int] of var bool: ns, array[int] of var bool: es, var int: K, var bool: b) = abort("Reified steiner constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/roots_fn.mzn0000644000175000017500000000050114536677021020572 0ustar kaolkaolinclude "roots.mzn"; /** @group globals.set Returns \a s such that \a x[\p i] in \a t for all \p i in \a s */ function var set of $$X: roots( array[$$X] of var $$Y: x, var set of $$Y: t, ) :: promise_total = let { var set of index_set(x): s ::is_defined_var; constraint roots(x,s,t) ::defines_var(s); } in s; libminizinc-2.8.2/share/minizinc/std/alldifferent_except.mzn0000644000175000017500000000026114536677021022753 0ustar kaolkaol% The actual definitions are in all_different.mzn. % This file is used to handle the case where users include % "alldifferent_except.mzn"; % include "all_different_except.mzn"; libminizinc-2.8.2/share/minizinc/std/var_perm_sym.mzn0000644000175000017500000000040114536677021021443 0ustar kaolkaolinclude "fzn_var_perm_sym.mzn"; /** @group globals.lexicographic Requires that the array \a x is lex least under the given list of permutations \a p */ predicate var_perm_sym(array[$$X] of var $$Y: x, array[$$Z,$$X] of $$X: p) = fzn_var_perm_sym(x,p); libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_opt.mzn0000644000175000017500000000064614536677021024335 0ustar kaolkaolinclude "global_cardinality.mzn"; predicate fzn_global_cardinality_opt(array[int] of var opt int: x, array[int] of int: cover, array[int] of var int: counts) = let { % Set <> to something outside the cover int: def = if 0 in cover then min(cover) - 1 else 0 endif; } in global_cardinality([x_i default def | x_i in x], cover, counts); libminizinc-2.8.2/share/minizinc/std/fzn_arg_min_bool.mzn0000644000175000017500000000073214536677021022253 0ustar kaolkaolpredicate fzn_minimum_arg_bool(array[int] of var bool: x, var int: z) = % general case: min could be 0 or 1 let { int: l = min(index_set(x)) ; int: u = max(index_set(x)) ; int: n = u-l+1; array[int] of var int: xs = array1d(l..u,[ n*x[j]+j | j in l..u ]); var int: Mx = min(xs) ; } in forall (j in l..u) ( (z != j) = (Mx < xs[j]) ); %%% only the new decomposition from argmax paper CP2020 submission libminizinc-2.8.2/share/minizinc/std/fzn_member_bool_reif.mzn0000644000175000017500000000053614536677021023115 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array or set 'x'. %-----------------------------------------------------------------------------% predicate fzn_member_bool_reif(array[int] of var bool: x, var bool: y, var bool: b) = b <-> exists(i in index_set(x)) ( x[i] == y ); libminizinc-2.8.2/share/minizinc/std/fzn_bin_packing_load_reif.mzn0000644000175000017500000000121114536677021024065 0ustar kaolkaolpredicate fzn_bin_packing_load_reif(array[int] of var int: load, array[int] of var int: bin, array[int] of int: w, var bool: b) = b <-> ( sum(load) = sum(w) /\ forall( i in index_set(bin) ) ( min(index_set(load)) <= bin[i] /\ bin[i] <= max(index_set(load)) ) /\ forall( assigned_bin in index_set(load) ) ( load[assigned_bin] = sum ( i in index_set(bin) ) ( w[i] * ( bin[i] = assigned_bin ) ) ) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/redefinitions-2.2.1.mzn0000644000175000017500000000052614536677021022250 0ustar kaolkaol% This file contains redefinitions of standard builtins for version 2.2.1 % that can be overridden by solvers. predicate int_pow_fixed(var int: x, int: y, var int: z) = if y = 0 then z = 1 elseif y = 1 then z = x else if y >= 0 then z = product([x | i in 1..y]) else z = 1 div pow(x, -y) endif endif; libminizinc-2.8.2/share/minizinc/std/arg_sort_float.mzn0000644000175000017500000000051714536677021021755 0ustar kaolkaolinclude "fzn_arg_sort_float.mzn"; include "fzn_arg_sort_float_reif.mzn"; predicate arg_sort_float(array[int] of var float:x, array[int] of var int:p) = assert(index_set(p) = 1..length(x), "arg_sort_float: second argument must have index 1..length(first argument)", fzn_arg_sort_float(x, p) ); libminizinc-2.8.2/share/minizinc/std/fzn_value_precede_chain_int_opt.mzn0000644000175000017500000000051214536677021025321 0ustar kaolkaolinclude "value_precede_chain.mzn"; predicate fzn_value_precede_chain_int_opt(array[int] of int: T, array[int] of var opt int: X) = let { int: def = if had_zero(X) then max(T) + 1 else 0 endif; array [int] of var int: x = array1d(index_set(X), [xi default def | xi in X]); } in value_precede_chain(T, x); libminizinc-2.8.2/share/minizinc/std/fzn_at_most_set_reif.mzn0000644000175000017500000000057414536677021023156 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires at most 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate fzn_at_most_set_reif(int: n, array[int] of var set of int: x, set of int: v, var bool: b) = b <-> sum(i in index_set(x)) ( x[i] == v ) <= n; libminizinc-2.8.2/share/minizinc/std/arg_min.mzn0000644000175000017500000001600514536677021020363 0ustar kaolkaolinclude "fzn_arg_min_int.mzn"; include "fzn_arg_min_int_opt.mzn"; include "fzn_arg_min_bool.mzn"; include "fzn_arg_min_bool_opt.mzn"; include "fzn_arg_min_float.mzn"; include "fzn_arg_min_float_opt.mzn"; /** @group globals.math Returns the index of the minimum value in the array \a x. When breaking ties the least index is returned. */ function var $$E: arg_min(array[$$E] of var int: x) = let { constraint length(x) > 0; } in arg_min_total(x); /** @group globals.math Returns the index of the minimum value in the array \a x. When breaking ties the least index is returned. */ function var $$E: arg_min(array[$$E] of var bool: x) = let { constraint length(x) > 0; } in arg_min_total(x); /** @group globals.math Returns the index of the minimum value in the array \a x. When breaking ties the least index is returned. */ function var $$E: arg_min(array[$$E] of var float: x) = let { constraint length(x) > 0; } in arg_min_total(x); /** @group globals.math Returns the index of the minimum non-absent value in the array \a x. When breaking ties the least index is returned. */ function var $$E: arg_min(array[$$E] of var opt int: x) = let { constraint length(x) > 0; } in arg_min_total(x); /** @group globals.math Returns the index of the minimum non-absent value in the array \a x. When breaking ties the least index is returned. Returns absent when all elements are absent. */ function var opt $$E: arg_min_weak(array[$$E] of var opt int: x) :: promise_total = if length(x) = 0 then <> elseif exists (xi in x) (is_fixed(occurs(xi)) /\ (fix(occurs(xi)))) then let { var index_set(x): i; constraint fzn_minimum_arg_int_opt(x, i); } in i else let { set of int: idx = min(index_set(x)) .. max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [ub_array(x)]); var idx: i; var opt index_set(x): ii = if i in index_set(x) then i else <> endif; constraint fzn_minimum_arg_int_opt(xx, i); } in ii endif; /** @group globals.math Returns the index of the minimum non-absent value in the array \a x. When breaking ties the least index is returned. */ function var $$E: arg_min(array[$$E] of var opt bool: x) = let { constraint length(x) > 0; } in arg_max_total(x); /** @group globals.math Returns the index of the minimum non-absent value in the array \a x. When breaking ties the least index is returned. Returns absent when all elements are absent. */ function var opt $$E: arg_min_weak(array[$$E] of var opt bool: x) :: promise_total = if length(x) = 0 then <> elseif exists (xi in x) (is_fixed(occurs(xi)) /\ (fix(occurs(xi)))) then let { var index_set(x): i; constraint fzn_minimum_arg_bool_opt(x, i); } in i else let { set of int: idx = min(index_set(x)) .. max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [true]); var idx: i; var opt index_set(x): ii = if i in index_set(x) then i else <> endif; constraint fzn_minimum_arg_bool_opt(xx, i); } in ii endif; /** @group globals.math Returns the index of the minimum non-absent value in the array \a x. When breaking ties the least index is returned. */ function var $$E: arg_min(array[$$E] of var opt float: x) = let { constraint length(x) > 0; } in arg_min_total(x); /** @group globals.math Returns the index of the minimum non-absent value in the array \a x. When breaking ties the least index is returned. Returns absent when all elements are absent. */ function var opt $$E: arg_min_weak(array[$$E] of var opt float: x) :: promise_total = if length(x) = 0 then <> elseif exists (xi in x) (is_fixed(occurs(xi)) /\ (fix(occurs(xi)))) then let { var index_set(x): i; constraint fzn_minimum_arg_float_opt(x, i); } in i else let { set of int: idx = min(index_set(x)) .. max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [ub_array(x)]); var idx: i; var opt index_set(x): ii = if i in index_set(x) then i else <> endif; constraint fzn_minimum_arg_float_opt(xx, i); } in ii endif; function var $$E: arg_min_total(array[$$E] of var int: x) :: promise_total = if length(x) = 0 then 0 else let { var min(index_set(x)) .. max(index_set(x)): i; constraint fzn_minimum_arg_int(x, i); } in i endif; function var $$E: arg_min_total(array[$$E] of var bool: x) :: promise_total = if length(x) = 0 then 0 else let { var min(index_set(x)) .. max(index_set(x)): i; constraint fzn_minimum_arg_bool(x, i); } in i endif; function var $$E: arg_min_total(array[$$E] of var float: x) :: promise_total = if length(x) = 0 then 0 else let { var min(index_set(x)) .. max(index_set(x)): i; constraint fzn_minimum_arg_float(x, i); } in i endif; function var $$E: arg_min_total(array[$$E] of var opt int: x) :: promise_total = if length(x) = 0 then min(index_set(x)) elseif exists (xi in x) (is_fixed(occurs(xi)) /\ (fix(occurs(xi)))) then let { var index_set(x): i; constraint fzn_minimum_arg_int_opt(x, i); } in i else let { set of int: idx = min(index_set(x)) .. max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [ub_array(x)]); var idx: i; var index_set(x): ii = if i in index_set(x) then i else min(index_set(x)) endif; constraint fzn_minimum_arg_int_opt(xx, i); } in ii endif; function var $$E: arg_min_total(array[$$E] of var opt bool: x) :: promise_total = if length(x) = 0 then 0 elseif exists (xi in x) (is_fixed(occurs(xi)) /\ (fix(occurs(xi)))) then let { var index_set(x): i; constraint fzn_minimum_arg_bool_opt(x, i); } in i else let { set of int: idx = min(index_set(x)) .. max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [true]); var idx: i; var index_set(x): ii = if i in index_set(x) then i else min(index_set(x)) endif; constraint fzn_minimum_arg_bool_opt(xx, i); } in ii endif; function var $$E: arg_min_total(array[$$E] of var opt float: x) :: promise_total = if length(x) = 0 then 0 elseif exists (xi in x) (is_fixed(occurs(xi)) /\ (fix(occurs(xi)))) then let { var index_set(x): i; constraint fzn_minimum_arg_float_opt(x, i); } in i else let { set of int: idx = min(index_set(x)) .. max(index_set(x)) + 1; any: xx = array1d(idx, x ++ [ub_array(x)]); var idx: i; var index_set(x): ii = if i in index_set(x) then i else min(index_set(x)) endif; constraint fzn_minimum_arg_float_opt(xx, i); } in ii endif; /** @group globals.math Constrain \a i to be the index of the minimum value in the array \a x. When breaking ties the least index is returned. Assumption: |\a x| > 0 */ predicate minimum_arg(array[int] of var int: x, var int: i) = fzn_minimum_arg_int(x, i); /** @group globals.math Constrain \a i to be the index of the minimum value in the array \a x. When breaking ties the least index is returned. Assumption: |\a x| > 0 */ predicate minimum_arg(array[int] of var bool: x, var int: i) = fzn_minimum_arg_bool(x, i); /** @group globals.math Constrain \a i to be the index of the minimum value in the array \a x. When breaking ties the least index is returned. Assumption: |\a x| > 0 */ predicate minimum_arg(array[int] of var float: x, var int: i) = fzn_minimum_arg_float(x, i); libminizinc-2.8.2/share/minizinc/std/at_most_int.mzn0000644000175000017500000000061114536677021021263 0ustar kaolkaolinclude "fzn_at_most_int.mzn"; include "fzn_at_most_int_reif.mzn"; %-----------------------------------------------------------------------------% % Requires at most 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate at_most_int(int: n, array[$X] of var $$E: x, $$E: v) = fzn_at_most_int(n, array1d(x), v); libminizinc-2.8.2/share/minizinc/std/count.mzn0000644000175000017500000000032714536677021020077 0ustar kaolkaolinclude "count_eq.mzn"; /** @group globals.counting Constrains \a c to be the number of occurrences of \a y in \a x. */ predicate count(array[$X] of var opt $$E: x, var $$E: y, var int: c) = count_eq(x, y, c); libminizinc-2.8.2/share/minizinc/std/lex_lesseq.mzn0000644000175000017500000000561114536677021021114 0ustar kaolkaolinclude "fzn_lex_lesseq_bool.mzn"; include "fzn_lex_lesseq_bool_reif.mzn"; include "fzn_lex_lesseq_float.mzn"; include "fzn_lex_lesseq_float_reif.mzn"; include "fzn_lex_lesseq_int.mzn"; include "fzn_lex_lesseq_int_reif.mzn"; include "fzn_lex_lesseq_set.mzn"; include "fzn_lex_lesseq_set_reif.mzn"; /** @group globals.lexicographic Requires that the array \a x is lexicographically less than or equal to array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_lesseq( array[int] of var bool: x ::promise_ctx_antitone, array[int] of var bool: y ::promise_ctx_monotone, ) = if length(x)=1 /\ length(y)=1 then x[min(index_set(x))] <= y[min(index_set(y))] elseif length(x)=0 then true elseif length(y)=0 then false else fzn_lex_lesseq_bool(x, y) endif; /** @group globals.lexicographic Requires that the array \a x is lexicographically less than or equal to array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_lesseq( array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_monotone, ) = if length(x)=1 /\ length(y)=1 then x[min(index_set(x))] <= y[min(index_set(y))] elseif length(x)=0 then true elseif length(y)=0 then false else fzn_lex_lesseq_float(x, y) endif; /** @group globals.lexicographic Requires that the array \a x is lexicographically less than or equal to array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_lesseq( array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone, ) = if length(x)=1 /\ length(y)=1 then x[min(index_set(x))] <= y[min(index_set(y))] elseif length(x)=0 then true elseif length(y)=0 then false else fzn_lex_lesseq_int(x, y) endif; /** @group globals.lexicographic Requires that the array \a x is lexicographically less than or equal to array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_lesseq( array[int] of var set of int: x ::promise_ctx_antitone, array[int] of var set of int: y ::promise_ctx_monotone, ) = if length(x)=1 /\ length(y)=1 then x[min(index_set(x))] <= y[min(index_set(y))] elseif length(x)=0 then true elseif length(y)=0 then false else fzn_lex_lesseq_set(x, y) endif; % Alternative names for the above. % predicate lex_leq(array[int] of var bool: x ::promise_ctx_antitone, array[int] of var bool: y ::promise_ctx_monotone) = lex_lesseq(x, y); predicate lex_leq(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) = lex_lesseq(x, y); predicate lex_leq(array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_monotone) = lex_lesseq(x, y); predicate lex_leq( array[int] of var set of int: x::promise_ctx_antitone, array[int] of var set of int: y::promise_ctx_monotone, ) = lex_lesseq(x, y); libminizinc-2.8.2/share/minizinc/std/reachable.mzn0000644000175000017500000001075514536677021020663 0ustar kaolkaolinclude "fzn_reachable_int.mzn"; include "fzn_reachable_int_reif.mzn"; include "fzn_reachable_enum.mzn"; include "fzn_reachable_enum_reif.mzn"; include "fzn_dreachable_int.mzn"; include "fzn_dreachable_int_reif.mzn"; include "fzn_dreachable_enum.mzn"; include "fzn_dreachable_enum_reif.mzn"; /** @group globals.graph Constrains the subgraph \a ns and \a es of a given directed graph to be reachable from \a r. @param N: the number of nodes in the given graph @param E: the number of edges in the given graph @param from: the leaving node 1..\a N for each edge @param to: the entering node 1..\a N for each edge @param r: the root node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate dreachable(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: r, array[int] of var bool: ns, array[int] of var bool: es) = assert(index_set(from) = 1..E,"dreachable: index set of from must be 1..\(E)") /\ assert(index_set(to) = 1..E,"dreachable: index set of to must be 1..\(E)") /\ assert(index_set(ns) = 1..N,"dreachable: index set of ns must be 1..\(N)") /\ assert(index_set(es) = 1..E,"dreachable: index set of es must be 1..\(E)") /\ fzn_dreachable(N,E,from,to,r,ns,es); /** @group globals.graph Constrains the subgraph \a ns and \a es of a given directed graph to be reachable from \a r. @param from: the leaving node for each edge @param to: the entering node for each edge @param r: the root node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate dreachable(array[int] of $$N: from, array[int] of $$N: to, var $$N: r, array[$$N] of var bool: ns, array[int] of var bool: es) = assert(index_set(from) = index_set(to),"dreachable: index set of from and to must be identical") /\ assert(index_set(from) = index_set(es),"dreachable: index set of from and es must be identical") /\ assert(dom_array(from) subset index_set(ns),"dreachable: nodes in from must be in index set of ns") /\ assert(dom_array(to) subset index_set(ns),"dreachable: nodes in to must be in index set of ns") /\ fzn_dreachable(from,to,r,ns,es); %-----------------------------------------------------------------------------% /** @group globals.graph Constrains the subgraph \a ns and \a es of a given undirected graph to be reachable from \a r. @param N: the number of nodes in the given graph @param E: the number of edges in the given graph @param from: the leaving node 1..\a N for each edge @param to: the entering node 1..\a N for each edge @param r: the root node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate reachable(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: r, array[int] of var bool: ns, array[int] of var bool: es) = assert(index_set(from) = 1..E,"reachable: index set of from must be 1..\(E)") /\ assert(index_set(to) = 1..E,"reachable: index set of to must be 1..\(E)") /\ assert(index_set(ns) = 1..N,"reachable: index set of ns must be 1..\(N)") /\ assert(index_set(es) = 1..E,"reachable: index set of es must be 1..\(E)") /\ fzn_reachable(N,E,from,to,r,ns,es); /** @group globals.graph Constrains the subgraph \a ns and \a es of a given undirected graph to be reachable from \a r. @param from: the leaving node for each edge @param to: the entering node for each edge @param r: the root node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate reachable(array[int] of $$N: from, array[int] of $$N: to, var $$N: r, array[$$N] of var bool: ns, array[int] of var bool: es) = assert(index_set(from) = index_set(to),"reachable: index set of from and to must be identical") /\ assert(index_set(from) = index_set(es),"reachable: index set of from and es must be identical") /\ assert(dom_array(from) subset index_set(ns),"reachable: nodes in from must be in index set of ns") /\ assert(dom_array(to) subset index_set(ns),"reachable: nodes in to must be in index set of ns") /\ fzn_reachable(from,to,r,ns,es); libminizinc-2.8.2/share/minizinc/std/fzn_arg_max_bool.mzn0000644000175000017500000000074014536677021022254 0ustar kaolkaolpredicate fzn_maximum_arg_bool(array[int] of var bool: x, var int: z) = % general case: min could be 0 or 1 let { int: l = min(index_set(x)) ; int: u = max(index_set(x)) ; int: n = u-l+1; array[int] of var int: xs = array1d(l..u,[ n*x[j]+(u-j) | j in l..u ]); var int: Mx = max(xs) ; } in forall (j in l..u) ( (z != j) = (Mx > xs[j]) ); %%% only the new decomposition from argmax paper CP2020 submission libminizinc-2.8.2/share/minizinc/std/fzn_dpath_enum.mzn0000644000175000017500000000332214536677021021746 0ustar kaolkaolinclude "tree.mzn"; include "subgraph.mzn"; predicate fzn_dpath(array[int] of $$N: from, array[int] of $$N: to, var $$N: s, var $$N: t, array[$$N] of var bool: ns, array[int] of var bool: es) = let { set of int: EDGE = index_set(es); array[index_set(ns)] of var 0..length(ns)-1: dist; /* distance from root */ } in ns[s] /\ % source is selected ns[t] /\ % dest is selected dist[s] = 0 /\ % distance of source is zero forall(n in index_set(ns)) % nonselected nodes have distance 0 (not ns[n] -> dist[n] = 0) /\ forall(n in index_set(ns)) % 1 incoming edge ((ns[n] /\ n != s) -> exists(e in EDGE where to[e] = n)(es[e])) /\ forall(n in index_set(ns)) % 1 outgoing edge ((ns[n] /\ n != t) -> exists(e in EDGE where from[e] = n)(es[e])) /\ forall(n in index_set(ns)) % 1 incoming edge ((ns[n] /\ n != s) -> sum(e in EDGE where to[e] = n)(es[e]) <= 1) /\ forall(n in index_set(ns)) % 1 outgoing edge ((ns[n] /\ n != t) -> sum(e in EDGE where from[e] = n)(es[e]) <= 1) /\ % alternate for the previous 8 lines % forall(n in index_set(ns)) % 1 incoming edge % ((ns[n] /\ n != s) -> sum(e in EDGE where to[e] = n)(es[e]) = 1) /\ % forall(n in index_set(ns)) % 1 outgoing edge % ((ns[n] /\ n != t) -> sum(e in EDGE where from[e] = n)(es[e]) = 1) /\ forall(e in EDGE) (es[e] -> dist[to[e]] = dist[from[e]] + 1) /\ sum(n in index_set(ns))(ns[n]) = sum(e in EDGE)(es[e]) + 1 /\ subgraph(from,to,ns,es); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_dtree_enum.mzn0000644000175000017500000000333714536677021021757 0ustar kaolkaolinclude "subgraph.mzn"; predicate fzn_dtree(array[int] of $$N: from, array[int] of $$N: to, var $$N: r, array[$$N] of var bool: ns, array[int] of var bool: es) = let { set of int: EDGE = index_set(es); array[index_set(ns)] of var 0..length(ns)-1: dist; /* distance from root */ array[index_set(ns)] of var index_set(ns): parent; /* parent */ } in ns[r] /\ % the root must be chosen dist[r] = 0 /\ % root is at distance 0 parent[r] = r /\ % root is its own parent forall(n in index_set(ns)) % nonselected nodes have parent 0 (not ns[n] -> parent[n] = n) /\ forall(n in index_set(ns)) % nonselected nodes have distance 0 (not ns[n] -> dist[n] = 0) /\ forall(n in index_set(ns)) % each in node except root must have a parent (ns[n] -> (n = r \/ parent[n] != n)) /\ forall(n in index_set(ns)) % each in node with a parent must be in and also its parent (parent[n] != n -> (ns[n] /\ ns[parent[n]])) /\ forall(n in index_set(ns)) % each except with a parent is one more than its parent (parent[n] != n -> dist[n] = dist[parent[n]] + 1) /\ forall(n in index_set(ns)) % each node with a parent must have that edge in (parent[n] != n -> exists(e in EDGE where to[e] = n)(es[e] /\ from[e] = parent[n])) /\ forall(e in EDGE) % each edge must be part of the parent relation (es[e] -> parent[to[e]] = from[e]) /\ sum(e in EDGE)(es[e]) = sum(n in index_set(ns))(ns[n]) - 1 /\ % redundant relationship of trees subgraph(from,to,ns,es); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_count_neq.mzn0000644000175000017500000000055114536677021021616 0ustar kaolkaolinclude "count_fn.mzn"; predicate fzn_count_neq(array[int] of var int: x, var int: y, var int: c) = let { var int: z = count(x,y) } in z != c; % This needs to be written with a let rather than count(x,y) != c % so that the automatic rewriting of the latter doesn't kick in %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_neural_net.mzn0000644000175000017500000000526514536677021021766 0ustar kaolkaolpredicate fzn_neural_net(array[int] of var float: inputs, array[int] of int: input_ids, array[int] of var float: outputs, array[int] of int: output_ids, array[int] of float: bias, array[int] of float: edge_weight, array[int] of int: edge_parent, array[int] of int: first_edge, NEURON_TYPE: neuron_type) = let { set of int: NODE = index_set(bias) } in let { set of int: INPUTS = array2set(input_ids) } in let { set of int: EDGE = index_set(edge_weight) } in let { array[NODE] of var float: neuron } in forall(i in index_set(inputs))(neuron[input_ids[i]] = inputs[i]) /\ forall(i in index_set(outputs))(neuron[output_ids[i]] = outputs[i]) /\ forall(i in NODE diff INPUTS) ( let { int: first = first_edge[i]; int: last = if i = max(NODE) then max(EDGE) else first_edge[i+1] - 1 endif; array[int] of var float: ins = [neuron[edge_parent[j]] | j in first..last]; array[int] of float: ws = [ edge_weight[j] | j in first..last ]; float: b = bias[i]; } in neuron[i] = if neuron_type = NT_RELU then neuron_relu(ins,ws,b) elseif neuron_type = NT_STEP then neuron_step(ins,ws,b) elseif neuron_type = NT_LINEAR then neuron_linear(ins,ws,b) elseif neuron_type = NT_SOFTPLUS then neuron_softplus(ins,ws,b) else 0.0 endif ); %-----------------------------------------------------------------------------% function var float: neuron_relu(array[int] of var float: inputs, array[int] of float: weights, float: bias) = max(0.0, sum(i in index_set(inputs))(weights[i]*inputs[i]) + bias); function var float: neuron_step(array[int] of var float: inputs, array[int] of float: weights, float: bias) = (sum(i in index_set(inputs))(weights[i]*inputs[i]) + bias >= 0.0); function var float: neuron_linear(array[int] of var float: inputs, array[int] of float: weights, float: bias) = (sum(i in index_set(inputs))(weights[i]*inputs[i]) + bias); function var float: neuron_softplus(array[int] of var float: inputs, array[int] of float: weights, float: bias) = (ln(1 + exp(sum(i in index_set(inputs))(weights[i]*inputs[i]) + bias))); libminizinc-2.8.2/share/minizinc/std/atmost1.mzn0000644000175000017500000000022414536677021020333 0ustar kaolkaol% The actual definitions are in at_most1.mzn. % This file is used to handle the case where users include % "atmost1.mzn"; % include "at_most1.mzn"; libminizinc-2.8.2/share/minizinc/std/arg_sort_int.mzn0000644000175000017500000000064714536677021021446 0ustar kaolkaolinclude "fzn_arg_sort_int.mzn"; include "fzn_arg_sort_int_reif.mzn"; predicate arg_sort_int( array[$$E] of var int: x, array[int] of var $$E: p, ) = assert( index_set(p) = 1..length(x), "arg_sort_int: second argument must have index 1..length(first argument)", fzn_arg_sort_int(x, p) ); predicate arg_sort_int( array[$$E] of var int: x, array[int] of var $$E: p, var bool:b ) = b <-> fzn_arg_sort_int(x, p); libminizinc-2.8.2/share/minizinc/std/fzn_value_precede_chain_set_reif.mzn0000644000175000017500000000025214536677021025446 0ustar kaolkaolpredicate fzn_value_precede_chain_set_reif(array[int] of int: c, array[int] of var set of int: x, var bool: b) = abort("Reified value_precede_chain is not supported"); libminizinc-2.8.2/share/minizinc/std/element_bool.mzn0000644000175000017500000000046514536677021021416 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' is the ith element of the array 'x'. %-----------------------------------------------------------------------------% predicate element_bool(var $$E: i, array[$$E] of var bool: x, var bool: y) = y = x[i]; libminizinc-2.8.2/share/minizinc/std/diffn_k.mzn0000644000175000017500000000144214536677021020346 0ustar kaolkaolinclude "fzn_diffn_k.mzn"; include "fzn_diffn_k_reif.mzn"; /** @group globals.packing Constrains \p k-dimensional boxes to be non-overlapping. For each box \p i and dimension \p j, \a box_posn[\p i, \p j] is the base position of the box in dimension \p j, and \a box_size[\p i, \p j] is the size in that dimension. Boxes whose size is 0 in any dimension still cannot overlap with any other box. */ predicate diffn_k(array[int,int] of var int: box_posn, array[int,int] of var int: box_size) = let { set of int: DIMS= index_set_2of2(box_posn) } in assert(index_set_2of2(box_size) = DIMS /\ index_set_1of2(box_posn) = index_set_1of2(box_size), "diffn: index sets of arguments are incorrect", fzn_diffn_k(box_posn, box_size) ); libminizinc-2.8.2/share/minizinc/std/fzn_wst.mzn0000644000175000017500000000070114536677021020435 0ustar kaolkaolinclude "tree.mzn"; predicate fzn_wst(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, array[int] of var bool: es, var int: K) = let { var 1..N: r; /* root of tree */ array[1..N] of bool: ns = [true | n in 1..N]; } in tree(N,E,from,to,r,ns,es) /\ K = sum(e in 1..E)(es[e]*w[e]); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/element_bool.mzn.deprecated.mzn0000644000175000017500000000025214536677021024312 0ustar kaolkaolpredicate element_bool(var $$E: i, array[$$E] of var bool: x, var bool: y) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/increasing_bool.mzn0000644000175000017500000000062414536677021022104 0ustar kaolkaolinclude "fzn_increasing_bool.mzn"; include "fzn_increasing_bool_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate increasing_bool(array[$X] of var bool: x) = fzn_increasing_bool(array1d(x)); libminizinc-2.8.2/share/minizinc/std/fzn_arg_sort_int_reif.mzn0000644000175000017500000000053714536677021023326 0ustar kaolkaolinclude "all_different.mzn"; predicate fzn_arg_sort_int_reif(array[int] of var int:x, array[int] of var int:p, var bool:b) = b <-> ( all_different(p) /\ forall(j in 1..length(x)-1) (x[p[j]] <= x[p[j+1]] /\ (x[p[j]] == x[p[j+1]] -> p[j] < p[j+1])) ); libminizinc-2.8.2/share/minizinc/std/at_least.mzn0000644000175000017500000000147614536677021020551 0ustar kaolkaolinclude "fzn_at_least_int.mzn"; include "fzn_at_least_int_reif.mzn"; include "fzn_at_least_set.mzn"; include "fzn_at_least_set_reif.mzn"; /** @group globals.deprecated Requires at least \a n variables in \a x to take the value \a v. This constraint is deprecated. Use count(i in x)(i=v) >= n instead. */ predicate at_least(int: n, array[$X] of var $$E: x, $$E: v) = fzn_at_least_int(n, array1d(x), v); /** @group globals.counting Requires at least \a n variables in \a x to take the value \a v. */ predicate at_least(int: n, array[$X] of var set of $$E: x, set of $$E: v) = fzn_at_least_set(n, array1d(x), v); % Synonyms for the above. predicate atleast(int: n, array[$X] of var $$E: x, $$E: v) = at_least(n, x, v); predicate atleast(int: n, array[$X] of var set of $$E: x, set of $$E: v) = at_least(n, x, v); libminizinc-2.8.2/share/minizinc/std/lex_chain_less_bool.mzn.deprecated.mzn0000644000175000017500000000023514536677021025642 0ustar kaolkaolpredicate lex_chain_less_bool(array[int, int] of var bool: a) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_all_different_int.mzn0000644000175000017500000000052614536677021023275 0ustar kaolkaol%-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all different. %-----------------------------------------------------------------------------% predicate fzn_all_different_int(array[int] of var int: x) = forall(i,j in index_set(x) where i < j) ( x[i] != x[j] ); libminizinc-2.8.2/share/minizinc/std/redefinitions-2.1.mzn0000644000175000017500000000055414536677021022111 0ustar kaolkaol% This file contains redefinitions of standard builtins for version 2.1 % that can be overridden by solvers. predicate float_in(var float: x, float: a, float: b) = x >= a /\ x <= b; predicate float_dom(var float: x, array[int] of float: as) = let { array[int] of var bool: b = [float_in(x,as[2*i-1],as[2*i]) | i in 1..length(as) div 2] } in exists(b); libminizinc-2.8.2/share/minizinc/std/fzn_subcircuit.mzn0000644000175000017500000000312314536677021021775 0ustar kaolkaolinclude "alldifferent.mzn"; predicate fzn_subcircuit(array[int] of var int: x) = if length(x) = 0 then true else let { set of int: S = index_set(x), int: l = min(S), int: u = max(S), int: n = card(S), array[S] of var 1..n: order, array[S] of var bool: ins = array1d(S,[ x[i] != i | i in S]), var l..u+1: firstin = min([ u+1 + bool2int(ins[i])*(i-u-1) | i in S]), var S: lastin, var bool: empty = (firstin > u), } in alldifferent(x) /\ alldifferent(order) /\ % If the subcircuit is empty then each node points at itself. % (empty -> forall(i in S)(not ins[i])) /\ % If the subcircuit is non-empty then order numbers the subcircuit. % ((not empty) -> % The firstin node is numbered 1. order[firstin] = 1 /\ % The lastin node is greater than firstin. lastin > firstin /\ % The lastin node points at firstin. x[lastin] = firstin /\ % And both are in ins[lastin] /\ ins[firstin] /\ % The successor of each node except where it is firstin is % numbered one more than the predecessor. forall(i in S) ( (ins[i] /\ x[i] != firstin) -> order[x[i]] = order[i] + 1 ) /\ % Each node that is not in is numbered after the lastin node. forall(i in S) ( ins[i] \/ order[lastin] < order[i] ) ) endif; %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_arg_val_float_opt.mzn0000644000175000017500000000042214536677021023302 0ustar kaolkaolinclude "fzn_arg_val_float.mzn"; predicate fzn_arg_val_float_opt(array[int] of var opt float: x, var opt float: v, var int: i) = let { any: values = x ++ [v]; float: def = lb_array(values) - 1; } in fzn_arg_val_float([xi default def | xi in x], v default def, i); libminizinc-2.8.2/share/minizinc/std/fzn_network_flow.mzn0000644000175000017500000000100514536677021022336 0ustar kaolkaolpredicate fzn_network_flow(array[int,1..2] of int: arc, array[int] of int: balance, array[int] of var int: flow) = let { int: source_node = 1; int: sink_node = 2; set of int: ARCS = index_set_1of2(arc); set of int: NODES = index_set(balance); } in forall (i in NODES) ( sum (j in ARCS where i == arc[j,source_node]) (flow[j]) - sum (j in ARCS where i == arc[j,sink_node]) (flow[j]) = balance[i] ); libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_low_up_closed_opt.mzn0000644000175000017500000000072714536677021027253 0ustar kaolkaolinclude "global_cardinality.mzn"; predicate fzn_global_cardinality_low_up_closed_opt(array[int] of var opt int: x, array[int] of int: cover, array[int] of int: lbound, array[int] of int: ubound) = forall (xi in x) (absent(xi) \/ deopt(xi) in { d | d in cover }) /\ global_cardinality(x, cover, lbound, ubound); libminizinc-2.8.2/share/minizinc/std/member_int.mzn0000644000175000017500000000055614536677021021074 0ustar kaolkaolinclude "fzn_member_int.mzn"; include "fzn_member_int_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array or set 'x'. %-----------------------------------------------------------------------------% predicate member_int(array[int] of var $$E: x, var $$E: y) = fzn_member_int(x, y); libminizinc-2.8.2/share/minizinc/std/fzn_all_different_set.mzn0000644000175000017500000000053514536677021023276 0ustar kaolkaol%-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all different. %-----------------------------------------------------------------------------% predicate fzn_all_different_set(array[int] of var set of int: x) = forall(i,j in index_set(x) where i < j) ( x[i] != x[j] ); libminizinc-2.8.2/share/minizinc/std/all_disjoint.mzn0000644000175000017500000000042214536677021021416 0ustar kaolkaolinclude "fzn_all_disjoint.mzn"; include "fzn_all_disjoint_reif.mzn"; /** @group globals.alldifferent Constrain the array of sets of integers \a S to be pairwise disjoint. */ predicate all_disjoint(array[$X] of var set of int: S) = fzn_all_disjoint(array1d(S)); libminizinc-2.8.2/share/minizinc/std/fzn_at_least_int_reif.mzn0000644000175000017500000000055714536677021023304 0ustar kaolkaolinclude "count_fn.mzn"; %-----------------------------------------------------------------------------% % Requires at least 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate fzn_at_least_int_reif(int: n, array[int] of var int: x, int: v, var bool: b) = b <-> count(x, v) >= n; libminizinc-2.8.2/share/minizinc/std/fzn_cost_regular.mzn0000644000175000017500000000243214536677021022314 0ustar kaolkaolpredicate fzn_cost_regular(array[int] of var int: x, int: Q, int: S, array[int,int] of int: d, int: q0, set of int: F, array[int,int] of int: c, var int: C) = if length(x) = 0 then C = 0 /\ q0 in F else let { % If x has index set m..n-1, then a[m] holds the initial state % (q0), and a[i+1] holds the state we're in after processing % x[i]. If a[n] is in F, then we succeed (ie. accept the string). int: m = min(index_set(x)); int: n = max(index_set(x)) + 1; array[m..n] of var 1..Q: a; % cc[i+1] holds the accumulated cost of edges taken process up to x[i] array[m..n] of var int: cc; } in a[m] = q0 /\ % Set a[0]. cc[m] = 0 /\ % initially zero cost forall(i in index_set(x)) ( x[i] in 1..S /\ % Do this in case it's a var. a[i+1] = d[a[i], x[i]] /\ % Determine a[i+1]. cc[i+1] = c[a[i],x[i]] + cc[i] % Calculate new cost sum ) /\ a[n] in F /\ % Check the final state is in F. C = cc[n] % return final cost endif; libminizinc-2.8.2/share/minizinc/std/fzn_inverse_opt.mzn0000644000175000017500000000053214536677021022157 0ustar kaolkaolinclude "all_different.mzn"; predicate fzn_inverse_opt(array[int] of var opt int: f, array[int] of var opt int: invf) = all_different(f) /\ all_different(invf) /\ forall (i in index_set(f)) ( occurs(f[i]) <-> invf[f[i]] = i ) /\ forall (j in index_set(invf)) ( occurs(invf[j]) <-> f[invf[j]] = j ); libminizinc-2.8.2/share/minizinc/std/fzn_steiner.mzn0000644000175000017500000000062214536677021021273 0ustar kaolkaolinclude "tree.mzn"; predicate fzn_steiner(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, array[int] of var bool: ns, array[int] of var bool: es, var int: K) = let { var 1..N: r; } in tree(N,E,from,to,r,ns,es) /\ K = sum(e in 1..E)(es[e]*w[e]); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/all_equal_set.mzn0000644000175000017500000000064714536677021021566 0ustar kaolkaolinclude "fzn_all_equal_set.mzn"; include "fzn_all_equal_set_reif.mzn"; %-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all equal. %-----------------------------------------------------------------------------% predicate all_equal_set(array[$X] of var set of int: x) = if length(x) <=1 then true else fzn_all_equal_set(array1d(x)) endif; libminizinc-2.8.2/share/minizinc/std/lex_chain_less_int.mzn0000644000175000017500000000100114536677021022567 0ustar kaolkaolinclude "fzn_lex_chain_less_int.mzn"; include "fzn_lex_chain_less_int_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the columns of matrix \a a are lexicographically sorted, % strictly increasing. %-----------------------------------------------------------------------------% predicate lex_chain_less_int(array[int, int] of var int: a) = fzn_lex_chain_less_int(a); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_piecewise_linear_non_continuous_reif.mzn0000644000175000017500000000100314536677021027270 0ustar kaolkaolpredicate fzn_piecewise_linear_non_continuous_reif(var float: x, var float: y, array[int] of float: xi1, array[int] of float: xi2, array[int] of float: vi1, array[int] of float: vi2, var bool: b) = abort("Reified piecewise_linear (non_continuous) constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/member_int.mzn.deprecated.mzn0000644000175000017500000000023214536677021023765 0ustar kaolkaolpredicate member_int(array[int] of var $$E: x, var $$E: y) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_table_bool_reif.mzn0000644000175000017500000000072614536677021022736 0ustar kaolkaol%-----------------------------------------------------------------------------% % A table constraint: table(x, t) represents the constraint x in t where we % consider each row in t to be a tuple and t as a set of tuples. %-----------------------------------------------------------------------------% predicate fzn_table_bool_reif(array[int] of var bool: x, array[int, int] of bool: t, var bool: b) = abort("Reified table/2 for Booleans is not supported."); libminizinc-2.8.2/share/minizinc/std/fzn_at_most_int_reif.mzn0000644000175000017500000000055514536677021023154 0ustar kaolkaolinclude "count_fn.mzn"; %-----------------------------------------------------------------------------% % Requires at most 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate fzn_at_most_int_reif(int: n, array[int] of var int: x, int: v, var bool: b) = b <-> count(x,v) <= n; libminizinc-2.8.2/share/minizinc/std/fzn_inverse_reif.mzn0000644000175000017500000000057714536677021022313 0ustar kaolkaolpredicate fzn_inverse_reif(array[int] of var int: f, array[int] of var int: invf, var bool: b) = b <-> ( forall(i in index_set(f)) ( f[i] in index_set(invf) /\ (invf[f[i]] == i) ) /\ forall(j in index_set(invf)) ( invf[j] in index_set(f) /\ (f[invf[j]] == j) ) ); libminizinc-2.8.2/share/minizinc/std/mdd_nondet.mzn0000644000175000017500000000567614536677021021076 0ustar kaolkaolinclude "fzn_mdd_nondet.mzn"; include "fzn_mdd_nondet_reif.mzn"; /** @group globals.extensional Requires that \a x defines a path from root to true node T through the (nondeterministic) Multivalued Decision Diagram (MDD) defined by the parameters. @param N: the number of nodes, the root node is node 1 @param level: the level of each node, the root is level 1, T is level \a length(x)+1 @param E: the number of edges @param from: the leaving node (1..\a N)for each edge @param label: the set of values of the \a x variable for each edge @param to: the entering node for each edge, where 0 = T node The MDD can be nondeterministic, i.e., there can be two edges with the same label leaving the same node. */ predicate mdd_nondet(array[int] of var int: x, % variables constrained by MDD int: N, % number of nodes root is node 1 array[int] of int: level, % level of each node root is level 1, T is level length(x)+1 int: E, % number of edges array[int] of int: from, % edge leaving node 1..N array[int] of set of int: label, % possible values of variable array[int] of int: to % edge entering node 0..N where 0 = T node ) = let { set of int: NODE = 1..N; set of int: EDGE = 1..E; int: L = length(x); array[0..N] of int: levele = array1d(0..N,[L+1]++level); } in assert(index_set(level) = NODE, "mdd: third argument must be of length N = \(N)") /\ assert(index_set(from) = EDGE, "mdd: 5th argument must be of length E = \(E)") /\ assert(index_set(to) = EDGE, "mdd: 7th argument must be of length E = \(E)") /\ forall(e in EDGE)(assert(from[e] in NODE, "mdd: from[\(e)] must be in \(NODE)")) /\ forall(e in EDGE)(assert(to[e] in 0..N, "mdd: to[\(e)] must be in 0..\(N)")) /\ forall(e in EDGE)(assert(level[from[e]]+1 = levele[to[e]], "mdd level of from[\(e)] = \(level[from[e]])" ++ "must be 1 less than level of to[\(e)] = \(levele[to[e]])")) /\ fzn_mdd_nondet(x, N, level, E, from, label, to); % Example consider an MDD over 3 variables % 5 nodes and 12 edges % level 1 root = 1 % level 2 2 3 % level 3 4 5 % level 4 T % with edges (from,label,to) given by % (1,1,2), (1,2,3), (1,3,2) % (2,2,4), (2,3,5) % (3,3,4), (3,2,5) % (4,1,0), (4,5,0) % (5,2,0), (5,4,0), (5,6,0) % this is defined by the call % mdd([x1,x2,x3],5,[1,2,2,3,3],12,[1,1,1,2,2,3,3,4,4,5,5,5],[1,3,2,2,3,3,2,1,5,2,4,6],[2,2,3,4,5,4,5,0,0,0,0,0]) libminizinc-2.8.2/share/minizinc/std/fzn_lex_chain_lesseq_int_reif.mzn0000644000175000017500000000045614536677021025014 0ustar kaolkaolinclude "lex_lesseq.mzn"; predicate fzn_lex_chain_lesseq_int_reif( array[int, int] of var int: a, var bool: b) = let { set of int: is2 = index_set_2of2(a); } in b <-> ( forall(j in is2 where j+1 in is2) ( lex_lesseq(col(a, j), col(a, j+1)) ) ); libminizinc-2.8.2/share/minizinc/std/count_lt.mzn0000644000175000017500000000174014536677021020576 0ustar kaolkaolinclude "fzn_count_lt.mzn"; include "fzn_count_lt_par.mzn"; include "fzn_count_lt_reif.mzn"; include "fzn_count_lt_par_reif.mzn"; /** @group globals.counting Constrains \a c to be strictly less than the number of occurrences of \a y in \a x. */ predicate count_lt(array[$X] of var $$E: x, var $$E: y, var int: c) = fzn_count_lt(array1d(x), y, c); /** @group globals.counting Constrains \a c to be strictly less than the number of occurrences of \a y in \a x. */ predicate count_lt(array[$X] of var opt $$E: x, var $$E: y, var int: c) =let { % Set <> to something not y int: def = if 0 in dom(y) then lb(y)-1 else 0 endif; } in count_lt([i default def | i in x], y, c); /** @group globals.counting Constrains \a c to be strictly less than the number of occurrences of \a y in \a x. */ predicate count_lt(array[$X] of var $$E: x, $$E: y, int: c) = fzn_count_lt_par(array1d(x), y, c); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_set_member.mzn0000644000175000017500000000043314536677021021744 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array or set 'x'. %-----------------------------------------------------------------------------% predicate fzn_set_member(var set of int: x, var int: y) = y in x; libminizinc-2.8.2/share/minizinc/std/arg_sort_int.mzn.deprecated.mzn0000644000175000017500000000055314536677021024344 0ustar kaolkaolpredicate arg_sort_int( array[$$E] of var int: x, array[int] of var $$E: p, ) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); predicate arg_sort_int( array[$$E] of var int: x, array[int] of var $$E: p, var bool:b ) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_value_precede_chain_set.mzn0000644000175000017500000000035414536677021024444 0ustar kaolkaolinclude "value_precede.mzn"; predicate fzn_value_precede_chain_set(array[int] of int: c, array[int] of var set of int: x) = forall (i in min(index_set(c)) + 1 .. max(index_set(c))) ( value_precede(c[i - 1], c[i], x) ); libminizinc-2.8.2/share/minizinc/std/writes_seq.mzn0000644000175000017500000000216214536677021021133 0ustar kaolkaolinclude "fzn_writes_seq.mzn"; include "fzn_writes_seq_reif.mzn"; /** @group globals.array Creates a new array \a O from an input array \a I with a sequence of changes at positions \a P to take values \a V \a I is an array of integers \a O is an array of integers with same index set as \a I \a P is an array of index values in \a I \a V is an array of integer values */ predicate writes_seq(array[$$X] of var int: I, array[$$Y] of var int: P, array[$$Y] of var int: V, array[$$X] of var int: O) = assert(index_set(O) = index_set(I),"writes: index set of I must be same as O") /\ assert(index_set(P) = index_set(V),"writes: index set of P must be same as V") /\ fzn_writes_seq(I, P, V, O); function array[$$X] of var int: writes_seq( array[$$X] of var int: I, array[$$Y] of var int: P, array[$$Y] of var int: V ) = let { array[index_set(I)] of var int: O; constraint assert(index_set(P) = index_set(V),"writes: index set of P must be same as V"); constraint fzn_writes_seq(I,P,V,O); } in O; %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_lex_less_bool.mzn0000644000175000017500000000110614536677021022451 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than array 'y'. % Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_less_bool(array[int] of var bool: x ::promise_ctx_antitone, array[int] of var bool: y ::promise_ctx_monotone) = lex_less_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_reif.mzn0000644000175000017500000000062014536677021024450 0ustar kaolkaolinclude "count.mzn"; predicate fzn_global_cardinality_reif(array[int] of var int: x, array[int] of int: cover, array[int] of var int: counts, var bool: b) = b <-> ( forall(i in index_set(cover))( count(x, cover[i], counts[i]) ) /\ % Implied constraint length(x) >= sum(counts) ); libminizinc-2.8.2/share/minizinc/std/minimum.mzn0000644000175000017500000000062514536677021020423 0ustar kaolkaol/** @group globals.math Constrains \a m to be the minimum of the values in \a x. Assumptions: |\a x| > 0. */ predicate minimum(var float: m, array[int] of var float: x) = array_float_minimum(m, x); /** @group globals.math Constrains \a m to be the minimum of the values in \a x. Assumptions: |\a x| > 0. */ predicate minimum(var $$E: m, array[int] of var $$E: x) = array_int_minimum(m, x); libminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_set.mzn0000644000175000017500000000057214536677021023125 0ustar kaolkaolpredicate fzn_if_then_else_set(array[int] of var bool: c, array[int] of set of int: x, var set of int: y) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/ide/0000755000175000017500000000000014536677021016760 5ustar kaolkaollibminizinc-2.8.2/share/minizinc/std/ide/vis_geost.html0000644000175000017500000001677214536677021021665 0ustar kaolkaol MiniZinc Visualization libminizinc-2.8.2/share/minizinc/std/ide/vis_gantt.html0000644000175000017500000002613014536677021021646 0ustar kaolkaol MiniZinc Visualization
libminizinc-2.8.2/share/minizinc/std/ide/vis.mzn0000644000175000017500000011026314536677021020312 0ustar kaolkaol /*** @groupdef ide MiniZincIDE tools This library contains features designed for use from within the MiniZinc IDE. These are not guaranteed to work when run outside the IDE. */ /*** @groupdef ide.visualisation MiniZincIDE solution visualisation tools Provides functionality for web-based solution visualisation. All predefined visualisations are designed to used from :mzn:`output` items: .. code-block:: minizinc var 1..10: x; output vis_line(x, "x-value"); Multiple such output items can be used in a single model to open multiple visualisations concurrently. Custom visualisations can be created using the :mzn:`vis_server` function: .. code-block:: minizinc int: n; var 1..10: x; output :: vis_server("my-vis.html", (n: n)) (x: x); The file ``my-vis.html`` will be opened and the MiniZinc IDE JavaScript API can be used to listen for events and retrieve solutions. For more information, see :ref:`ch-visualisation`. */ /** @group ide.visualisation Launch a visualisation server for a custom visualisation using the given \a file. */ function ann: vis_server(string: file) = vis_server(file, <>); /** @group ide.visualisation Launch a visualisation server for a custom visualisation using the given \a file. The \a user_data value can be retrieved in the page using ``MiniZincIDE.getUserData()``. */ function ann: vis_server(string: file, opt $T: user_data) = mzn_output_section(mzn_vis_server(file, user_data), true); /** @group ide.visualisation Launch a visualisation server for a custom visualisation using the given \a file. The \a user_data value can be retrieved in the page using ``MiniZincIDE.getUserData()``. */ function ann: vis_server(string: file, array [$X] of opt $T: user_data) = mzn_output_section(mzn_vis_server(file, user_data), true); function string: mzn_vis_server(string: file, opt $T: user_data) = let { int: i = mzn_increment_counter("mzn_vis"); string: section = "mzn_vis_\(i)"; constraint trace_to_json_section(section, ( url: file, userData: user_data )); } in section; function string: mzn_vis_server(string: file, array [$X] of opt $T: user_data) = let { int: i = mzn_increment_counter("mzn_vis"); string: section = "mzn_vis_\(i)"; constraint trace_to_json_section(section, ( url: file, userData: user_data )); } in section; /** @group ide.visualisation Add a line graph of \a x with respect to solution time, labelling the trace \a label. */ function ann: vis_line(var int: x, string: label) = vis_line([x], [label]); /** @group ide.visualisation Add a line graph of \a x with respect to solution time, labelling the trace \a label. */ function ann: vis_line(var float: x, string: label) = vis_line([x], [label]); /** @group ide.visualisation Add line graphs of the values in \a x with respect to solution time on the same axes, labelling the series using their index. */ function ann: vis_line(array [$$E] of var int: x) = vis_line(x, [i: show(i) | i in index_set(x)]); /** @group ide.visualisation Add line graphs of the values in \a x with respect to solution time on the same axes, labelling the series using their index. */ function ann: vis_line(array [$$E] of var float: x) = vis_line(x, [i: show(i) | i in index_set(x)]); /** @group ide.visualisation Add line graphs of the values in \a x with respect to solution time on the same axes, labelling the series with \a series_labels. */ function ann: vis_line(array [$$E] of var int: x, array [$$E] of string: series_labels) = let { constraint assert( index_sets_agree(x, series_labels), "index set of series labels doesn't match x" ); constraint output_to_json_section( mzn_vis_server("std/ide/vis_scatter.html", ( 'type': "line-time", seriesLabels: series_labels )), x ); } in output_only; /** @group ide.visualisation Add line graphs of the values in \a x with respect to solution time on the same axes, labelling the series with \a series_labels. */ function ann: vis_line(array [$$E] of var float: x, array [$$E] of string: series_labels) = let { constraint assert( index_sets_agree(x, series_labels), "index set of series labels doesn't match x" ); constraint output_to_json_section( mzn_vis_server("std/ide/vis_scatter.html", ( 'type': "line-time", seriesLabels: series_labels )), x ); } in output_only; /** @group ide.visualisation Add a line graph of \a x against \a y, labelling the axes \a x_label and \a y_label respectively. */ function ann: vis_line( array [$$E] of var int: x, array [$$E] of var int: y, string: x_label, string: y_label ) = let { constraint assert( index_sets_agree(x, y), "x and y must have same index sets" ); constraint output_to_json_section( mzn_vis_server("std/ide/vis_scatter.html", ( 'type': "line", seriesLabels: [concat(["(", x_label, ",", y_label, ")"])], xLabel: x_label, yLabel: y_label )), [(x: x, y: y)] ); } in output_only; /** @group ide.visualisation Add a line graph of \a x against \a y, labelling the axes \a x_label and \a y_label respectively. */ function ann: vis_line( array [$$E] of var float: x, array [$$E] of var float: y, string: x_label, string: y_label ) = let { constraint assert( index_sets_agree(x, y), "x and y must have same index sets" ); constraint output_to_json_section( mzn_vis_server("std/ide/vis_scatter.html", ( 'type': "line", seriesLabels: [concat(["(", x_label, ",", y_label, ")"])], xLabel: x_label, yLabel: y_label )), [(x: x, y: y)] ); } in output_only; /** @group ide.visualisation Add a scatter plot of \a x against \a y, labelling the axes \a x_label and \a y_label respectively. */ function ann: vis_scatter( array [$$E] of var int: x, array [$$E] of var int: y, string: x_label, string: y_label ) = let { constraint assert( index_sets_agree(x, y), "x and y must have same index sets" ); constraint output_to_json_section( mzn_vis_server("std/ide/vis_scatter.html", ( 'type': "scatter", seriesLabels: [concat(["(", x_label, ",", y_label, ")"])], xLabel: x_label, yLabel: y_label )), [(x: x, y: y)] ); } in output_only; /** @group ide.visualisation Add a scatter plot of \a x against \a y, labelling the axes \a x_label and \a y_label respectively. */ function ann: vis_scatter( array [$$E] of var float: x, array [$$E] of var float: y, string: x_label, string: y_label ) = let { constraint assert( index_sets_agree(x, y), "x and y must have same index sets" ); constraint output_to_json_section( mzn_vis_server("std/ide/vis_scatter.html", ( 'type': ("scatter"), seriesLabels: [concat(["(", x_label, ",", y_label, ")"])], xLabel: x_label, yLabel: y_label )), [(x: x, y: y)] ); } in output_only; /** @group ide.visualisation Create a scatter-plot visualisation. The point (\a x, \a y) is added to the plot for each solution. @param x: the x coordinate @param y: the y coordinate @param x_label: the x-axis label @param y_label: the y-axis label @param series_label: the series label */ function ann: vis_scatter_cumulative( var int: x, var int: y, string: x_label, string: y_label, string: series_label) = vis_scatter_cumulative([x], [y], x_label, y_label, [series_label]); /** @group ide.visualisation Create a scatter-plot visualisation. The point (\a x, \a y) is added to the plot for each solution. @param x: the x coordinate @param y: the y coordinate @param x_label: the x-axis label @param y_label: the y-axis label @param series_label: the series label */ function ann: vis_scatter_cumulative( var float: x, var float: y, string: x_label, string: y_label, string: series_label ) = vis_scatter_cumulative([x], [y], x_label, y_label, [series_label]); /** @group ide.visualisation Create a scatter-plot visualisation with multiple series. The point (\a x[i], \a y[i]) for each series \a i is added to the plot for each solution. Series are labelled using the index set of \a x and \a y. @param x: the x coordinate for each series @param y: the y coordinate for each series @param x_label: the x-axis label @param y_label: the y-axis label */ function ann: vis_scatter_cumulative( array [$$E] of var int: x, array [$$E] of var int: y, string: x_label, string: y_label ) = vis_scatter_cumulative(x, y, x_label, y_label, [i: show(i) | i in index_set(x)]); /** @group ide.visualisation Create a scatter-plot visualisation with multiple series. The point (\a x[i], \a y[i]) for each series \a i is added to the plot for each solution. Series are labelled using the index set of \a x and \a y. @param x: the x coordinate for each series @param y: the y coordinate for each series @param x_label: the x-axis label @param y_label: the y-axis label */ function ann: vis_scatter_cumulative( array [$$E] of var float: x, array [$$E] of var float: y, string: x_label, string: y_label ) = vis_scatter_cumulative(x, y, x_label, y_label, [i: show(i) | i in index_set(x)]); /** @group ide.visualisation Create a scatter-plot visualisation with multiple series. The point (\a x[i], \a y[i]) for each series \a i is added to the plot for each solution. @param x: the x coordinate for each series @param y: the y coordinate for each series @param x_label: the x-axis label @param y_label: the y-axis label @param series_labels: the label for each series */ function ann: vis_scatter_cumulative( array [$$E] of var int: x, array [$$E] of var int: y, string: x_label, string: y_label, array [$$E] of string: series_labels ) = let { constraint assert( index_sets_agree(x, y), "x and y must have same index sets" ); constraint assert( index_sets_agree(x, series_labels), "index set of series labels doesn't match x and y" ); constraint output_to_json_section( mzn_vis_server("std/ide/vis_scatter.html", ( 'type': "scatter-cumulative", seriesLabels: series_labels, xLabel: x_label, yLabel: y_label )), [( x: x[i], y: y[i] ) | i in index_set(x)] ); } in output_only; /** @group ide.visualisation Create a scatter-plot visualisation with multiple series. The point (\a x[i], \a y[i]) for each series \a i is added to the plot for each solution. @param x: the x coordinate for each series @param y: the y coordinate for each series @param x_label: the x-axis label @param y_label: the y-axis label @param series_labels: the label for each series */ function ann: vis_scatter_cumulative( array [$$E] of var float: x, array [$$E] of var float: y, string: x_label, string: y_label, array [$$E] of string: series_labels ) = let { constraint assert( index_sets_agree(x, y), "x and y must have same index sets" ); constraint assert( index_sets_agree(x, series_labels), "index set of series labels doesn't match x and y" ); constraint output_to_json_section( mzn_vis_server("std/ide/vis_scatter.html", ( 'type': "scatter-cumulative", seriesLabels: series_labels, xLabel: x_label, yLabel: y_label )), [( x: x[i], y: y[i] ) | i in index_set(x)] ); } in output_only; /** @group ide.visualisation Visualise a bar chart of the values in \a x (labelled by index set) */ function ann: vis_bar(array [$$D] of var int: x) = vis_bar(x, [i: show(i) | i in index_set(x)]); /** @group ide.visualisation Visualise a bar chart of the values in \a x (labelled by index set) */ function ann: vis_bar(array [$$D] of var float: x) = vis_bar(x, [i: show(i) | i in index_set(x)]); /** @group ide.visualisation Visualise a bar chart of the values in \a x. Chart values are labelled with \a data_labels. */ function ann: vis_bar( array [$$D] of var int: x, array [$$D] of string: data_labels ) = let { constraint assert( index_sets_agree(x, data_labels), "x and data labels must have same index sets" ); constraint output_to_json_section( mzn_vis_server("std/ide/vis_bar.html", ( 'type': "bar", seriesLabels: <>, dataLabels: data_labels )), [(1, i): x[i]| i in index_set(x)] ); } in output_only; /** @group ide.visualisation Visualise a bar chart of the values in \a x. Chart values are labelled with \a data_labels. */ function ann: vis_bar( array [$$D] of var float: x, array [$$D] of string: data_labels ) = let { constraint output_to_json_section( mzn_vis_server("std/ide/vis_bar.html", ( 'type': "bar", seriesLabels: <>, dataLabels: data_labels )), [(1, i): x[i]| i in index_set(x)] ); } in output_only; /** @group ide.visualisation Visualise a bar chart with grouped data (labelled by index set). \a x[\p i, \p j] is the value for \p j in data series \p i. */ function ann: vis_bar(array [$$S, $$D] of var int: x) = vis_bar(x, [i: show(i) | i in index_set_1of2(x)], [i: show(i) | i in index_set_2of2(x)]); /** @group ide.visualisation Visualise a bar chart with grouped data (labelled by index set). \a x[\p i, \p j] is the value for \p j in data series \p i. */ function ann: vis_bar(array [$$S, $$D] of var float: x) = vis_bar(x, [i: show(i) | i in index_set_1of2(x)], [i: show(i) | i in index_set_2of2(x)]); /** @group ide.visualisation Visualise a bar chart with grouped data. \a x[\p i, \p j] is the value for \p j in data series \p i. Series are labelled with \a series_labels. Chart values are labelled with \a data_labels. */ function ann: vis_bar( array [$$S, $$D] of var int: x, array [$$S] of string: series_labels, array [$$D] of string: data_labels ) = let { constraint assert(index_set_1of2(x) == index_set(series_labels), "index set of series labels do not match x"); constraint assert(index_set_2of2(x) == index_set(data_labels), "index set of data labels do not match x"); constraint output_to_json_section( mzn_vis_server("std/ide/vis_bar.html", ( 'type': "bar", seriesLabels: series_labels, dataLabels: data_labels )), x ); } in output_only; /** @group ide.visualisation Visualise a bar chart with grouped data. \a x[\p i, \p j] is the value for \p j in data series \p i. Series are labelled with \a series_labels. Chart values are labelled with \a data_labels. */ function ann: vis_bar( array [$$S, $$D] of var float: x, array [$$S] of string: series_labels, array [$$D] of string: data_labels ) = let { constraint assert(index_set_1of2(x) == index_set(series_labels), "index set of series labels do not match x"); constraint assert(index_set_2of2(x) == index_set(data_labels), "index set of data labels do not match x"); constraint output_to_json_section( mzn_vis_server("std/ide/vis_bar.html", ( 'type': "bar", seriesLabels: series_labels, dataLabels: data_labels )), x ); } in output_only; /** @group ide.visualisation Visualise a column chart of the values in \a x (labelled by index set) */ function ann: vis_column(array [$$D] of var int: x) = vis_column(x, [i: show(i) | i in index_set(x)]); /** @group ide.visualisation Visualise a column chart of the values in \a x (labelled by index set) */ function ann: vis_column(array [$$D] of var float: x) = vis_column(x, [i: show(i) | i in index_set(x)]); /** @group ide.visualisation Visualise a column chart of the values in \a x. Chart values are labelled with \a data_labels. */ function ann: vis_column(array [$$D] of var int: x, array [$$D] of string: data_labels) = let { constraint assert(index_sets_agree(x, data_labels), "index set of data labels do not match x"); constraint output_to_json_section( mzn_vis_server("std/ide/vis_bar.html", ( 'type': "column", seriesLabels: <>, dataLabels: data_labels )), [(1, i): x[i]| i in index_set(x)] ); } in output_only; /** @group ide.visualisation Visualise a column chart of the values in \a x. Chart values are labelled with \a data_labels. */ function ann: vis_column(array [$$D] of var float: x, array [$$D] of string: data_labels) = let { constraint assert(index_sets_agree(x, data_labels), "index set of data labels do not match x"); constraint output_to_json_section( mzn_vis_server("std/ide/vis_bar.html", ( 'type': "column", seriesLabels: <>, dataLabels: data_labels )), [(1, i): x[i]| i in index_set(x)] ); } in output_only; /** @group ide.visualisation Visualise a column chart with grouped data (labelled by index set). \a x[\p i, \p j] is the value for \p j in data series \p i. */ function ann: vis_column(array [$$S, $$D] of var int: x) = vis_column(x, [i: show(i) | i in index_set_1of2(x)], [i: show(i) | i in index_set_2of2(x)]); /** @group ide.visualisation Visualise a column chart with grouped data (labelled by index set). \a x[\p i, \p j] is the value for \p j in data series \p i. */ function ann: vis_column(array [$$S, $$D] of var float: x) = vis_column(x, [i: show(i) | i in index_set_1of2(x)], [i: show(i) | i in index_set_2of2(x)]); /** @group ide.visualisation Visualise a column chart with grouped data. \a x[\p i, \p j] is the value for \p j in data series \p i. Series are labelled with \a series_labels. Chart values are labelled with \a data_labels. */ function ann: vis_column( array [$$S, $$D] of var int: x, array [$$S] of string: series_labels, array [$$D] of string: data_labels ) = let { constraint output_to_json_section( mzn_vis_server("std/ide/vis_bar.html", ( 'type': "column", seriesLabels: series_labels, dataLabels: data_labels )), x ); } in output_only; /** @group ide.visualisation Visualise a column chart with grouped data. \a x[\p i, \p j] is the value for \p j in data series \p i. Series are labelled with \a series_labels. Chart values are labelled with \a data_labels. */ function ann: vis_column( array [$$S, $$D] of var float: x, array [$$S] of string: series_labels, array [$$D] of string: data_labels ) = let { constraint assert(index_set_1of2(x) == index_set(series_labels), "index set of series labels do not match x"); constraint assert(index_set_2of2(x) == index_set(data_labels), "index set of data labels do not match x"); constraint output_to_json_section( mzn_vis_server("std/ide/vis_bar.html", ( 'type': "column", seriesLabels: series_labels, dataLabels: data_labels )), x ); } in output_only; /** @group ide.visualisation Visualise a Gantt chart of tasks with start times \a start and durations \a dur. The tasks are labelled using the index set of \a start. */ function ann: vis_gantt(array [$$E] of var int: start, array [$$E] of var int: dur) = vis_gantt(start, dur, [i: show(i) | i in index_set(start)]); /** @group ide.visualisation Visualise a Gantt chart of tasks with start times \a start and durations \a dur. The tasks are labelled using \a labels. */ function ann: vis_gantt( array [$$E] of var int: start, array [$$E] of var int: dur, array [$$E] of string: labels ) = let { constraint assert( index_sets_agree(start, dur) /\ index_sets_agree(start, labels), "index sets of start, dur, and labels must match" ); constraint output_to_json_section( mzn_vis_server("std/ide/vis_gantt.html", ( 'type': "gantt", labels: labels )), ( start: start, dur: dur) ); } in output_only; /** @group ide.visualisation Visualise a Gantt chart of tasks with start times \a start and durations \a dur. The tasks are labelled using \a labels and given the colours \a colors. */ function ann: vis_gantt( array [$$E] of var int: start, array [$$E] of var int: dur, array [$$E] of string: labels, array [$$E] of string: colors ) = let { constraint assert( index_sets_agree(start, dur) /\ index_sets_agree(start, labels)/\ index_sets_agree(start, colors), "index sets of start, dur, labels, and colors must match" ); constraint output_to_json_section( mzn_vis_server("std/ide/vis_gantt.html", ( 'type': "gantt", labels: labels, colors: colors )), ( start: start, dur: dur) ); } in output_only; function ann: vis_graph_internal( bool: directed, bool: highlight, array [$$N] of string: node_labels, array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$E] of string: edge_labels, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = let { constraint assert(index_sets_agree(from, to),"vis_graph: index set of from and to must be identical"); constraint assert(index_sets_agree(from, es),"vis_graph: index set of from and es must be identical"); constraint assert(index_sets_agree(edge_labels, es),"vis_graph: index set of edge_labels and es must be identical"); constraint assert(dom_array(from) subset index_set(ns),"vis_graph: nodes in from must be in index set of ns"); constraint assert(dom_array(to) subset index_set(ns),"vis_graph: nodes in to must be in index set of ns"); constraint output_to_json_section( mzn_vis_server("std/ide/vis_network.html", ( 'type': if directed then "digraph" else "graph" endif, highlight: highlight, nodes: [show(i) | i in index_set(ns)], nodeLabels: node_labels, from: [show(n) | n in from], to: [show(n) | n in to], edgeLabels: edge_labels )), ( ns: ns, es: es ) ); } in output_only; /** @group ide.visualisation Create a visualisation of the subgraph \a ns and \a es of a given undirected graph. The nodes are labelled using the index set of \a ns. @param from: the leaving node for each edge @param to: the entering node for each edge @param edge_labels: labels to use for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ function ann: vis_graph( array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$E] of string: edge_labels, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = vis_graph([i: show(i) | i in index_set(ns)], from, to, edge_labels, ns, es); /** @group ide.visualisation Create a visualisation of the subgraph \a ns and \a es of a given undirected graph. The nodes are labelled using the index set of \a ns and the edges are labelled using the index set of \a es. @param from: the leaving node for each edge @param to: the entering node for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ function ann: vis_graph( array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = vis_graph([i: show(i) | i in index_set(ns)], from, to, [i: show(i) | i in index_set(es)], ns, es); /** @group ide.visualisation Create a visualisation of the subgraph \a ns and \a es of a given undirected graph. @param node_labels: the label for each node @param from: the leaving node for each edge @param to: the entering node for each edge @param edge_labels: labels to use for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ function ann: vis_graph( array [$$N] of string: node_labels, array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$E] of string: edge_labels, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = vis_graph_internal(false, false, node_labels, from, to, edge_labels, ns, es); /** @group ide.visualisation Create a visualisation of the subgraph \a ns and \a es of a given undirected graph. The nodes are labelled using the index set of \a ns. The entire graph is drawn, with the given subgraph highlighted. @param from: the leaving node for each edge @param to: the entering node for each edge @param edge_labels: labels to use for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ function ann: vis_graph_highlight( array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$E] of string: edge_labels, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = vis_graph_highlight([i: show(i) | i in index_set(ns)], from, to, edge_labels, ns, es); /** @group ide.visualisation Create a visualisation of the subgraph \a ns and \a es of a given undirected graph. The nodes are labelled using the index set of \a ns and the edges are labelled using the index set of \a es. The entire graph is drawn, with the given subgraph highlighted. @param from: the leaving node for each edge @param to: the entering node for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ function ann: vis_graph_highlight( array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = vis_graph_highlight([i: show(i) | i in index_set(ns)], from, to, [i: show(i) | i in index_set(es)], ns, es); /** @group ide.visualisation Create a visualisation of the subgraph \a ns and \a es of a given undirected graph. The entire graph is drawn, with the given subgraph highlighted. @param node_labels: the label for each node @param from: the leaving node for each edge @param to: the entering node for each edge @param edge_labels: labels to use for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ function ann: vis_graph_highlight( array [$$N] of string: node_labels, array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$E] of string: edge_labels, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = vis_graph_internal(false, true, node_labels, from, to, edge_labels, ns, es); /** @group ide.visualisation Create a visualisation of the subgraph \a ns and \a es of a given directed graph. The nodes are labelled using the index set of \a ns. @param from: the leaving node for each edge @param to: the entering node for each edge @param edge_labels: labels to use for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ function ann: vis_digraph( array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$E] of string: edge_labels, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = vis_digraph([i: show(i) | i in index_set(ns)], from, to, edge_labels, ns, es); /** @group ide.visualisation Create a visualisation of the subgraph \a ns and \a es of a given directed graph. The nodes are labelled using the index set of \a ns and the edges are labelled using the index set of \a es. @param from: the leaving node for each edge @param to: the entering node for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ function ann: vis_digraph( array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = vis_digraph([i: show(i) | i in index_set(ns)], from, to, [i: show(i) | i in index_set(es)], ns, es); /** @group ide.visualisation Create a visualisation of the subgraph \a ns and \a es of a given directed graph. @param node_labels: the label for each node @param from: the leaving node for each edge @param to: the entering node for each edge @param edge_labels: labels to use for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ function ann: vis_digraph( array [$$N] of string: node_labels, array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$E] of string: edge_labels, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = vis_graph_internal(true, false, node_labels, from, to, edge_labels, ns, es); /** @group ide.visualisation Create a visualisation of the subgraph \a ns and \a es of a given directed graph. The nodes are labelled using the index set of \a ns. The entire graph is drawn, with the given subgraph highlighted. @param from: the leaving node for each edge @param to: the entering node for each edge @param edge_labels: labels to use for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ function ann: vis_digraph_highlight( array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$E] of string: edge_labels, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = vis_digraph_highlight([i: show(i) | i in index_set(ns)], from, to, edge_labels, ns, es); /** @group ide.visualisation Create a visualisation of the subgraph \a ns and \a es of a given directed graph. The nodes are labelled using the index set of \a ns and the edges are labelled using the index set of \a es. The entire graph is drawn, with the given subgraph highlighted. @param from: the leaving node for each edge @param to: the entering node for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ function ann: vis_digraph_highlight( array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = vis_digraph_highlight([i: show(i) | i in index_set(ns)], from, to, [i: show(i) | i in index_set(es)], ns, es); /** @group ide.visualisation Create a visualisation of the subgraph \a ns and \a es of a given directed graph. The entire graph is drawn, with the given subgraph highlighted. @param node_labels: the label for each node @param from: the leaving node for each edge @param to: the entering node for each edge @param edge_labels: labels to use for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ function ann: vis_digraph_highlight( array [$$N] of string: node_labels, array [$$E] of $$N: from, array [$$E] of $$N: to, array [$$E] of string: edge_labels, array [$$N] of var bool: ns, array [$$E] of var bool: es ) = vis_graph_internal(true, true, node_labels, from, to, edge_labels, ns, es); /** @group ide.visualisation Visualise the positions of 2-dimensional objects which take a particular shape composed of rectangles. @param rect_x: x-position of each rectangle @param rect_y: y-position of each rectangle @param rect_dx: width of each rectangle @param rect_dy: height of each rectangle @param shape: the rectangles which comprise each shape @param x: the x-position of each object @param y: the y-position of each object @param kind: which shape each object is */ function ann: vis_geost_2d( array [$$E] of int: rect_x, array [$$E] of int: rect_y, array [$$E] of int: rect_dx, array [$$E] of int: rect_dy, array [$$K] of set of $$E: shape, array [$$T] of var int: x, array [$$T] of var int: y, array [$$T] of var $$K: kind ) = let { constraint assert( index_sets_agree(rect_x, rect_y) /\ index_sets_agree(rect_x, rect_dx) /\ index_sets_agree(rect_x, rect_dy), "first four arguments must have same index set" ); constraint assert( index_sets_agree(x, y) /\ index_sets_agree(x, kind), "last three arguments must have same index set" ); constraint assert( dom_array(kind) subset index_set(shape), "kind must be a subset of the index set of shape" ); constraint output_to_json_section( mzn_vis_server("std/ide/vis_geost.html", ( 'type': "geost-2d", rectIndexSet: [show(i) | i in index_set(rect_x)], rectX: rect_x, rectY: rect_y, rectDx: rect_dx, rectDy: rect_dy, shapeIndexSet: [show(i) | i in index_set(shape)], shape: [(i, j): if j in shape[i] then show(j) else <> endif | i in index_set(shape), j in index_set(rect_x)] )), ( x: x, y: y, kind: [show(k) | k in kind]) ); } in output_only; /** @group ide.visualisation Visualise the positions of 2-dimensional objects which take a particular shape composed of rectangles. @param rect_size: the size of each rectangle @param rect_offset: the position of each rectangle @param shape: the rectangles which comprise each shape @param x: the position of each object @param kind: which shape each object is */ function ann: vis_geost_2d( array[$$E, 1..2] of int: rect_size, array[$$E, 1..2] of int: rect_offset, array[$$K] of set of $$E: shape, array[$$T, 1..2] of var int: x, array[$$T] of var $$K: kind ) = vis_geost_2d( rect_offset[.., 1], rect_offset[.., 2], rect_size[.., 1], rect_size[.., 2], shape, x[.., 1], x[.., 2], kind ); /** @group ide.visualisation Visualise the positions of 2-dimensional objects which take a particular shape composed of rectangles. @param rect_size: the size of each rectangle @param rect_offset: the position of each rectangle @param shape: the rectangles which comprise each shape @param x: the position of each object @param kind: which shape each object is */ function ann: vis_geost_2d( array[$$E] of tuple(int, int): rect_size, array[$$E] of tuple(int, int): rect_offset, array[$$K] of set of $$E: shape, array[$$T] of tuple(var int, var int): x, array[$$T] of var $$K: kind ) = vis_geost_2d( [i: rect_offset[i].1 | i in index_set(rect_offset)], [i: rect_offset[i].2 | i in index_set(rect_offset)], [i: rect_size[i].1 | i in index_set(rect_size)], [i: rect_size[i].2 | i in index_set(rect_size)], shape, [i: x[i].1 | i in index_set(x)], [i: x[i].2 | i in index_set(x)], kind ); libminizinc-2.8.2/share/minizinc/std/ide/vis_network.html0000644000175000017500000001014614536677021022222 0ustar kaolkaol MiniZinc Visualization
libminizinc-2.8.2/share/minizinc/std/ide/vis_scatter.html0000644000175000017500000001721314536677021022200 0ustar kaolkaol MiniZinc Visualization
libminizinc-2.8.2/share/minizinc/std/ide/vis_bar.html0000644000175000017500000000702014536677021021272 0ustar kaolkaol MiniZinc Visualization
libminizinc-2.8.2/share/minizinc/std/fzn_count_gt_par_reif.mzn0000644000175000017500000000035214536677021023313 0ustar kaolkaolinclude "fzn_count_gt_reif.mzn"; predicate fzn_count_gt_par_reif(array[int] of var int: x, int: y, int: c, var bool: b) = fzn_count_gt_reif(x,y,c,b); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/lex_chain_greatereq_orbitope.mzn0000644000175000017500000000124314536677021024641 0ustar kaolkaolinclude "lex_chain_lesseq_orbitope.mzn"; /** @group globals.lexicographic Requires that the columns of binary matrix \a a are lexicographically sorted, non-increasing. Moreover, the second parameter \a kind has the following meaning: 0: no further constraints, 1: set-partitioning orbitope, 2: set-packing orbitope */ predicate lex_chain_greatereq_orbitope( array[int, int] of var int: a, int: kind ) = if card(index_set_2of2(a)) > 1 then lex_chain_lesseq_orbitope( array2d( index_set_1of2(a), index_set_2of2(a), [a[i, max(index_set_2of2(a)) - j + min(index_set_2of2(a))] | i in index_set_1of2(a), j in index_set_2of2(a)] ), kind ) endif; libminizinc-2.8.2/share/minizinc/std/fzn_at_most_int.mzn0000644000175000017500000000052514536677021022144 0ustar kaolkaolinclude "count_fn.mzn"; %-----------------------------------------------------------------------------% % Requires at most 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate fzn_at_most_int(int: n, array[int] of var int: x, int: v) = count(x,v) <= n; libminizinc-2.8.2/share/minizinc/std/fzn_increasing_int_reif.mzn0000644000175000017500000000061414536677021023624 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate fzn_increasing_int_reif(array[int] of var int: x, var bool: b) = b <-> forall(i in index_set(x) diff { min(index_set(x)) }) (x[i-1] <= x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_mdd.mzn0000644000175000017500000000356314536677021020375 0ustar kaolkaolpredicate fzn_mdd(array[int] of var int: x, % variables constrained by MDD int: N, % number of nodes root is node 1 array[int] of int: level, % level of each node root is level 1, T is level length(x)+1 int: E, % number of edges array[int] of int: from, % edge leaving node 1..N array[int] of set of int: label, % value of variable array[int] of int: to % edge entering node 0..N where 0 = T node ) = let { set of int: NODE = 1..N; set of int: EDGE = 1..E; int: L = length(x); array[0..N] of var bool: bn; array[EDGE] of var bool: be; set of int: D = dom_array(x); } in bn[0] /\ % true node is true bn[1] /\ % root must hold % T1 each node except the true node enforces an outgoing edge forall(n in NODE)(bn[n] -> exists(e in EDGE where from[e] = n)(be[e])) /\ % T23 each edge enforces its endpoints forall(e in EDGE)((be[e] -> bn[from[e]]) /\ (be[e] -> bn[to[e]])) /\ % T4 each edge enforces its label forall(e in EDGE)(be[e] -> x[level[from[e]]] in label[e]) /\ % P1 each node enforces its outgoing edges forall(e in EDGE)(bn[from[e]] /\ x[level[from[e]]] in label[e] -> be[e]) /\ % P2 each node except the root enforces an incoming edge exists(e in EDGE where to[e] = 0)(be[e]) /\ forall(n in 2..N)(bn[n] -> exists(e in EDGE where to[e] = n)(be[e])) /\ % P3 each label has a support forall(i in 1..L, d in D) (x[i] = d -> exists(e in EDGE where level[from[e]] = i /\ d in label[e])(be[e])) /\ % P4 exactly one node at each level forall(i in 1..L) (sum(n in NODE where level[n] = i)(bn[n]) = 1); libminizinc-2.8.2/share/minizinc/std/fzn_value_precede_set_reif.mzn0000644000175000017500000000030214536677021024300 0ustar kaolkaolpredicate fzn_value_precede_set_reif(int: s, int: t, array[int] of var set of int: x, var bool: b) = abort("Reified value_precede/3 for sets is not supported."); libminizinc-2.8.2/share/minizinc/std/fzn_bounded_path_int.mzn0000644000175000017500000000047414536677021023135 0ustar kaolkaolinclude "path.mzn"; predicate fzn_bounded_path(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, var int: s, var int: t, array[int] of var bool: ns, array[int] of var bool: es, var int: K) = path(N,E,from,to,s,t,ns,es) /\ K = sum(e in 1..E)(es[e]*w[e]); libminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_var_int.mzn0000644000175000017500000000056414536677021023775 0ustar kaolkaolpredicate fzn_if_then_else_var_int(array[int] of var bool: c, array[int] of var int: x, var int: y) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_all_equal_set_reif.mzn0000644000175000017500000000055214536677021023443 0ustar kaolkaol%-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all equal. %-----------------------------------------------------------------------------% predicate fzn_all_equal_set_reif(array[int] of var set of int: x, var bool: b) = b <-> forall(i, j in index_set(x) where i < j) ( x[i] = x[j] ); libminizinc-2.8.2/share/minizinc/std/decreasing_float.mzn.deprecated.mzn0000644000175000017500000000022514536677021025137 0ustar kaolkaolpredicate decreasing_float(array[$X] of var float: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_lex_less_float_reif.mzn0000644000175000017500000000113314536677021023630 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than array 'y'. % Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_less_float_reif(array[int] of var float: x, array[int] of var float: y, var bool: c) = c <-> lex_less_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_value_precede_int_reif.mzn0000644000175000017500000000031114536677021024277 0ustar kaolkaolpredicate fzn_value_precede_int_reif(int: s, int: t, array[int] of var int: x, var bool: b) = abort("Reified value_precede/3 for integers is not supported."); libminizinc-2.8.2/share/minizinc/std/lex_less_set.mzn.deprecated.mzn0000644000175000017500000000063314536677021024342 0ustar kaolkaol predicate lex_less_set(array[int] of var set of int: x, array[int] of var set of int: y) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); predicate lex_lt_set(array[int] of var set of int: x, array[int] of var set of int: y) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/alldifferent.mzn0000644000175000017500000000024314536677021021403 0ustar kaolkaol% The actual definitions are in all_different.mzn. % This file is used to handle the case where users include % "alldifferent.mzn"; % include "all_different.mzn"; libminizinc-2.8.2/share/minizinc/std/fzn_count_lt_reif.mzn0000644000175000017500000000057614536677021022466 0ustar kaolkaolinclude "count_fn.mzn"; predicate fzn_count_lt_reif(array[int] of var int: x, var int: y, var int: c, var bool: b) = let { var int: z = count(x,y) } in b <-> z > c; % This needs to be written with a let rather than count(x,y) > c % so that the automatic rewriting of the latter doesn't kick in %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_var_opt_bool.mzn0000644000175000017500000000060314536677021025012 0ustar kaolkaolpredicate fzn_if_then_else_var_opt_bool(array[int] of var bool: c, array[int] of var opt bool: x, var opt bool: y) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_geost_bb_reif.mzn0000644000175000017500000000221314536677021022411 0ustar kaolkaolinclude "fzn_geost.mzn"; include "fzn_geost_reif.mzn"; predicate fzn_geost_bb_reif( int : k , array[int,int] of int : rect_size , array[int,int] of int : rect_offset , array[int ] of set of int : shape , array[int,int] of var int : x , array[int ] of var int : kind , array[int ] of var int : l , array[int ] of var int : u , var bool: b ) = % Two useful definitions let { set of int: DIMS = 1..k; set of int: OBJECTS = index_set(kind); } in b <-> ( % Posting the geost constraint fzn_geost(k, rect_size, rect_offset, shape, x, kind) /\ % Posting the bounding box constraints forall(o in OBJECTS)( forall(s in dom(kind[o]))( (kind[o] = s -> forall(r in shape[s], j in DIMS)( x[o,j] + rect_offset[r,j] >= l[j] /\ x[o,j] + rect_offset[r,j] + rect_size[r,j] <= u[j] ) ) ) )); libminizinc-2.8.2/share/minizinc/std/fzn_circuit_reif.mzn0000644000175000017500000000031014536677021022263 0ustar kaolkaolpredicate fzn_circuit_reif(array[int] of var int: x, var bool: b) = abort("Reified circuit/1 is not supported."); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_alldifferent_except_0_reif.mzn0000644000175000017500000000025514536677021025057 0ustar kaolkaolinclude "fzn_alldifferent_except_reif.mzn"; predicate fzn_alldifferent_except_0_reif(array[int] of var int: vs, var bool: b) = fzn_alldifferent_except_reif(vs,{0},b); libminizinc-2.8.2/share/minizinc/std/fzn_disjunctive_reif.mzn0000644000175000017500000000060514536677021023157 0ustar kaolkaolpredicate fzn_disjunctive_reif(array[int] of var int: s, array[int] of var int: d, var bool: b) = b <-> ( forall (i in index_set(d)) (d[i] >= 0) /\ forall (i,j in index_set(d) where i exists(i in index_set(x)) ( x[i] == y ); libminizinc-2.8.2/share/minizinc/std/lex_chain_lesseq_int.mzn.deprecated.mzn0000644000175000017500000000023514536677021026027 0ustar kaolkaolpredicate lex_chain_lesseq_int(array[int, int] of var int: a) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_increasing_int_opt.mzn0000644000175000017500000000123114536677021023475 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order %-----------------------------------------------------------------------------% predicate fzn_increasing_int_opt(array[int] of var opt int: x) = let { array[int] of var opt int: xx = array1d(x); array[1..length(xx)] of var int: y; constraint forall(i in 1..length(xx)) ( y[i] = if occurs(xx[i]) then deopt(xx[i]) elseif i = 1 then lb_array(xx) else y[i-1] endif ); } in forall (i in 2..length(y) where occurs(xx[i])) ( deopt(xx[i]) >= y[i-1] ); libminizinc-2.8.2/share/minizinc/std/fzn_bounded_dpath_enum_reif.mzn0000644000175000017500000000053414536677021024455 0ustar kaolkaolinclude "path.mzn"; predicate fzn_bounded_dpath_reif(array[int] of $$N: from, array[int] of $$N: to, array[int] of int: w, var $$N: s, var $$N: t, array[$$N] of var bool: ns, array[int] of var bool: es, var int: K, var bool: b) = b <-> ( dpath(from,to,s,t,ns,es) /\ K = sum(e in index_set(es))(es[e]*w[e]) ); libminizinc-2.8.2/share/minizinc/std/diffn.mzn0000644000175000017500000000136314536677021020036 0ustar kaolkaolinclude "fzn_diffn.mzn"; include "fzn_diffn_reif.mzn"; /** @group globals.packing Constrains rectangles \p i, given by their origins (\a x[\p i], \a y[\p i]) and sizes (\a dx[\p i], \a dy[\p i]), to be non-overlapping. Zero-width rectangles can still not overlap with any other rectangle. */ predicate diffn(array[int] of var int: x, array[int] of var int: y, array[int] of var int: dx, array[int] of var int: dy) = assert( index_set(x) = index_set(y) /\ index_set(x) = index_set(dx) /\ index_set(x) = index_set(dy), "diffn: index set mismatch", fzn_diffn(x,y,dx,dy) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/element_float.mzn.deprecated.mzn0000644000175000017500000000025514536677021024467 0ustar kaolkaolpredicate element_float(var $$E: i, array[$$E] of var float: x, var float: y) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/geost.mzn0000644000175000017500000002116614536677021020074 0ustar kaolkaolinclude "fzn_geost.mzn"; include "fzn_geost_reif.mzn"; include "fzn_geost_bb.mzn"; include "fzn_geost_bb_reif.mzn"; include "fzn_geost_smallest_bb.mzn"; include "fzn_geost_smallest_bb_reif.mzn"; include "fzn_geost_nonoverlap_k.mzn"; include "fzn_geost_nonoverlap_k_reif.mzn"; /** @group globals.packing A global non-overlap constraint for \a k dimensional objects. It enforces that no two objects overlap. @param k: the number of dimensions @param rect_size: the size of each box in \a k dimensions @param rect_offset: the offset of each box from the base position in \a k dimensions @param shape: the set of rectangles defining the \p i-th shape. @param x: the base position of each object. \a x[\p i,\p j] is the position of object \p i in. dimension \p j. @param kind: the shape used by each object. */ predicate geost( int : k , array[int,int] of int : rect_size , array[int,int] of int : rect_offset , array[int ] of set of int : shape , array[int,int] of var int : x , array[int ] of var int : kind ) = assert( % Some sanity checks index_set_1of2( rect_size ) = index_set_1of2(rect_offset) /\ index_set_2of2( rect_size ) = 1..k /\ index_set_2of2( rect_offset ) = 1..k /\ index_set( shape ) = 1..length(shape) /\ index_set_1of2( x ) = index_set(kind) /\ index_set_2of2( x ) = 1..k /\ forall(i in index_set(shape))( shape[i] subset index_set_1of2(rect_size) ), % Error message "geost: index sets of arguments are incorrect", assert( % More sanity checks forall(i in index_set(shape))(card(shape[i]) > 0), % Error message "geost: sets in shape must be non-empty", fzn_geost(k, rect_size, rect_offset, shape, x, kind) )); % End assert statements /** @group globals.packing A global non-overlap constraint for \a k dimensional objects. It enforces that no two objects overlap, and that all objects fit within a global \a k dimensional bounding box. @param k: the number of dimensions @param rect_size: the size of each box in \a k dimensions @param rect_offset: the offset of each box from the base position in \a k dimensions @param shape: the set of rectangles defining the \p i-th shape. @param x: the base position of each object. \a x[\p i,\p j] is the position of object \p i in dimension \p j. @param kind: the shape used by each object. @param l: is an array of lower bounds, \a l[\p i] is the minimum bounding box for all objects in dimension \p i. @param u: is an array of upper bounds, \a u[\p i] is the maximum bounding box for all objects in dimension \p i. */ predicate geost_bb( int : k , array[int,int] of int : rect_size , array[int,int] of int : rect_offset , array[int ] of set of int : shape , array[int,int] of var int : x , array[int ] of var int : kind , array[int ] of var int : l , array[int ] of var int : u ) = assert( % Some sanity checks index_set_1of2( rect_size ) = index_set_1of2(rect_offset) /\ index_set_2of2( rect_size ) = 1..k /\ index_set_2of2( rect_offset ) = 1..k /\ index_set( shape ) = 1..length(shape) /\ index_set_1of2( x ) = index_set(kind) /\ index_set_2of2( x ) = 1..k /\ forall(i in index_set(shape))( shape[i] subset index_set_1of2(rect_size) ), % Error message "geost_bb: index sets of arguments are incorrect", assert( % More sanity checks forall(i in index_set(shape))(card(shape[i]) > 0), % Error message "geost_bb: sets in shape must be non-empty", assert( % Sanity check index_set(l) = 1..k /\ index_set(u) = 1..k, % Error message "geost_bb: index set of bounds arrays is not 1.." ++ show(k), % Posting the geost constraint fzn_geost_bb(k, rect_size, rect_offset, shape, x, kind, l, u) ))); /** @group globals.packing A global non-overlap constraint for \a k dimensional objects. It enforces that no two objects overlap, and that all objects fit within a global \a k dimensional bounding box. In addition, it enforces that the bounding box is the smallest one containing all objects, i.e., each of the \a 2k boundaries is touched by at least by one object. @param k: the number of dimensions @param rect_size: the size of each box in \a k dimensions @param rect_offset: the offset of each box from the base position in \a k dimensions @param shape: the set of rectangles defining the \p i-th shape. @param x: the base position of each object. \a x[\p i,\p j] is the position of object \p i in dimension \p j. @param kind: the shape used by each object. @param l: is an array of lower bounds, \a l[\p i] is the minimum bounding box for all objects in dimension \p i. @param u: is an array of upper bounds, \a u[\p i] is the maximum bounding box for all objects in dimension \p i. */ predicate geost_smallest_bb( int : k , array[int,int] of int : rect_size , array[int,int] of int : rect_offset , array[int ] of set of int : shape , array[int,int] of var int : x , array[int ] of var int : kind , array[int ] of var int : l , array[int ] of var int : u ) = assert( % Some sanity checks index_set_1of2( rect_size ) = index_set_1of2(rect_offset) /\ index_set_2of2( rect_size ) = 1..k /\ index_set_2of2( rect_offset ) = 1..k /\ index_set( shape ) = 1..length(shape) /\ index_set_1of2( x ) = index_set(kind) /\ index_set_2of2( x ) = 1..k /\ forall(i in index_set(shape))( shape[i] subset index_set_1of2(rect_size) ), % Error message "geost_bb: index sets of arguments are incorrect", assert( % More sanity checks forall(i in index_set(shape))(card(shape[i]) > 0), % Error message "geost_bb: sets in shape must be non-empty", % A few useful definitions let { set of int: DIMS = 1..k; set of int: SHAPES = 1..length(shape); set of int: OBJECTS = index_set(kind); } in ( assert( % Sanity check index_set(l) = 1..k /\ index_set(u) = 1..k, % Error message "geost_bb: index set of bounds arrays is not 1.." ++ show(k), % Posting the geost constraint fzn_geost_smallest_bb(k, rect_size, rect_offset, shape, x, kind, l, u) )))); /** @group globals.packing A non-overlap constraint for two \a k dimensional objects. It enforces that there is at least one dimension where the objects occupy a different space. @param x1: coordinate of each dimension for the first object @param w1: width of each dimension for the first object @param x2: coordinate of each dimension for the second object @param w2: width of each dimension for the second object */ predicate geost_nonoverlap_k( array[int] of var int : x1, array[int] of int : w1, array[int] of var int : x2, array[int] of int : w2 ) = assert( % Some sanity checks index_set( x1 ) = index_set( w1 ) /\ index_set( x1 ) = index_set( x2 ) /\ index_set( x1 ) = index_set( w2 ), % Error message "geost_nonoverlap_k: index sets of arguments do not match", % Non-overlap constraint fzn_geost_nonoverlap_k(x1,w1,x2,w2) ); test geost_nonoverlap_k( array[int] of int: x1, array[int] of int: w1, array[int] of int: x2, array[int] of int: w2 ) = assert( % Some sanity checks index_set( x1 ) = index_set( w1 ) /\ index_set( x1 ) = index_set( x2 ) /\ index_set( x1 ) = index_set( w2 ), % Error message "geost_nonoverlap_k: index sets of arguments do not match", % Non-overlap test exists(j in index_set(x1))( x1[j] + w1[j] <= x2[j] \/ x2[j] + w2[j] <= x1[j] ) ); libminizinc-2.8.2/share/minizinc/std/fzn_inverse.mzn0000644000175000017500000000045614536677021021302 0ustar kaolkaolpredicate fzn_inverse(array[int] of var int: f, array[int] of var int: invf) = forall(i in index_set(f)) ( f[i] in index_set(invf) /\ (invf[f[i]] == i) ) /\ forall(j in index_set(invf)) ( invf[j] in index_set(f) /\ (f[invf[j]] == j) ); libminizinc-2.8.2/share/minizinc/std/strictly_increasing.mzn0000644000175000017500000000331414536677021023025 0ustar kaolkaolinclude "fzn_strictly_increasing_int.mzn"; include "fzn_strictly_increasing_int_opt.mzn"; include "fzn_strictly_increasing_int_reif.mzn"; include "fzn_strictly_increasing_int_opt_reif.mzn"; include "fzn_strictly_increasing_bool.mzn"; include "fzn_strictly_increasing_bool_reif.mzn"; include "analyse_all_different.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is in strict increasing order %-----------------------------------------------------------------------------% /** @group globals.sort Requires that the array \a x is in a stricly increasing order (duplicates are *not* allowed). */ predicate strictly_increasing(array[$X] of var bool: x) = analyse_all_different(array1d(x)) /\ fzn_strictly_increasing_bool(array1d(x)); predicate strictly_increasing_reif(array[$X] of var bool: x, var bool: b) = fzn_strictly_increasing_bool_reif(array1d(x),b); /** @group globals.sort Requires that the array \a x is in a stricly increasing order (duplicates are *not* allowed). */ predicate strictly_increasing(array[$X] of var int: x) = analyse_all_different(array1d(x)) /\ fzn_strictly_increasing_int(array1d(x)); /** @group globals.sort Requires that the array \a x is in a stricly increasing order (duplicates are *not* allowed). */ predicate strictly_increasing(array[$X] of var opt int: x) = analyse_all_different(array1d(x)) /\ fzn_strictly_increasing_int_opt(array1d(x)); predicate strictly_increasing_reif(array[$X] of var int: x, var bool: b) = fzn_strictly_increasing_int_reif(array1d(x),b); predicate strictly_increasing_reif(array[$X] of var opt int: x, var bool: b) = fzn_strictly_increasing_int_opt_reif(array1d(x),b); libminizinc-2.8.2/share/minizinc/std/lex_less_float.mzn0000644000175000017500000000151214536677021021747 0ustar kaolkaolinclude "lex_less.mzn"; include "fzn_lex_less_float.mzn"; include "fzn_lex_less_float_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than array 'y'. % Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate lex_less_float(array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_monotone) = fzn_lex_less_float(x, y); predicate lex_lt_float(array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_monotone) = lex_less(x, y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/circuit.mzn0000644000175000017500000000054614536677021020414 0ustar kaolkaolinclude "fzn_circuit.mzn"; include "fzn_circuit_reif.mzn"; /** @group globals.graph Constrains the elements of \a x to define a circuit where \a x[\p i] = \p j means that \p j is the successor of \p i. */ predicate circuit(array[$$E] of var $$E: x) = fzn_circuit(x); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/arg_max_int.mzn0000644000175000017500000000017614536677021021241 0ustar kaolkaolinclude "fzn_arg_max_int.mzn"; predicate maximum_arg_int(array[$$E] of var int: x, var $$E: i) = fzn_maximum_arg_int(x, i); libminizinc-2.8.2/share/minizinc/std/fzn_inverse_in_range_reif.mzn0000644000175000017500000000061014536677021024141 0ustar kaolkaolpredicate fzn_inverse_in_range_reif(array[int] of var int: f, array[int] of var int: invf, var bool: b) = b <-> ( forall(i in index_set(f)) ( f[i] in index_set(invf) -> (invf[f[i]] == i) ) /\ forall(j in index_set(invf)) ( invf[j] in index_set(f) -> (f[invf[j]] == j) ) ); libminizinc-2.8.2/share/minizinc/std/among_fn.mzn0000644000175000017500000000052014536677021020526 0ustar kaolkaolinclude "fzn_among.mzn"; /** @group globals.counting Returns the number of variables in \a x that take one of the values in \a v. */ function var int: among(array[$X] of var $$E: x, set of $$E: v) :: promise_total = let { var 0..length(x): n ::is_defined_var; constraint fzn_among(n, array1d(x), v) ::defines_var(n); } in n; libminizinc-2.8.2/share/minizinc/std/fzn_cost_regular_reif.mzn0000644000175000017500000000043414536677021023321 0ustar kaolkaolpredicate fzn_cost_regular_reif(array[int] of var int: x, int: Q, int: S, array[int,int] of int: d, int: q0, set of int: F, array[int,int] of int: c, var int: C, var bool: b) = abort("Reified cost_regular is not supported."); libminizinc-2.8.2/share/minizinc/std/fzn_all_disjoint.mzn0000644000175000017500000000024514536677021022276 0ustar kaolkaolinclude "fzn_disjoint.mzn"; predicate fzn_all_disjoint(array[int] of var set of int: S) = forall(i,j in index_set(S) where i < j) ( fzn_disjoint(S[i], S[j]) ); libminizinc-2.8.2/share/minizinc/std/fzn_neural_net_reif.mzn0000644000175000017500000000113114536677021022757 0ustar kaolkaolpredicate fzn_neural_net_reif(array[int] of var float: inputs, array[int] of int: input_ids, array[int] of var float: outputs, array[int] of int: output_ids, array[int] of float: bias, array[int] of float: edge_weight, array[int] of int: edge_parent, array[int] of int: first_edge, NEURON_TYPE: neuron_type, var bool: b) = abort("Reification of neural_net constraint is not supported"); libminizinc-2.8.2/share/minizinc/std/fzn_alternative.mzn0000644000175000017500000000041514536677021022140 0ustar kaolkaolinclude "span.mzn"; predicate fzn_alternative(var opt int: s0, var int: d0, array[int] of var opt int: s, array[int] of var int: d) = sum(i in index_set(s))(occurs(s[i])) = occurs(s0) /\ span(s0,d0,s,d); libminizinc-2.8.2/share/minizinc/std/fzn_among_reif.mzn0000644000175000017500000000022614536677021021730 0ustar kaolkaolpredicate fzn_among_reif(var int: n, array[int] of var int: x, set of int: v, var bool: b) = b <-> ( n == sum(i in index_set(x)) ( x[i] in v ) ); libminizinc-2.8.2/share/minizinc/std/fzn_link_set_to_booleans_reif.mzn0000644000175000017500000000024014536677021025017 0ustar kaolkaolpredicate fzn_link_set_to_booleans_reif(var set of int: s, array[int] of var bool: b, var bool: bb) = bb <-> forall(i in index_set(b)) ( b[i] <-> i in s ); libminizinc-2.8.2/share/minizinc/std/fzn_geost_smallest_bb_reif.mzn0000644000175000017500000000251114536677021024316 0ustar kaolkaolinclude "fzn_geost_bb.mzn"; include "fzn_geost_bb_reif.mzn"; predicate fzn_geost_smallest_bb_reif( int : k , array[int,int] of int : rect_size , array[int,int] of int : rect_offset , array[int ] of set of int : shape , array[int,int] of var int : x , array[int ] of var int : kind , array[int ] of var int : l , array[int ] of var int : u , var bool: b ) = % Two useful definitions let { set of int: DIMS = 1..k; set of int: OBJECTS = index_set(kind); } in b <-> ( % Posting the geost constraint fzn_geost_bb(k, rect_size, rect_offset, shape, x, kind, l, u) /\ % Posting the smallest bounding box constraints forall(j in DIMS)( % Lower boundary exists(o in OBJECTS, s in dom(kind[o]))( kind[o] = s /\ exists(r in shape[s])( x[o,j] + rect_offset[r,j] == l[j] ) ) /\ % Upper boundary exists(o in OBJECTS, s in dom(kind[o]))( kind[o] = s /\ exists(r in shape[s])( x[o,j] + rect_offset[r,j] + rect_size[r,j] == u[j] ) ) ) ); libminizinc-2.8.2/share/minizinc/std/at_most.mzn0000644000175000017500000000146414536677021020420 0ustar kaolkaolinclude "fzn_at_most_int.mzn"; include "fzn_at_most_int_reif.mzn"; include "fzn_at_most_set.mzn"; include "fzn_at_most_set_reif.mzn"; /** @group globals.deprecated Requires at most \a n variables in \a x to take the value \a v. This constraint is deprecated. Use count(i in x)(i=v) <= n instead. */ predicate at_most(int: n, array[$X] of var $$E: x, $$E: v) = fzn_at_most_int(n, array1d(x), v); /** @group globals.counting Requires at most \a n variables in \a x to take the value \a v. */ predicate at_most(int: n, array[$X] of var set of $$E: x, set of $$E: v) = fzn_at_most_set(n, array1d(x), v); % Synonyms for the above. predicate atmost(int: n, array[$X] of var $$E: x, $$E: v) = at_most(n, x, v); predicate atmost(int: n, array[$X] of var set of $$E: x, set of $$E: v) = at_most(n, x, v); libminizinc-2.8.2/share/minizinc/std/fzn_all_different_int_opt.mzn0000644000175000017500000000132214536677021024152 0ustar kaolkaol%-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all different. %-----------------------------------------------------------------------------% include "alldifferent_except.mzn"; include "alldifferent_except_0.mzn"; predicate fzn_all_different_int_opt(array[int] of var opt int: x) = if had_zero(x) then let { int: dummy = lb_array(x) - 1; array [int] of var int: xx = [x[i] default dummy | i in index_set(x)]; } in alldifferent_except(xx, {dummy}) else let { array [int] of var int: xx = [x[i] default 0 | i in index_set(x)]; } in alldifferent_except_0(xx) endif; libminizinc-2.8.2/share/minizinc/std/redefinitions-2.0.mzn0000644000175000017500000000335014536677021022105 0ustar kaolkaol% This file contains redefinitions of standard builtins that can be overridden % by solvers. predicate bool_clause_reif(array[int] of var bool: as, array[int] of var bool: bs, var bool: b) = clause(as,bs++[b]) /\ forall (i in index_set(as)) (as[i] -> b) /\ forall (i in index_set(bs)) (bs[i] \/ b); predicate array_int_maximum(var int: m, array[int] of var int: x) = let { int: l = min(index_set(x)), int: u = max(index_set(x)), int: ly = lb_array(x), int: uy = ub_array(x), array[l..u] of var ly..uy: y } in y[l] = x[l] /\ m = y[u] /\ forall (i in l+1 .. u) ( y[i] == max(x[i],y[i-1]) ); predicate array_float_maximum(var float: m, array[int] of var float: x) = let { int: l = min(index_set(x)), int: u = max(index_set(x)), float: ly = lb_array(x), float: uy = ub_array(x), array[l..u] of var ly..uy: y } in y[l] = x[l] /\ m = y[u] /\ forall (i in l+1 .. u) ( y[i] == max(x[i],y[i-1]) ); predicate array_int_minimum(var int: m, array[int] of var int: x) = let { int: l = min(index_set(x)), int: u = max(index_set(x)), int: ly = lb_array(x), int: uy = ub_array(x), array[l..u] of var ly..uy: y } in y[l] = x[l] /\ m = y[u] /\ forall (i in l+1 .. u) ( y[i] == min(x[i],y[i-1]) ); predicate array_float_minimum(var float: m, array[int] of var float: x) = let { int: l = min(index_set(x)), int: u = max(index_set(x)), float: ly = lb_array(x), float: uy = ub_array(x), array[l..u] of var ly..uy: y } in y[l] = x[l] /\ m = y[u] /\ forall (i in l+1 .. u) ( y[i] == min(x[i],y[i-1]) ); libminizinc-2.8.2/share/minizinc/std/fzn_arg_sort_float_reif.mzn0000644000175000017500000000056014536677021023635 0ustar kaolkaolinclude "all_different.mzn"; predicate fzn_arg_sort_float_reif(array[int] of var float:x, array[int] of var int:p, var bool: b) = b <-> ( all_different(p) /\ forall(j in 1..length(x)-1) (x[p[j]] <= x[p[j+1]] /\ (x[p[j]] == x[p[j+1]] -> p[j] < p[j+1])) ); libminizinc-2.8.2/share/minizinc/std/count_geq.mzn0000644000175000017500000000177414536677021020742 0ustar kaolkaolinclude "fzn_count_geq_par.mzn"; include "fzn_count_geq.mzn"; include "fzn_count_geq_par_reif.mzn"; include "fzn_count_geq_reif.mzn"; /** @group globals.counting Constrains \a c to be greater than or equal to the number of occurrences of \a y in \a x. */ predicate count_geq(array[$X] of var $$E: x, var $$E: y, var int: c) = fzn_count_geq(array1d(x), y, c); /** @group globals.counting Constrains \a c to be strictly greater than the number of occurrences of \a y in \a x. */ predicate count_geq(array[$X] of var opt $$E: x, var $$E: y, var int: c) =let { % Set <> to something not y int: def = if 0 in dom(y) then lb(y)-1 else 0 endif; } in count_geq([i default def | i in x], y, c); /** @group globals.counting Constrains \a c to be greater than or equal to the number of occurrences of \a y in \a x. */ predicate count_geq(array[$X] of var $$E: x, $$E: y, int: c) = fzn_count_geq_par(array1d(x), y, c); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/redefinitions-2.1.1.mzn0000644000175000017500000000364714536677021022256 0ustar kaolkaol% This file contains redefinitions of standard builtins for version 2.1.1 % that can be overridden by solvers. function var $$E: min(var set of $$E: s) = let { var min(ub(s)) .. max(ub(s)): m = min([ e + (max(ub(s))+1-e)*(1 - (e in s)) | e in ub(s) ]) } in m; %% The following can be used as an alternative if the solver supports %% a FlatZinc builtin set_min: % predicate set_min(var set of int: s, var int: m); % % function var $$E: min(var set of $$E: s) = % if mzn_in_root_context(s) then min_t(s) else % let { constraint card(s) > 0 } in min_mt(s) endif; % % function var $$E: min_t(var set of $$E: s) ::promise_total = % let { % var min(ub(s))..max(ub(s)): ms ::is_defined_var; % constraint card(s) > 0; % constraint set_min(s,ms) ::defines_var(ms); % } in ms; % % function var $$E: min_mt(var set of $$E: s) ::promise_total = % let { % var set of ub(s) union {1}: x; % var bool: b = card(s) > 0; % constraint b -> x=s; % constraint b \/ 1 in x; % } in min_t(x); function var $$E: max(var set of $$E: s) = let { var min(ub(s)) .. max(ub(s)): m = max([ e + (min(ub(s))-1-e)*(1 - (e in s)) | e in ub(s) ]) } in m; %% The following can be used as an alternative if the solver supports %% a FlatZinc builtin set_max: % predicate set_max(var set of int: s, var int: m); % % function var $$E: max(var set of $$E: s) = % if mzn_in_root_context(s) then max_t(s) else % let { constraint card(s) > 0 } in max_mt(s) endif; % % function var $$E: max_t(var set of $$E: s) ::promise_total = % let { % var min(ub(s))..max(ub(s)): ms ::is_defined_var; % constraint card(s) > 0; % constraint set_max(s,ms) ::defines_var(ms); % } in ms; % % function var $$E: max_mt(var set of $$E: s) ::promise_total = % let { % var set of ub(s) union {1}: x; % var bool: b = card(s) > 0; % constraint b -> x=s; % constraint b \/ 1 in x; % } in max_t(x); libminizinc-2.8.2/share/minizinc/std/fzn_bin_packing_load.mzn0000644000175000017500000000105514536677021023066 0ustar kaolkaolpredicate fzn_bin_packing_load(array[int] of var int: load, array[int] of var int: bin, array[int] of int: w) = sum(load) = sum(w) /\ forall( i in index_set(bin) ) ( min(index_set(load)) <= bin[i] /\ bin[i] <= max(index_set(load)) ) /\ forall( b in index_set(load) ) ( load[b] = sum ( i in index_set(bin) ) ( w[i] * ( bin[i] = b ) ) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/element_set.mzn0000644000175000017500000000050214536677021021246 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' is the ith element of the array 'x'. %-----------------------------------------------------------------------------% predicate element_set( var $$E: i, array[$$E] of var set of $$T: x, var set of $$T: y ) = y = x[i]; libminizinc-2.8.2/share/minizinc/std/fzn_subgraph_int.mzn0000644000175000017500000000051714536677021022312 0ustar kaolkaolpredicate fzn_subgraph(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of var bool: ns, array[int] of var bool: es) = forall(e in 1..E) ( (es[e] -> ns[from[e]]) /\ (es[e] -> ns[to[e]]) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_bool.mzn0000644000175000017500000000055714536677021023270 0ustar kaolkaolpredicate fzn_if_then_else_bool(array[int] of var bool: c, array[int] of bool: x, var bool: y) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/nvalue.mzn0000644000175000017500000000105714536677021020242 0ustar kaolkaolinclude "fzn_nvalue.mzn"; include "fzn_nvalue_reif.mzn"; /** @group globals.alldifferent Requires that the number of distinct values in \a x is \a n. */ predicate nvalue(var int: n, array[$X] of var int: x) = fzn_nvalue(n, array1d(x)); /** @group globals.alldifferent Requires that the number of distinct values in \a x is \a n. */ predicate nvalue(var int: n, array[$X] of var opt int: x) = let { any: xdom = dom_array(x); int: def = if 0 in xdom then min(xdom) - 1 else 0 endif; } in nvalue(n + 1, [x_i default def | x_i in x] ++ [def]); libminizinc-2.8.2/share/minizinc/std/sum_set.mzn0000644000175000017500000000056314536677021020430 0ustar kaolkaolinclude "fzn_sum_set.mzn"; include "fzn_sum_set_reif.mzn"; /** @group globals.math Requires that the sum of the weights \a ws[\p i1]..\a ws[\p iN] equals \a s, where \a vs[\p i1]..\a vs[\p iN] are the elements appearing in set \a x */ predicate sum_set( array[$$X] of $$Y: vs, array[$$X] of int: ws, var set of $$Y: x, var int: s ) = fzn_sum_set(vs, ws, x, s); libminizinc-2.8.2/share/minizinc/std/subgraph.mzn0000644000175000017500000000413414536677021020562 0ustar kaolkaolinclude "fzn_subgraph_int.mzn"; include "fzn_subgraph_int_reif.mzn"; include "fzn_subgraph_enum.mzn"; include "fzn_subgraph_enum_reif.mzn"; /** @group globals.graph Constrains that \a ns and \a es is a subgraph of a given directed graph. @param N: the number of nodes in the given graph @param E: the number of edges in the given graph @param from: the leaving node 1..\a N for each edge @param to: the entering node 1..\a N for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate subgraph(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of var bool: ns, array[int] of var bool: es) = assert(index_set(from) = 1..E,"subgraph: index set of from must be 1..\(E)") /\ assert(index_set(to) = 1..E,"subgraph: index set of to must be 1..\(E)") /\ assert(index_set(ns) = 1..N,"subgraph: index set of ns must be 1..\(N)") /\ assert(index_set(es) = 1..E,"subgraph: index set of es must be 1..\(E)") /\ fzn_subgraph(N,E,from,to,ns,es); /** @group globals.graph Constrains that \a ns and \a es is a subgraph of a given directed graph. @param from: the leaving node for each edge @param to: the entering node for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate subgraph(array[$$E] of $$N: from, array[$$E] of $$N: to, array[$$N] of var bool: ns, array[$$E] of var bool: es) = assert(index_set(from) = index_set(to),"subgraph: index set of from and to must be identical") /\ assert(index_set(from) = index_set(es),"subgraph: index set of from and es must be identical") /\ assert(dom_array(from) subset index_set(ns),"subgraph: elements in from must be in index set of ns") /\ assert(dom_array(to) subset index_set(ns),"subgraph: elements in to must be in index set of ns") /\ fzn_subgraph(from,to,ns,es); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/increasing.mzn0000644000175000017500000000316614536677021021075 0ustar kaolkaolinclude "fzn_increasing_bool.mzn"; include "fzn_increasing_bool.mzn"; include "fzn_increasing_bool_reif.mzn"; include "fzn_increasing_float.mzn"; include "fzn_increasing_float_reif.mzn"; include "fzn_increasing_float_opt.mzn"; include "fzn_increasing_float_opt_reif.mzn"; include "fzn_increasing_int.mzn"; include "fzn_increasing_int_reif.mzn"; include "fzn_increasing_int_opt.mzn"; include "fzn_increasing_int_opt_reif.mzn"; include "fzn_increasing_set.mzn"; include "fzn_increasing_set_reif.mzn"; /** @group globals.sort Requires that the array \a x is in increasing order (duplicates are allowed). */ predicate increasing(array[$X] of var bool: x) = fzn_increasing_bool(array1d(x)); /** @group globals.sort Requires that the array \a x is in increasing order (duplicates are allowed). */ predicate increasing(array[$X] of var float: x) = fzn_increasing_float(array1d(x)); /** @group globals.sort Requires that the array \a x is in increasing order (duplicates are allowed). */ predicate increasing(array[$X] of var opt float: x) = fzn_increasing_float_opt(array1d(x)); /** @group globals.sort Requires that the array \a x is in increasing order (duplicates are allowed). */ predicate increasing(array[$X] of var int: x) = fzn_increasing_int(array1d(x)); /** @group globals.sort Requires that the array \a x is in increasing order (duplicates are allowed). */ predicate increasing(array[$X] of var opt int: x) = fzn_increasing_int_opt(array1d(x)); /** @group globals.sort Requires that the array \a x is in increasing order (duplicates are allowed). */ predicate increasing(array[$X] of var set of int: x) = fzn_increasing_set(array1d(x)); libminizinc-2.8.2/share/minizinc/std/lex_less_bool.mzn0000644000175000017500000000134314536677021021577 0ustar kaolkaolinclude "lex_less.mzn"; include "fzn_lex_less_bool.mzn"; include "fzn_lex_less_bool_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than array 'y'. % Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate lex_less_bool(array[int] of var bool: x, array[int] of var bool: y) = fzn_lex_less_bool(x, y); predicate lex_lt_bool(array[int] of var bool: x, array[int] of var bool: y) = lex_less(x, y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_arg_max_int_opt.mzn0000644000175000017500000000042014536677021022770 0ustar kaolkaolinclude "arg_max.mzn"; predicate fzn_maximum_arg_int_opt(array[int] of var opt int: x, var int: z) = let { int: def = if not had_zero(x) /\ lb_array(x) > 0 then 0 else lb_array(x) - 1 endif; } in maximum_arg(array1d(index_set(x), [xi default def | xi in x]), z); libminizinc-2.8.2/share/minizinc/std/fzn_inverse_set_reif.mzn0000644000175000017500000000072714536677021023163 0ustar kaolkaolpredicate fzn_inverse_set_reif(array[int] of var set of int: f, array[int] of var set of int: invf, var bool: b) = b <-> ( forall(i in index_set(f)) ( f[i] subset index_set(invf) ) /\ forall(j in index_set(invf)) ( invf[j] subset index_set(f) ) /\ forall(i in index_set(f), j in index_set(invf)) ( (j in f[i] <-> i in invf[j]) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_writes_seq_reif.mzn0000644000175000017500000000117614536677021023021 0ustar kaolkaolinclude "arg_max.mzn"; predicate fzn_writes_seq_reif(array[int] of var int: I, array[int] of var int: P, array[int] of var int: V, array[int] of var int: O, var bool: b) = b <-> forall (i in index_set(I)) ( let { array[1..length(V)+1] of var int: Vi = array1d(1..length(V)+1, reverse(V) ++ [I[i]]); array[1..length(V)+1] of var bool: Pi = array1d(1..length(V)+1, reverse([P[j] == i | j in index_set(V)]) ++ [true]); } in O[i] = Vi[arg_max(Pi)] ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_partiality.mzn0000644000175000017500000000071014536677021024506 0ustar kaolkaolpredicate fzn_if_then_else_partiality(array[int] of var bool: c, array[int] of var bool: def, var bool: b) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall(i in index_set(c)) ( (b /\ c[i] /\ d[i] -> def[i])) /\ forall (i in index_set(c)) (d[i] /\ c[i] /\ def[i] -> b); libminizinc-2.8.2/share/minizinc/std/fzn_path_enum.mzn0000644000175000017500000000140114536677021021576 0ustar kaolkaolinclude "tree.mzn"; include "subgraph.mzn"; predicate fzn_path(array[int] of $$N: from, array[int] of $$N: to, var $$N: s, var $$N: t, array[$$N] of var bool: ns, array[int] of var bool: es) = let { int: E = length(es); array[1..2*E] of int: dfrom = from ++ to; array[1..2*E] of int: dto = to ++ from; array[1..2*E] of var bool: des; } in /* ensure that the directed edges selected agree with undirected edges */ forall(e in 1..E)(es[e-1+min(index_set(es))] <-> (des[e] \/ des[e+E])) /\ /* duplicate the edges so that the we can use directed graph path */ fzn_dpath(dfrom,dto,s,t,ns,des); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_arg_max_bool_opt.mzn0000644000175000017500000000035514536677021023140 0ustar kaolkaolinclude "arg_max.mzn"; predicate fzn_maximum_arg_bool_opt(array[int] of var opt bool: x, var int: z) = let { array [index_set(x)] of var 0..2: dx = array1d(index_set(x), [(xi + 1) default 0 | xi in x]); } in maximum_arg(dx, z); libminizinc-2.8.2/share/minizinc/std/fzn_dpath_int_reif.mzn0000644000175000017500000000067414536677021022610 0ustar kaolkaolinclude "tree.mzn"; include "subgraph.mzn"; predicate fzn_dpath_reif(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: s, var int: t, array[int] of var bool: ns, array[int] of var bool: es, var bool: b) = b <-> ( dtree(N,E,from,to,s,ns,es) /\ dtree(N,E,to,from,t,ns,es) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_disjunctive_opt_reif.mzn0000644000175000017500000000062514536677021024043 0ustar kaolkaolpredicate fzn_disjunctive_opt_reif(array[int] of var opt int: s, array[int] of var int: d, var bool: b) = b <-> forall (i,j in index_set(d) where i= s[i]), constraint x == sum(i in is_1)(xi[i] * f[i] + (xi[i+1]-xi[i]) * s[i]), } in array2d(1..2, is_1, f++s); predicate fzn_piecewise_linear(var float: x, var float: y, array[int] of float: xi, array[int] of float: vi) = let { set of int: is = index_set(xi), constraint assert(is == index_set(vi) /\ 0 forall(i,j in index_set(x) where i < j)( x[i] + dx[i] <= x[j] \/ y[i] + dy[i] <= y[j] \/ x[j] + dx[j] <= x[i] \/ y[j] + dy[j] <= y[i] ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_arg_min_int_opt.mzn0000644000175000017500000000042014536677021022766 0ustar kaolkaolinclude "arg_min.mzn"; predicate fzn_minimum_arg_int_opt(array[int] of var opt int: x, var int: z) = let { int: def = if not had_zero(x) /\ ub_array(x) < 0 then 0 else ub_array(x) + 1 endif; } in minimum_arg(array1d(index_set(x), [xi default def | xi in x]), z); libminizinc-2.8.2/share/minizinc/std/decreasing_bool.mzn.deprecated.mzn0000644000175000017500000000022314536677021024763 0ustar kaolkaolpredicate decreasing_bool(array[$X] of var bool: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_dsteiner_reif.mzn0000644000175000017500000000057114536677021022447 0ustar kaolkaolpredicate fzn_dsteiner_reif(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, var int: r, array[int] of var bool: ns, array[int] of var bool: es, var int: K, var bool: b) = abort("Reified steiner constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_diffn_nonstrict_reif.mzn0000644000175000017500000000074314536677021024024 0ustar kaolkaolpredicate fzn_diffn_nonstrict_reif(array[int] of var int: x, array[int] of var int: y, array[int] of var int: dx, array[int] of var int: dy, var bool: b) = b <-> forall(i,j in index_set(x) where i < j)( dx[i] = 0 \/ dx[j] = 0 \/ dy[i]=0 \/ dy[j]=0 \/ x[i] + dx[i] <= x[j] \/ y[i] + dy[i] <= y[j] \/ x[j] + dx[j] <= x[i] \/ y[j] + dy[j] <= y[i] ); libminizinc-2.8.2/share/minizinc/std/fzn_symmetric_all_different_reif.mzn0000644000175000017500000000034014536677021025516 0ustar kaolkaolinclude "all_different.mzn"; predicate fzn_symmetric_all_different_reif(array[int] of var int:x, var bool: b) = b <-> ( all_different(x) /\ forall(i, j in index_set(x) where i!=j) (x[i] = j -> x[j] = i) ); libminizinc-2.8.2/share/minizinc/std/fzn_seq_precede_chain_int.mzn0000644000175000017500000000077014536677021024121 0ustar kaolkaolpredicate fzn_seq_precede_chain_int(array[int] of var int: X) = if length(X) = 0 then true else let { int : l = lb_array (X) ; % least possible value int : u = ub_array (X) ; % greatest possible value int : f = min ( index_set (X )); array [ index_set (X) ] of var l .. u: H; } in H[f] <= 1 /\ H[f] = max (X[f], 0) /\ forall ( i in index_set ( X) diff {f} ) ( H[i] <= H[i-1] + 1 /\ H[i] = max (X[i], H[i-1]) ) endif; libminizinc-2.8.2/share/minizinc/std/fzn_arg_max_float_opt.mzn0000644000175000017500000000033614536677021023311 0ustar kaolkaolinclude "arg_max.mzn"; predicate fzn_maximum_arg_float_opt(array[int] of var opt float: x, var int: z) = let { float: def = lb_array(x) - 1; } in maximum_arg(array1d(index_set(x), [xi default def | xi in x]), z); libminizinc-2.8.2/share/minizinc/std/fzn_distribute_reif.mzn0000644000175000017500000000062314536677021023006 0ustar kaolkaolpredicate fzn_distribute_reif(array[int] of var int: card, array[int] of var int: value, array[int] of var int: base, var bool: b) = b <-> forall (i in index_set(card)) ( card[i] == sum(j in index_set(base)) ( value[i] = base[j] ) ); libminizinc-2.8.2/share/minizinc/std/inverse_set.mzn0000644000175000017500000000065614536677021021302 0ustar kaolkaolinclude "fzn_inverse_set.mzn"; include "fzn_inverse_set_reif.mzn"; /** @group globals.channeling Constrains two arrays of set of int variables, \a f and \a invf, so that a \p j in f[\p i] iff \p i in invf[\p j]. All the values in each array's sets must be within the index set of the other array. */ predicate inverse_set( array[$$X] of var set of $$Y: f, array[$$Y] of var set of $$X: invf ) = fzn_inverse_set(f,invf); libminizinc-2.8.2/share/minizinc/std/global_cardinality_closed.mzn0000644000175000017500000001575714536677021024140 0ustar kaolkaolinclude "fzn_global_cardinality_closed.mzn"; include "fzn_global_cardinality_closed_reif.mzn"; include "fzn_global_cardinality_closed_opt.mzn"; include "fzn_global_cardinality_closed_set.mzn"; include "fzn_global_cardinality_low_up_closed.mzn"; include "fzn_global_cardinality_low_up_closed_reif.mzn"; include "fzn_global_cardinality_low_up_closed_opt.mzn"; include "fzn_global_cardinality_low_up_closed_set.mzn"; /** @group globals.counting Requires that the number of occurrences of \a cover[\p i] in \a x is \a counts[\p i]. The elements of \a x must take their values from \a cover. */ predicate global_cardinality_closed(array[$X] of var $$E: x, array[$Y] of $$E: cover, array[$Y] of var int: counts) = assert(index_sets_agree(cover, counts), "global_cardinality_closed: " ++ "cover has index sets " ++ show_index_sets(cover) ++ " and count has index sets " ++ show_index_sets(counts) ++ ", but they must have identical index sets", if length(x) == 0 then forall(c in array1d(counts))(c = 0) else fzn_global_cardinality_closed(array1d(x), array1d(cover), array1d(counts)) endif ); /** @group globals.counting Requires that the number of occurrences of \a cover[\p i] in \a x is \a counts[\p i]. The elements of \a x must take their values from \a cover or be absent. */ predicate global_cardinality_closed(array[$X] of var opt $$E: x, array[$Y] of $$E: cover, array[$Y] of var int: counts) = assert(index_sets_agree(cover, counts), "global_cardinality_closed: " ++ "cover and counts must have identical index sets", if length(x) == 0 then forall(c in array1d(counts))(c = 0) else fzn_global_cardinality_closed_opt(array1d(x), array1d(cover), array1d(counts)) endif ); /** @group globals.counting Requires that for all \p i, the value \a cover[\p i] appears at least \a lbound[\p i] and at most \a ubound[\p i] times in the array \a x. The elements of \a x must take their values from \a cover. */ predicate global_cardinality_closed(array[$X] of var $$E: x, array[$Y] of $$E: cover, array[$Y] of int: lbound, array[$Y] of int: ubound) = assert( index_sets_agree(cover,lbound) /\ index_sets_agree(cover,ubound), "global_cardinality_low_up_closed: " ++ "cover has index sets " ++ show_index_sets(cover) ++ ", lbound has index sets " ++ show_index_sets(lbound) ++ ", and ubound has index sets " ++ show_index_sets(lbound) ++ ", but they must have identical index sets", if length(x) == 0 then assert(forall(l in array1d(lbound))( l <= 0) /\ forall(u in array1d(ubound))( u >= 0) \/ length(cover) == 0, "global_cardinality_low_up_closed: " ++ "lbound and ubound must allow a count of 0 when x is empty, or also be empty", true) elseif length(cover) == 0 then assert(false,"global_cardinality_low_up_closed: " ++ "cover must be empty when x is empty", false) else fzn_global_cardinality_low_up_closed(array1d(x), array1d(cover), array1d(lbound), array1d(ubound)) endif ); /** @group globals.counting Requires that for all \p i, the value \a cover[\p i] appears at least \a lbound[\p i] and at most \a ubound[\p i] times in the array \a x. The elements of \a x must take their values from \a cover or be absent. */ predicate global_cardinality_closed(array[$X] of var opt $$E: x, array[$Y] of $$E: cover, array[$Y] of int: lbound, array[$Y] of int: ubound) = assert( index_sets_agree(cover,lbound) /\ index_sets_agree(cover,ubound), "global_cardinality_low_up_closed: " ++ "cover has index sets " ++ show_index_sets(cover) ++ ", lbound has index sets " ++ show_index_sets(lbound) ++ ", and ubound has index sets " ++ show_index_sets(lbound) ++ ", but they must have identical index sets", if length(x) == 0 then assert(forall(l in array1d(lbound))( l <= 0) /\ forall(u in array1d(ubound))( u >= 0) \/ length(cover) == 0, "global_cardinality_low_up_closed: " ++ "lbound and ubound must allow a count of 0 when x is empty, or also be empty", true) elseif length(cover) == 0 then assert(false,"global_cardinality_low_up_closed: " ++ "cover must be empty when x is empty", false) else fzn_global_cardinality_low_up_closed_opt(array1d(x), array1d(cover), array1d(lbound), array1d(ubound)) endif ); /** @group globals.counting Requires that the number of occurrences of \a cover[\p i] in \a x is \a counts[\p i]. The elements of \a x must take their values from \a cover or be absent. */ predicate global_cardinality_closed(array[$X] of var set of $$E: x, array[$Y] of $$E: cover, array[$Y] of var int: counts) = assert(index_sets_agree(cover, counts), "global_cardinality_closed: " ++ "cover has index sets " ++ show_index_sets(cover) ++ " and count has index sets " ++ show_index_sets(counts) ++ ", but they must have identical index sets", if length(x) == 0 then forall(c in array1d(counts))(c = 0) else fzn_global_cardinality_closed_set(array1d(x), array1d(cover), array1d(counts)) endif ); /** @group globals.counting Requires that for all \p i, the value \a cover[\p i] appears at least \a lbound[\p i] and at most \a ubound[\p i] times in the array \a x. The elements of \a x must take their values from \a cover or be absent. */ predicate global_cardinality_closed(array[$X] of var set of $$E: x, array[$Y] of $$E: cover, array[$Y] of int: lbound, array[$Y] of int: ubound) = assert( index_sets_agree(cover,lbound) /\ index_sets_agree(cover,ubound), "global_cardinality_low_up_closed: " ++ "cover has index sets " ++ show_index_sets(cover) ++ ", lbound has index sets " ++ show_index_sets(lbound) ++ ", and ubound has index sets " ++ show_index_sets(lbound) ++ ", but they must have identical index sets", if length(x) == 0 then assert(forall(l in array1d(lbound))( l <= 0) /\ forall(u in array1d(ubound))( u >= 0) \/ length(cover) == 0, "global_cardinality_low_up_closed: " ++ "lbound and ubound must allow a count of 0 when x is empty, or also be empty", true) elseif length(cover) == 0 then assert(false,"global_cardinality_low_up_closed: " ++ "cover must be empty when x is empty", false) else fzn_global_cardinality_low_up_closed_set(array1d(x), array1d(cover), array1d(lbound), array1d(ubound)) endif ); libminizinc-2.8.2/share/minizinc/std/fzn_dtree_int.mzn0000644000175000017500000000313414536677021021600 0ustar kaolkaolinclude "subgraph.mzn"; predicate fzn_dtree(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: r, array[int] of var bool: ns, array[int] of var bool: es) = let { set of int: NODE = 1..N; set of int: EDGE = 1..E; array[NODE] of var 0..N-1: dist; /* distance from root */ array[NODE] of var 0..N: parent; /* parent */ } in ns[r] /\ % the root must be chosen dist[r] = 0 /\ % root is at distance 0 forall(n in NODE) % nonselected nodes have parent 0 (not ns[n] -> parent[n] <= 0) /\ forall(n in NODE) % nonselected nodes have distance 0 (not ns[n] -> dist[n] = 0) /\ forall(n in NODE) % each in node except root must have a parent (ns[n] -> (n = r \/ parent[n] > 0)) /\ forall(n in NODE) % each node with a parent then parent is in (parent[n] > 0 -> (ns[n] /\ ns[parent[n]])) /\ forall(n in NODE) % each node with a parent is one more than its parent (parent[n] > 0 -> dist[n] = dist[parent[n]] + 1) /\ forall(n in NODE) % each node with a parent must have that edge in (parent[n] > 0 -> exists(e in EDGE)(es[e] /\ from[e] = parent[n] /\ to[e] = n)) /\ forall(e in EDGE) % each edge must be part of the parent relation (es[e] -> parent[to[e]] = from[e]) /\ sum(e in EDGE)(es[e]) = sum(n in NODE)(ns[n]) - 1 /\ % redundant relationship of trees subgraph(N,E,from,to,ns,es); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_roots.mzn0000644000175000017500000000047614536677021020777 0ustar kaolkaolpredicate fzn_roots(array[int] of var int: x, var set of int: s, var set of int: t) = % All values in 's' must map to a value in 't'. forall(i in ub(s)) ( i in s -> x[i] in t ) /\ forall(i in ub(t)) ( i in t -> forall(j in index_set(x)) (x[j] = i -> j in s ) ); libminizinc-2.8.2/share/minizinc/std/fzn_regular_nfa_reif.mzn0000644000175000017500000000041314536677021023112 0ustar kaolkaolpredicate fzn_regular_nfa_reif(array[int] of var int: x, int: Q, int: S, array[int,int] of set of int: d, int: q0, set of int: F, var bool: b) = abort("Reified regular_nfa constraint is not supported"); libminizinc-2.8.2/share/minizinc/std/fzn_lex_chain_less_int.mzn0000644000175000017500000000040714536677021023455 0ustar kaolkaolinclude "lex_less.mzn"; predicate fzn_lex_chain_less_int(array[int, int] of var int: a) = let { set of int: is2 = index_set_2of2(a); } in ( forall(j in is2 where j+1 in is2) ( lex_less(col(a, j), col(a, j+1)) ) ); libminizinc-2.8.2/share/minizinc/std/lex_chain_greater.mzn0000644000175000017500000000173614536677021022417 0ustar kaolkaolinclude "lex_chain_less.mzn"; /** @group globals.lexicographic Requires that the columns of matrix \a a are lexicographically sorted, strictly decreasing. */ predicate lex_chain_greater(array[int, int] of var bool: a) = if 1>=card(index_set_2of2(a)) then true else lex_chain_less( array2d( index_set_1of2(a), index_set_2of2(a), [a[i, max(index_set_2of2(a)) - j + min(index_set_2of2(a))] | i in index_set_1of2(a), j in index_set_2of2(a)] ) ) endif; /** @group globals.lexicographic Requires that the columns of matrix \a a are lexicographically sorted, strictly decreasing. */ predicate lex_chain_greater(array[int, int] of var int: a) = if 1>=card(index_set_2of2(a)) then true else lex_chain_less( array2d( index_set_1of2(a), index_set_2of2(a), [a[i, max(index_set_2of2(a)) - j + min(index_set_2of2(a))] | i in index_set_1of2(a), j in index_set_2of2(a)] ) ) endif; libminizinc-2.8.2/share/minizinc/std/fzn_count_geq_reif.mzn0000644000175000017500000000060114536677021022610 0ustar kaolkaolinclude "count_fn.mzn"; predicate fzn_count_geq_reif(array[int] of var int: x, var int: y, var int: c, var bool: b) = let { var int: z = count(x,y) } in b <-> z <= c; % This needs to be written with a let rather than count(x,y) <= c % so that the automatic rewriting of the latter doesn't kick in %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/arg_min_int.mzn.deprecated.mzn0000644000175000017500000000023714536677021024137 0ustar kaolkaolpredicate minimum_arg_int(array[$$E] of var int: x, var $$E: i) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_opt_int.mzn0000644000175000017500000000057014536677021024004 0ustar kaolkaolpredicate fzn_if_then_else_opt_int(array[int] of var bool: c, array[int] of opt int: x, var opt int: y) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/all_equal_int.mzn0000644000175000017500000000064114536677021021557 0ustar kaolkaolinclude "fzn_all_equal_int.mzn"; include "fzn_all_equal_int_reif.mzn"; %-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all equal. %-----------------------------------------------------------------------------% predicate all_equal_int(array[$X] of var int: x) = if length(x) <= 1 then true else fzn_all_equal_int(array1d(x)) endif; libminizinc-2.8.2/share/minizinc/std/value_precede_chain_set.mzn0000644000175000017500000000033614536677021023567 0ustar kaolkaolinclude "fzn_value_precede_chain_set.mzn"; include "fzn_value_precede_chain_set_reif.mzn"; predicate value_precede_chain_set(array[int] of int: c, array[int] of var set of int: x) = fzn_value_precede_chain_set(c, x); libminizinc-2.8.2/share/minizinc/std/exactly_set.mzn0000644000175000017500000000062714536677021021276 0ustar kaolkaolinclude "fzn_exactly_set.mzn"; include "fzn_exactly_set_reif.mzn"; %-----------------------------------------------------------------------------% % Requires exactly 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate exactly_set(int: n, array[$X] of var set of $$E: x, set of $$E: v) = fzn_exactly_set(n, array1d(x), v); libminizinc-2.8.2/share/minizinc/std/fzn_exactly_int.mzn0000644000175000017500000000052514536677021022147 0ustar kaolkaolinclude "count_fn.mzn"; %-----------------------------------------------------------------------------% % Requires exactly 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate fzn_exactly_int(int: n, array[int] of var int: x, int: v) = n == count(x, v); libminizinc-2.8.2/share/minizinc/std/global_cardinality_fn.mzn0000644000175000017500000000206314536677021023254 0ustar kaolkaolinclude "global_cardinality.mzn"; /** @group globals.counting Returns the number of occurrences of \a cover[\p i] in \a x. */ function array[$Y] of var int: global_cardinality(array[$X] of var $$E: x, array[$Y] of $$E: cover) :: promise_total = let { array[int] of int: cover1d = array1d(cover); array[index_set(cover1d)] of var 0..length(x): counts ::is_defined_var; constraint global_cardinality(array1d(x), cover1d, counts) ::defines_var(counts); } in arrayXd(cover, counts); /** @group globals.counting Returns the number of occurrences of \a cover[\p i] in \a x. */ function array[$Y] of var int: global_cardinality(array[$X] of var opt $$E: x, array[$Y] of $$E: cover) :: promise_total = let { array[int] of int: cover1d = array1d(cover); array[index_set(cover1d)] of var 0..length(x): counts ::is_defined_var; constraint global_cardinality(array1d(x), cover1d, counts) ::defines_var(counts); } in arrayXd(cover, counts); libminizinc-2.8.2/share/minizinc/std/dag.mzn0000644000175000017500000000171514536677021017504 0ustar kaolkaolinclude "fzn_dag.mzn"; include "fzn_dag_reif.mzn"; /** @group globals.graph Constrains the subgraph \a ns and \a es of a given directed graph to be a DAG. @param from: the leaving node for each edge @param to: the entering node for each edge @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate dag(array[$$E] of $$N: from, array[$$E] of $$N: to, array[$$N] of var bool: ns, array[$$E] of var bool: es) = assert(index_set(from) = index_set(to),"dreachable: index set of from and to must be identical") /\ assert(index_set(from) = index_set(es),"dreachable: index set of from and es must be identical") /\ assert(dom_array(from) subset index_set(ns),"dreachable: nodes in from must be in index set of ns") /\ assert(dom_array(to) subset index_set(ns),"dreachable: nodes in to must be in index set of ns") /\ fzn_dag(from,to,ns,es); libminizinc-2.8.2/share/minizinc/std/fzn_piecewise_linear_non_continuous.mzn0000644000175000017500000000344614536677021026300 0ustar kaolkaol/* * Function fzn_piecewise_linear_non_continuous_base creates * auxiliary variables for the intervals {x_start[i]..x_end[i]}, * and constrains them to correspond to the value of x. * The auxiliaries are reusable if we have several pwls * on the same set of intervals and x. */ function array[int, int] of var 0.0..1.0: fzn_piecewise_linear_non_continuous_base(var float: x, array[int] of float: x_start, array[int] of float: x_end) ::promise_total = let { set of int: is = index_set(x_start), array[is] of var 0.0..1.0: s, %% Segment variables array[is] of var 0..1: f, constraint 1 == sum(f), constraint forall(i in is)( if x_start[i] < x_end[i] then f[i] >= s[i] elseif x_start[i] == x_end[i] then s[i] == 0.0 else abort("piecewise linear discontinuous: interval \(i): x_end < x_start") endif), constraint x == sum(i in is)(x_start[i] * f[i] + (x_end[i]-x_start[i]) * s[i]), } in array2d(1..2, is, f++s); predicate fzn_piecewise_linear_non_continuous(var float: x, var float: y, array[int] of float: x_start, array[int] of float: x_end, array[int] of float: v_start, array[int] of float: v_end) = let { set of int: is = index_set(x_start), constraint assert(is == index_set(v_start) /\ is == index_set(v_end) /\ is == index_set(x_end) /\ 0= sum(counts); libminizinc-2.8.2/share/minizinc/std/fzn_circuit_opt.mzn0000644000175000017500000000040314536677021022143 0ustar kaolkaolinclude "subcircuit.mzn"; predicate fzn_circuit_opt(array[int] of var opt int: x) = subcircuit(array1d(index_set(x),[if occurs(x[i]) then deopt(x[i]) else i endif | i in index_set(x)])) /\ forall (i in index_set(x)) (occurs(x[i]) -> deopt(x[i]) != i); libminizinc-2.8.2/share/minizinc/std/fzn_bounded_path_int_reif.mzn0000644000175000017500000000054014536677021024134 0ustar kaolkaolinclude "path.mzn"; predicate fzn_bounded_path_reif(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, var int: s, var int: t, array[int] of var bool: ns, array[int] of var bool: es, var int: K, var bool: b) = b <-> ( path(N,E,from,to,s,t,ns,es) /\ K = sum(e in 1..E)(es[e]*w[e]) ); libminizinc-2.8.2/share/minizinc/std/increasing_int.mzn0000644000175000017500000000061714536677021021745 0ustar kaolkaolinclude "fzn_increasing_int.mzn"; include "fzn_increasing_int_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate increasing_int(array[$X] of var int: x) = fzn_increasing_int(array1d(x)); libminizinc-2.8.2/share/minizinc/std/lex_chain_less_bool.mzn0000644000175000017500000000100614536677021022735 0ustar kaolkaolinclude "fzn_lex_chain_less_bool.mzn"; include "fzn_lex_chain_less_bool_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the columns of matrix \a a are lexicographically sorted, % strictly increasing. %-----------------------------------------------------------------------------% predicate lex_chain_less_bool(array[int, int] of var bool: a) = fzn_lex_chain_less_bool(a); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_increasing_float.mzn0000644000175000017500000000063014536677021023130 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate fzn_increasing_float(array[int] of var float: x) = if length(x) > 1 then forall(i in index_set(x) diff { min(index_set(x)) }) (x[i-1] <= x[i]) endif; libminizinc-2.8.2/share/minizinc/std/fzn_regular_set.mzn0000644000175000017500000000160314536677021022136 0ustar kaolkaolpredicate fzn_regular_set( array[int] of var int: x, int: Q, set of int: S, array[int,int] of int: d, int: q0, set of int: F ) = let { % If x has index set m..n-1, then a[m] holds the initial state % (q0), and a[i+1] holds the state we're in after processing % x[i]. If a[n] is in F, then we succeed (ie. accept the string). int: m = min(index_set(x)), int: n = max(index_set(x)) + 1, array[m..n] of var 1..Q: a } in a[m] = q0 % Set a[0]. /\ forall(i in index_set(x)) ( x[i] in S % Do this in case it's a var. /\ a[i+1] = d[a[i], x[i]] % Determine a[i+1]. ) /\ a[n] in F; % Check the final state is in F. % Deprecated call predicate fzn_regular( array[int] of var int: x, int: Q, set of int: S, array[int,int] of int: d, int: q0, set of int: F ) = fzn_regular_set(x, Q, S, d, q0, F); libminizinc-2.8.2/share/minizinc/std/fzn_disjunctive_strict_opt.mzn0000644000175000017500000000034514536677021024425 0ustar kaolkaolinclude "fzn_disjunctive_strict_opt_decomp.mzn"; predicate fzn_disjunctive_strict_opt(array[int] of var opt int: s, array[int] of var int: d) = fzn_disjunctive_strict_opt_decomp(s,d);libminizinc-2.8.2/share/minizinc/std/value_precede_int.mzn.deprecated.mzn0000644000175000017500000000024514536677021025325 0ustar kaolkaolpredicate value_precede_int($$E: s, $$E: t, array[int] of var $$E: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_member_float_reif.mzn0000644000175000017500000000054114536677021023263 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array or set 'x'. %-----------------------------------------------------------------------------% predicate fzn_member_float_reif(array[int] of var float: x, var float: y, var bool: b) = b <-> exists(i in index_set(x)) ( x[i] == y ); libminizinc-2.8.2/share/minizinc/std/fzn_lex_chain_lesseq_bool_reif.mzn0000644000175000017500000000046014536677021025150 0ustar kaolkaolinclude "lex_lesseq.mzn"; predicate fzn_lex_chain_lesseq_bool_reif( array[int, int] of var bool: a, var bool: b) = let { set of int: is2 = index_set_2of2(a); } in b <-> ( forall(j in is2 where j+1 in is2) ( lex_lesseq(col(a, j), col(a, j+1)) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_at_least_set.mzn0000644000175000017500000000054614536677021022276 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires at least 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate fzn_at_least_set(int: n, array[int] of var set of int: x, set of int: v) = sum(i in index_set(x)) ( x[i] == v ) >= n; libminizinc-2.8.2/share/minizinc/std/fzn_regular_nfa_set_reif.mzn0000644000175000017500000000042214536677021023765 0ustar kaolkaolpredicate fzn_regular_nfa_reif(array[int] of var int: x, int: Q, set of int: S, array[int,int] of set of int: d, int: q0, set of int: F, var bool: b) = abort("Reified regular_nfa constraint is not supported"); libminizinc-2.8.2/share/minizinc/std/fzn_diffn.mzn0000644000175000017500000000064214536677021020712 0ustar kaolkaolpredicate fzn_diffn(array[int] of var int: x, array[int] of var int: y, array[int] of var int: dx, array[int] of var int: dy) = forall(i,j in index_set(x) where i < j)( x[i] + dx[i] <= x[j] \/ y[i] + dy[i] <= y[j] \/ x[j] + dx[j] <= x[i] \/ y[j] + dy[j] <= y[i] ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_dpath_int.mzn0000644000175000017500000000057214536677021021600 0ustar kaolkaolinclude "tree.mzn"; include "subgraph.mzn"; predicate fzn_dpath(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: s, var int: t, array[int] of var bool: ns, array[int] of var bool: es) = dtree(N,E,from,to,s,ns,es) /\ dtree(N,E,to,from,t,ns,es); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_var_opt_float.mzn0000644000175000017500000000060614536677021025167 0ustar kaolkaolpredicate fzn_if_then_else_var_opt_float(array[int] of var bool: c, array[int] of var opt float: x, var opt float: y) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_strict_lex2_reif.mzn0000644000175000017500000000060714536677021023074 0ustar kaolkaolinclude "lex_chain_less.mzn"; predicate fzn_strict_lex2_reif(array[int, int] of var int: x, var bool: b) = b <-> ( lex_chain_less(x) /\ lex_chain_less( %% transpose array2d(index_set_2of2(x), index_set_1of2(x), [x[i, j] | j in index_set_2of2(x), i in index_set_1of2(x)] ) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_lex_less_set_reif.mzn0000644000175000017500000000113714536677021023322 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than array 'y'. % Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_less_set_reif(array[int] of var set of int: x, array[int] of var set of int: y, var bool: c) = c <-> lex_less_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_bounded_dpath_int.mzn0000644000175000017500000000047714536677021023304 0ustar kaolkaolinclude "path.mzn"; predicate fzn_bounded_dpath(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, var int: s, var int: t, array[int] of var bool: ns, array[int] of var bool: es, var int: K) = dpath(N,E,from,to,s,t,ns,es) /\ K = sum(e in 1..E)(es[e]*w[e]); libminizinc-2.8.2/share/minizinc/std/disjunctive_strict_opt.mzn0000644000175000017500000000134314536677021023547 0ustar kaolkaolinclude "fzn_disjunctive_strict_opt.mzn"; include "fzn_disjunctive_strict_opt_reif.mzn"; /** @group globals.scheduling Requires that a set of tasks given by start times \a s and durations \a d do not overlap in time. Tasks with duration 0 CANNOT be scheduled at any time, but only when no other task is running. Start times are optional variables, so that absent tasks do not need to be scheduled. Assumptions: - forall \p i, \a d[\p i] >= 0 */ predicate disjunctive_strict(array[$$T] of var opt int: s, array[$$T] of var int: d) = assert(index_set(s) == index_set(d), "disjunctive: the array arguments must have identical index sets", fzn_disjunctive_strict_opt(s,d) ); libminizinc-2.8.2/share/minizinc/std/lex_lesseq_float.mzn0000644000175000017500000000151214536677021022275 0ustar kaolkaolinclude "fzn_lex_lesseq_float.mzn"; include "fzn_lex_lesseq_float_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate lex_lesseq_float(array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_monotone) = fzn_lex_lesseq_float(x, y); predicate lex_leq_float(array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_monotone) = lex_lesseq_float(x, y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/decreasing_set.mzn0000644000175000017500000000062714536677021021731 0ustar kaolkaolinclude "fzn_decreasing_set.mzn"; include "fzn_decreasing_set_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is in decreasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate decreasing_set(array[$X] of var set of int: x) = fzn_decreasing_set(array1d(x)); libminizinc-2.8.2/share/minizinc/std/fzn_strict_lex2.mzn0000644000175000017500000000050614536677021022065 0ustar kaolkaolinclude "lex_chain_less.mzn"; predicate fzn_strict_lex2(array[int, int] of var int: x) = lex_chain_less(x) /\ lex_chain_less( %% transpose array2d(index_set_2of2(x), index_set_1of2(x), [x[i, j] | j in index_set_2of2(x), i in index_set_1of2(x)] ) ); libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_closed_reif.mzn0000644000175000017500000000064314536677021026006 0ustar kaolkaolinclude "global_cardinality.mzn"; predicate fzn_global_cardinality_closed_reif(array[int] of var int: x, array[int] of int: cover, array[int] of var int: counts, var bool: b) = b <-> ( forall(i in index_set(x))( x[i] in { d | d in cover } ) /\ global_cardinality(x, cover, counts) ); libminizinc-2.8.2/share/minizinc/std/cumulative_opt.mzn0000644000175000017500000000173014536677021022006 0ustar kaolkaolinclude "fzn_cumulative_opt.mzn"; include "fzn_cumulative_opt_reif.mzn"; /** @group globals.scheduling Requires that a set of tasks given by start times \a s, durations \a d, and resource requirements \a r, never require more than a global resource bound \a b at any one time. Start times are optional variables, so that absent tasks do not need to be scheduled. Assumptions: - forall \p i, \a d[\p i] >= 0 and \a r[\p i] >= 0 */ predicate cumulative(array[int] of var opt int: s, array[int] of var int: d, array[int] of var int: r, var int: b) = assert(index_set(s) == index_set(d) /\ index_set(s) == index_set(r), "cumulative: the 3 array arguments must have identical index sets", if length(s) >= 1 then assert(lb_array(d) >= 0 /\ lb_array(r) >= 0, "cumulative: durations and resource usages must be non-negative", fzn_cumulative_opt(s,d,r,b) ) endif ); libminizinc-2.8.2/share/minizinc/std/lex2.mzn0000644000175000017500000000045414536677021017622 0ustar kaolkaolinclude "fzn_lex2.mzn"; include "fzn_lex2_reif.mzn"; /** @group globals.lexicographic Require adjacent rows and adjacent columns in the array \a x to be lexicographically ordered. Adjacent rows and adjacent columns may be equal. */ predicate lex2(array[int, int] of var int: x) = fzn_lex2(x); libminizinc-2.8.2/share/minizinc/std/fzn_count_eq_par.mzn0000644000175000017500000000031614536677021022301 0ustar kaolkaolinclude "fzn_count_eq.mzn"; predicate fzn_count_eq_par(array[int] of var int: x, int: y, int: c) = fzn_count_eq(x,y,c); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_increasing_set.mzn0000644000175000017500000000057314536677021022624 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate fzn_increasing_set(array[int] of var set of int: x) = forall(i in index_set(x) diff { min(index_set(x)) }) (x[i-1] <= x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_disjunctive_strict_opt_reif.mzn0000644000175000017500000000076414536677021025437 0ustar kaolkaolpredicate fzn_disjunctive_strict_opt_reif(array[int] of var opt int: s, array[int] of var int: d, var bool: b) = b <-> ( forall (i in index_set(d)) (d[i] >= 0) /\ forall (i,j in index_set(d) where i p[j] < p[j+1])); libminizinc-2.8.2/share/minizinc/std/member_float.mzn.deprecated.mzn0000644000175000017500000000024014536677021024277 0ustar kaolkaolpredicate member_float(array[int] of var float: x, var float: y) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_reachable_enum_reif.mzn0000644000175000017500000000137114536677021023563 0ustar kaolkaolpredicate fzn_reachable_reif(array[int] of $$N: from, array[int] of $$N: to, var $$N: r, array[$$N] of var bool: ns, array[int] of var bool: es, var bool: b) = let { int: E = length(es); set of int: NODE = index_set(ns); array[1..2*E] of NODE: dfrom = from ++ to; array[1..2*E] of NODE: dto = to ++ from; array[1..2*E] of var bool: des = es ++ es; array[NODE] of var bool: dns = array1d(NODE,ns); var NODE: dr = r; } in /* duplicate the edges so that we can use directed graph reachability */ b <-> fzn_dreachable(dfrom,dto,dr,dns,des); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/int_set_channel.mzn0000644000175000017500000000076114536677021022106 0ustar kaolkaolinclude "fzn_int_set_channel.mzn"; include "fzn_int_set_channel_reif.mzn"; /** @group globals.channeling Requires that array of int variables \a x and array of set variables \a y are related such that (\a x[\p i] = \p j) \( \leftrightarrow \) (\p i in \a y[\p j]). */ predicate int_set_channel(array[int] of var int: x, array[int] of var set of int: y) = fzn_int_set_channel(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/lex_chain_lesseq_int.mzn0000644000175000017500000000100414536677021023120 0ustar kaolkaolinclude "fzn_lex_chain_lesseq_int.mzn"; include "fzn_lex_chain_lesseq_int_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the columns of matrix \a a are lexicographically sorted, % non-decreasing. %-----------------------------------------------------------------------------% predicate lex_chain_lesseq_int(array[int, int] of var int: a) = fzn_lex_chain_lesseq_int(a); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/at_least_set.mzn0000644000175000017500000000063414536677021021417 0ustar kaolkaolinclude "fzn_at_least_set.mzn"; include "fzn_at_least_set_reif.mzn"; %-----------------------------------------------------------------------------% % Requires at least 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate at_least_set(int: n, array[$X] of var set of $$E: x, set of $$E: v) = fzn_at_least_set(n, array1d(x), v); libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_closed_opt.mzn0000644000175000017500000000056014536677021025661 0ustar kaolkaolinclude "global_cardinality.mzn"; predicate fzn_global_cardinality_closed_opt(array[int] of var opt int: x, array[int] of int: cover, array[int] of var int: counts) = forall (xi in x) (absent(xi) \/ deopt(xi) in { d | d in cover }) /\ global_cardinality(x, cover, counts); libminizinc-2.8.2/share/minizinc/std/regular.mzn0000644000175000017500000000651614536677021020416 0ustar kaolkaolinclude "fzn_regular.mzn"; include "fzn_regular_reif.mzn"; include "fzn_regular_set.mzn"; include "fzn_regular_set_reif.mzn"; /** @group globals.extensional The sequence of values in array \a x is accepted by the DFA with transition function \a d, initial state \a q0 and accepting states \a F. The transition function maps states (from enumerated type \a State) and values (from type \a Val) to states, or the absent value if the transition is not possible. */ predicate regular( array[int] of var $$Val: x, array[$$State,$$Val] of opt $$State: d, $$State: q0, set of $$State: F ) = let { any: State = index_set_1of2(d); any: Val = index_set_2of2(d); any: q_off = min(State) - 1; any: dd = [ (s,v): if occurs(d[s,v]) then deopt(d[s,v]) - q_off else 0 endif | s in State, v in Val ]; any: qq0 = q0 - q_off; any: FF = { i - q_off | i in F }; } in fzn_regular_set(x, card(State), Val, dd, qq0, FF); /** @group globals.extensional The sequence of values in array \a x (which must all be in the range 1..\a S) is accepted by the DFA of \a Q states with input 1..\a S and transition function \a d (which maps (1..\a Q, 1..\a S) -> 0..\a Q)) and initial state \a q0 (which must be in 1..\a Q) and accepting states \a F (which all must be in 1..\a Q). We reserve state 0 to be an always failing state. */ predicate regular( array[int] of var int: x, int: Q, int: S, array[int,int] of int: d, int: q0, set of int: F ) = assert(Q > 0, "regular: 'Q' must be greater than zero") /\ assert(S > 0, "regular: 'S' must be greater than zero") /\ assert( index_set_1of2(d) = 1..Q /\ index_set_2of2(d) == 1..S, "regular: the transition function 'd' must be [1..Q,1..S]", ) /\ assert( forall([d[i, j] in 0..Q | i in 1..Q, j in 1..S]), "regular: transition function 'd' points to states outside 0..Q", ) /\ assert( % Nb: we need the parentheses around the expression otherwise the % parser thinks it's a generator call! (q0 in 1..Q), "regular: start state 'q0' not in 1..Q", ) /\ assert( F subset 1..Q, "regular: final states in 'F' contain states outside 1..Q", ) /\ fzn_regular(x, Q, S, d, q0, F); /** @group globals.extensional The sequence of values in array \a x (which must all be in the set \a S) is accepted by the DFA of \a Q states with input \a S and transition function \a d (which maps (1..\a Q, \a S) -> 0..\a Q)) and initial state \a q0 (which must be in 1..\a Q) and accepting states \a F (which all must be in 1..\a Q). We reserve state 0 to be an always failing state. */ predicate regular( array[int] of var int: x, int: Q, set of int: S, array[int,int] of int: d, int: q0, set of int: F ) = assert(Q > 0, "regular: 'Q' must be greater than zero") /\ assert(card(S) > 0, "regular: 'S' must be non empty") /\ assert( index_set_1of2(d) = 1..Q /\ index_set_2of2(d) == S, "regular: the transition function 'd' must be [1..Q,S]", ) /\ assert( forall([d[i, j] in 0..Q | i in 1..Q, j in S]), "regular: transition function 'd' points to states outside 0..Q", ) /\ assert( % Nb: we need the parentheses around the expression otherwise the % parser thinks it's a generator call! (q0 in 1..Q), "regular: start state 'q0' not in 1..Q", ) /\ assert( F subset 1..Q, "regular: final states in 'F' contain states outside 1..Q", ) /\ fzn_regular_set(x, Q, S, d, q0, F); libminizinc-2.8.2/share/minizinc/std/fzn_arg_val_int.mzn0000644000175000017500000000027214536677021022110 0ustar kaolkaolinclude "fzn_arg_max_bool.mzn"; predicate fzn_arg_val_int(array[int] of var int: x, var int: v, var int: i) = fzn_maximum_arg_bool([j: x[j] == v | j in index_set(x)], i) /\ x[i] = v; libminizinc-2.8.2/share/minizinc/std/fzn_all_different_set_reif.mzn0000644000175000017500000000056514536677021024306 0ustar kaolkaol%-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all different. %-----------------------------------------------------------------------------% predicate fzn_all_different_set_reif(array[int] of var set of int: x, var bool: b) = b <-> forall(i,j in index_set(x) where i < j) ( x[i] != x[j] ); libminizinc-2.8.2/share/minizinc/std/value_precede_chain_int.mzn.deprecated.mzn0000644000175000017500000000026114536677021026465 0ustar kaolkaolpredicate value_precede_chain_int(array[int] of int: c, array[int] of var int: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_geost.mzn0000644000175000017500000000246014536677021020745 0ustar kaolkaolinclude "fzn_geost_nonoverlap_k.mzn"; predicate fzn_geost( int : k , array[int,int] of int : rect_size , array[int,int] of int : rect_offset , array[int ] of set of int : shape , array[int,int] of var int : x , array[int ] of var int : kind ) = % A few useful definitions assert(forall([has_bounds(ki) | ki in kind]), "fzn_geost: the `kind' argument must be bounded") /\ let { set of int: DIMS = 1..k; set of int: SHAPES = 1..length(shape); set of int: OBJECTS = index_set(kind); } in forall(o1, o2 in OBJECTS where o1 < o2)( forall(s1 in dom(kind[o1]), s2 in dom(kind[o2]))( (kind[o1] = s1 /\ kind[o2] = s2 -> forall(r1 in shape[s1], r2 in shape[s2])( fzn_geost_nonoverlap_k( [ x[o1,j] + rect_offset[r1,j] | j in DIMS ], [ rect_size[r1,j] | j in DIMS ], [ x[o2,j] + rect_offset[r2,j] | j in DIMS ], [ rect_size[r2,j] | j in DIMS ] ) ) ) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_regular.mzn0000644000175000017500000000151114536677021021261 0ustar kaolkaolpredicate fzn_regular(array[int] of var int: x, int: Q, int: S, array[int,int] of int: d, int: q0, set of int: F) = if length(x) = 0 then q0 in F else let { % If x has index set m..n-1, then a[m] holds the initial state % (q0), and a[i+1] holds the state we're in after processing % x[i]. If a[n] is in F, then we succeed (ie. accept the string). int: m = min(index_set(x)), int: n = max(index_set(x)) + 1, array[m..n] of var 1..Q: a } in a[m] = q0 /\ % Set a[0]. forall(i in index_set(x)) ( x[i] in 1..S /\ % Do this in case it's a var. a[i+1] = d[a[i], x[i]] % Determine a[i+1]. ) /\ a[n] in F % Check the final state is in F. endif;libminizinc-2.8.2/share/minizinc/std/cost_regular.mzn0000644000175000017500000000327414536677021021444 0ustar kaolkaolinclude "fzn_cost_regular.mzn"; include "fzn_cost_regular_reif.mzn"; /** @group globals.extensional The sequence of values in array \a x (which must all be in the range 1..\a S) is accepted by the DFA of \a Q states with input 1..\a S and transition function \a d (which maps (1..\a Q, 1..\a S) -> 0..\a Q)) and initial state \a q0 (which must be in 1..\a Q) and accepting states \a F (which all must be in 1..\a Q). We reserve state 0 to be an always failing state. Each edge has an associated cost \a c, and \a C is the sum of costs taken on the accepting path for \a x. */ predicate cost_regular(array[int] of var int: x, int: Q, int: S, array[int,int] of int: d, int: q0, set of int: F, array[int,int] of int: c, var int: C) = assert(Q > 0, "cost_regular: 'Q' must be greater than zero", assert(S > 0, "cost_regular: 'S' must be greater than zero", assert(index_set_1of2(d) = 1..Q /\ index_set_2of2(d) == 1..S, "cost_regular: the transition function 'd' must be [1..Q,1..S]", assert(index_set_1of2(c) = 1..Q /\ index_set_2of2(c) == 1..S, "cost_regular: the transition cost function 'c' must be [1..Q,1..S]", assert(forall([d[i, j] in 0..Q | i in 1..Q, j in 1..S]), "cost_regular: transition function 'd' points to states outside 0..Q", % Nb: we need the parentheses around the expression otherwise the % parser thinks it's a generator call! assert((q0 in 1..Q), "cost_regular: start state 'q0' not in 1..Q", assert(F subset 1..Q, "cost_regular: final states in 'F' contain states outside 1..Q", fzn_cost_regular(x,Q,S,d,q0,F,c,C) ))))))); libminizinc-2.8.2/share/minizinc/std/knapsack.mzn0000644000175000017500000000173114536677021020542 0ustar kaolkaolinclude "fzn_knapsack.mzn"; include "fzn_knapsack_reif.mzn"; /** @group globals.packing Requires that items are packed in a knapsack with certain weight and profit restrictions. Assumptions: - Weights \a w and profits \a p must be non-negative - \a w, \a p and \a x must have the same index sets @param w: weight of each type of item @param p: profit of each type of item @param x: number of items of each type that are packed @param W: sum of sizes of all items in the knapsack @param P: sum of profits of all items in the knapsack */ predicate knapsack( array[$$I] of int: w, array[$$I] of int:p, array[$$I] of var int: x, var int: W, var int: P ) = assert(index_set(w) = index_set(p) /\ index_set(w) = index_set(x), "index set of weights must be equal to index set of profits and index set of items", assert(lb_array(w) >= 0, "weights must be non-negative", assert(lb_array(p) >= 0, "profits must be non-negative", fzn_knapsack(w, p, x, W, P) ))); libminizinc-2.8.2/share/minizinc/std/writes.mzn0000644000175000017500000000264014536677021020264 0ustar kaolkaolinclude "fzn_writes.mzn"; include "fzn_writes_reif.mzn"; /** @group globals.array Creates a new array \a O from an input array \a I with a simultaneous change at positions \a P to values \a V \a I is an array of integers \a O is an array of integers with same index set as \a I \a P is an array of index values in \a I \a V is an array of integer values */ predicate writes(array[$$X] of var int: I, array[$$Y] of var int: P, array[$$Y] of var int: V, array[$$X] of var int: O) = assert(index_set(O) = index_set(I),"writes: index set of I must be same as O") /\ assert(index_set(P) = index_set(V),"writes: index set of P must be same as V") /\ fzn_writes(I, P, V, O); /** @group globals.array Returns a new array from an input array \a I with a simultaneous change at positions \a P to values \a V \a I is an array of integers \a P is an array of index values in \a I \a V is an array of integer values */ function array[$$X] of var int: writes(array[$$X] of var int: I, array[$$Y] of var int: P, array[$$Y] of var int: V) = assert(index_set(P) = index_set(V),"writes: index set of P must be same as V", let { array[index_set(I)] of var int: O; constraint fzn_writes(I,P,V,O); } in O); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_count_gt.mzn0000644000175000017500000000054614536677021021451 0ustar kaolkaolinclude "count_fn.mzn"; predicate fzn_count_gt(array[int] of var int: x, var int: y, var int: c) = let { var int: z = count(x,y) } in z < c; % This needs to be written with a let rather than count(x,y) < c % so that the automatic rewriting of the latter doesn't kick in %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_sort_reif.mzn0000644000175000017500000000026114536677021021615 0ustar kaolkaolinclude "sort_fn.mzn"; predicate fzn_sort_reif(array[int] of var int: x, array[int] of var int: y, var bool: b) = let { array[int] of var int: s = sort(x); } in b <-> s=y; libminizinc-2.8.2/share/minizinc/std/value_precede_chain.mzn0000644000175000017500000000257414536677021022722 0ustar kaolkaolinclude "fzn_value_precede_chain_int.mzn"; include "fzn_value_precede_chain_int_reif.mzn"; include "fzn_value_precede_chain_int_opt.mzn"; include "fzn_value_precede_chain_set.mzn"; include "fzn_value_precede_chain_set_reif.mzn"; /** @group globals.lexicographic Requires that \a c[\p i] precedes \a c[\p i +1] in the array \a x. Precedence means that if any element of \a x is equal to \a c[\p i +1], then another element of \a x with a lower index is equal to \a c[\p i]. */ predicate value_precede_chain(array[int] of $$E: c, array[int] of var $$E: x) = fzn_value_precede_chain_int(c, x); /** @group globals.lexicographic Requires that \a c[\p i] precedes \a c[\p i +1] in the array \a x. Precedence means that if any element of \a x is equal to \a c[\p i +1], then another element of \a x with a lower index is equal to \a c[\p i]. */ predicate value_precede_chain(array[int] of int: c, array[int] of var opt int: x) = fzn_value_precede_chain_int_opt(c, x); /** @group globals.lexicographic Requires that \a c[\p i] precedes \a c[\p i +1] in the array \a x. Precedence means that if an element of \a x contains \a c[\p i +1] but not \a c[\p i], then another element of \a x with lower index contains \a c[\p i] but not \a c[\p i +1]. */ predicate value_precede_chain(array[int] of $$E: c, array[int] of var set of $$E: x) = fzn_value_precede_chain_set(c, x); libminizinc-2.8.2/share/minizinc/std/fzn_cumulative_opt.mzn0000644000175000017500000000037114536677021022663 0ustar kaolkaolinclude "fzn_cumulative_opt_decomp.mzn"; predicate fzn_cumulative_opt(array[int] of var opt int: s, array[int] of var int: d, array[int] of var int: r, var int: b) = fzn_cumulative_opt_decomp(s,d,r,b); libminizinc-2.8.2/share/minizinc/std/alternative.mzn0000644000175000017500000000122514536677021021263 0ustar kaolkaolinclude "fzn_alternative.mzn"; include "fzn_alternative_reif.mzn"; /** @group globals.scheduling Alternative constraint for optional tasks. The task with start time \a s0 and duration \a d0 spans the optional tasks with start times \a s[\p i] and durations \a d[\p i]), and at most one of those tasks can occur. */ predicate alternative(var opt int: s0, var int: d0, array[int] of var opt int: s, array[int] of var int: d) = assert(index_set(s) = index_set(d), "alternative: index sets of third and fourth argument must be identical", fzn_alternative(s0, d0, s, d) ); libminizinc-2.8.2/share/minizinc/std/at_least_int.mzn0000644000175000017500000000061614536677021021416 0ustar kaolkaolinclude "fzn_at_least_int.mzn"; include "fzn_at_least_int_reif.mzn"; %-----------------------------------------------------------------------------% % Requires at least 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate at_least_int(int: n, array[$X] of var $$E: x, $$E: v) = fzn_at_least_int(n, array1d(x), v); libminizinc-2.8.2/share/minizinc/std/redefinitions-2.7.1.mzn0000644000175000017500000000057214536677021022256 0ustar kaolkaolpredicate float_ceil(var float: x, var int: y) = y - 1 < x /\ x <= y; predicate float_floor(var float: x, var int: y) = y <= x /\ x < y + 1; predicate float_round(var float: x, var int: y) = if lb(x) >= 0 then float_floor(x+0.5, y) elseif ub(x) <= 0 then float_ceil(x-0.5, y) else if x < 0 then float_ceil(x-0.5, y) else float_floor(x+0.5, y) endif endif; libminizinc-2.8.2/share/minizinc/std/lex_lesseq_int.mzn0000644000175000017500000000146214536677021021766 0ustar kaolkaolinclude "fzn_lex_lesseq_int.mzn"; include "fzn_lex_lesseq_int_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate lex_lesseq_int(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) = fzn_lex_lesseq_int(x, y); predicate lex_leq_int(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) = lex_lesseq_int(x, y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/global_cardinality_low_up_closed.deprecated.mzn0000644000175000017500000000057414536677021027613 0ustar kaolkaolpredicate global_cardinality_low_up_closed(array[$X] of var int: x, array[$Y] of int: cover, array[$Y] of int: lbound, array[$Y] of int: ubound) :: mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/lex_less_bool.mzn.deprecated.mzn0000644000175000017500000000060614536677021024502 0ustar kaolkaolpredicate lex_less_bool(array[int] of var bool: x, array[int] of var bool: y) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); predicate lex_lt_bool(array[int] of var bool: x, array[int] of var bool: y) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_opt_bool.mzn0000644000175000017500000000057314536677021024150 0ustar kaolkaolpredicate fzn_if_then_else_opt_bool(array[int] of var bool: c, array[int] of opt bool: x, var opt bool: y) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/piecewise_linear_non_continuous.mzn0000644000175000017500000000235714536677021025423 0ustar kaolkaolinclude "fzn_piecewise_linear_non_continuous.mzn"; include "fzn_piecewise_linear_non_continuous_reif.mzn"; /** @group globals.math Return the piecewise-linear function of \a x on the given (possibly disconnected) intervals. Each interval \p i connects (\a x_start[\p i], \a v_start[\p i]) to (\a x_end[\p i], \a v_end[\p i]). */ function var float: piecewise_linear(var float: x, array[int] of float: x_start, array[int] of float: x_end, array[int] of float: v_start, array[int] of float: v_end) ::promise_total = let { var float: res, constraint piecewise_linear(x, res, x_start,x_end, v_start,v_end), } in res; /** @group globals.math Constrains \a y(\a x) to be the piecewise-linear function on the given (possibly disconnected) intervals. Each interval \p i connects (\a x_start[\p i], \a v_start[\p i]) to (\a x_end[\p i], \a v_end[\p i]). */ predicate piecewise_linear(var float: x, var float: y, array[int] of float: x_start, array[int] of float: x_end, array[int] of float: v_start, array[int] of float: v_end ) = fzn_piecewise_linear_non_continuous(x, y, x_start,x_end, v_start,v_end); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/lex_lesseq_float.mzn.deprecated.mzn0000644000175000017500000000076014536677021025203 0ustar kaolkaolpredicate lex_lesseq_float(array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_monotone) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); predicate lex_leq_float(array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_monotone) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_at_most_set.mzn0000644000175000017500000000054414536677021022146 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires at most 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate fzn_at_most_set(int: n, array[int] of var set of int: x, set of int: v) = sum(i in index_set(x)) ( x[i] == v ) <= n; libminizinc-2.8.2/share/minizinc/std/decreasing_bool.mzn0000644000175000017500000000062414536677021022066 0ustar kaolkaolinclude "fzn_decreasing_bool.mzn"; include "fzn_decreasing_bool_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is in decreasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate decreasing_bool(array[$X] of var bool: x) = fzn_decreasing_bool(array1d(x)); libminizinc-2.8.2/share/minizinc/std/fzn_dconnected.mzn0000644000175000017500000000052714536677021021734 0ustar kaolkaolinclude "reachable.mzn"; predicate fzn_dconnected(array[int] of $$N: from, array[int] of $$N: to, array[$$N] of var bool: ns, array[int] of var bool: es) = let { var index_set(ns): r } in dreachable(from, to, r, ns, es); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/mdd.mzn0000644000175000017500000000613114536677021017512 0ustar kaolkaolinclude "fzn_mdd.mzn"; include "fzn_mdd_reif.mzn"; /** @group globals.extensional Requires that \a x defines a path from root to true node T through the (deterministic) Multivalued Decision Diagram (MDD) defined by the parameters. @param N: the number of nodes, the root node is node 1 @param level: the level of each node, the root is level 1, T is level \a length(x)+1 @param E: the number of edges @param from: the leaving node (1..\a N)for each edge @param label: the set of values of the \a x variable for each edge @param to: the entering node for each edge, where 0 = T node The MDD must be deterministic, i.e., there cannot be two edges with the same label leaving the same node. */ predicate mdd(array[int] of var int: x, % variables constrained by MDD int: N, % number of nodes root is node 1 array[int] of int: level, % level of each node root is level 1, T is level length(x)+1 int: E, % number of edges array[int] of int: from, % edge leaving node 1..N array[int] of set of int: label, % possible values of variable array[int] of int: to % edge entering node 0..N where 0 = T node ) = let { set of int: NODE = 1..N; set of int: EDGE = 1..E; int: L = length(x); array[0..N] of int: levele = array1d(0..N,[L+1]++level); } in assert(index_set(level) = NODE, "mdd: third argument must be of length N = \(N)") /\ assert(index_set(from) = EDGE, "mdd: 5th argument must be of length E = \(E)") /\ assert(index_set(to) = EDGE, "mdd: 7th argument must be of length E = \(E)") /\ forall(e in EDGE)(assert(from[e] in NODE, "mdd: from[\(e)] must be in \(NODE)")) /\ forall(e in EDGE)(assert(to[e] in 0..N, "mdd: to[\(e)] must be in 0..\(N)")) /\ forall(e in EDGE)(assert(level[from[e]]+1 = levele[to[e]], "mdd level of from[\(e)] = \(level[from[e]])" ++ "must be 1 less than level of to[\(e)] = \(levele[to[e]])")) /\ forall(e1,e2 in EDGE where e1 < e2 /\ from[e1] = from[e2]) (assert(label[e1] intersect label[e2] = {}, "mdd: Two edges \(e1) and \(e2) leaving node \(from[e1]) with overlapping labels")) /\ fzn_mdd(x, N, level, E, from, label, to); % Example consider an MDD over 3 variables % 5 nodes and 12 edges % level 1 root = 1 % level 2 2 3 % level 3 4 5 % level 4 T % with edges (from,label,to) given by % (1,1,2), (1,2,3), (1,3,2) % (2,2,4), (2,3,5) % (3,3,4), (3,2,5) % (4,1,0), (4,5,0) % (5,2,0), (5,4,0), (5,6,0) % this is defined by the call % mdd([x1,x2,x3],5,[1,2,2,3,3],12,[1,1,1,2,2,3,3,4,4,5,5,5],[1,3,2,2,3,3,2,1,5,2,4,6],[2,2,3,4,5,4,5,0,0,0,0,0]) libminizinc-2.8.2/share/minizinc/std/link_set_to_booleans.mzn0000644000175000017500000000111314536677021023135 0ustar kaolkaolinclude "fzn_link_set_to_booleans.mzn"; include "fzn_link_set_to_booleans_reif.mzn"; /** @group globals.channeling Constrains the array of Booleans \a b to be a representation of the set \a s: \p i in \a s \( \leftrightarrow \) \a b[\p i]. The index set of \a b must be a superset of the possible values of \a s. */ predicate link_set_to_booleans(var set of $$E: s, array[$$E] of var bool: b) = assert(ub(s) subset index_set(b), "link_set_to_booleans: the index set of b must be a superset of the possible values of s", fzn_link_set_to_booleans(s,b) ); libminizinc-2.8.2/share/minizinc/std/weighted_spanning_tree.mzn0000644000175000017500000000440614536677021023465 0ustar kaolkaolinclude "fzn_wst.mzn"; include "fzn_wst_reif.mzn"; include "fzn_dwst.mzn"; include "fzn_dwst_reif.mzn"; /** @group globals.graph Constrains the set of edges \a es of a given directed graph to be a weighted spanning tree rooted at \a r of weight \a W. @param N: the number of nodes in the given graph @param E: the number of edges in the given graph @param from: the leaving node 1..\a N for each edge @param to: the entering node 1..\a N for each edge @param w: the weight of each edge @param r: the root node (which may be variable) @param es: a Boolean for each edge whether it is in the subgraph @param K: the weight of the tree */ predicate d_weighted_spanning_tree(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, var int: r, array[int] of var bool: es, var int: K) = assert(index_set(from) = 1..E,"dwst: index set of from must be 1..\(E)") /\ assert(index_set(to) = 1..E,"dwst: index set of to must be 1..\(E)") /\ assert(index_set(es) = 1..E,"dwst: index set of es must be 1..\(E)") /\ assert(index_set(w) = 1..E,"dwst: index set of w must be 1..\(E)") /\ fzn_dwst(N,E,from,to,w,r,es,K); /** @group globals.graph Constrains the set of edges \a es of a given undirected graph to be a weighted spanning tree of weight \a W. @param N: the number of nodes in the given graph @param E: the number of edges in the given graph @param from: the leaving node 1..\a N for each edge @param to: the entering node 1..\a N for each edge @param w: the weight of each edge @param es: a Boolean for each edge whether it is in the subgraph @param K: the weight of the tree */ predicate weighted_spanning_tree(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, array[int] of var bool: es, var int: K) = assert(index_set(from) = 1..E,"wst: index set of from must be 1..\(E)") /\ assert(index_set(to) = 1..E,"wst: index set of to must be 1..\(E)") /\ assert(index_set(es) = 1..E,"wst: index set of es must be 1..\(E)") /\ assert(index_set(w) = 1..E,"dwst: index set of w must be 1..\(E)") /\ fzn_wst(N,E,from,to,w,es,K); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_count_neq_par.mzn0000644000175000017500000000031714536677021022460 0ustar kaolkaolinclude "fzn_count_neq.mzn"; predicate fzn_count_neq_par(array[int] of var int: x, int: y, int: c) = fzn_count_neq(x,y,c); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/piecewise_linear.mzn0000644000175000017500000000162214536677021022255 0ustar kaolkaolinclude "fzn_piecewise_linear.mzn"; include "fzn_piecewise_linear_reif.mzn"; /** @group globals.math Return the piecewise-linear function of \a x on the given point-value sequence. The array \a xi defines the points, and \a vi the corresponding values. */ function var float: piecewise_linear(var float: x, array[int] of float: xi, array[int] of float: vi) ::promise_total = let { var float: res, constraint piecewise_linear(x,res,xi,vi), } in res; /** @group globals.math Constrains \a y(\a x) to be the piecewise-linear function on the provided point-value sequence. The array \a xi defines the points, and \a vi the corresponding values. */ predicate piecewise_linear(var float: x, var float: y, array[int] of float: xi, array[int] of float: vi) = fzn_piecewise_linear(x, y, xi, vi); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_bin_packing_reif.mzn0000644000175000017500000000067414536677021023102 0ustar kaolkaolpredicate fzn_bin_packing_reif(int: c, array[int] of var int: bin, array[int] of int: w, var bool: b) = b <-> forall( assigned_bin in lb_array(bin)..ub_array(bin) ) ( c >= sum ( i in index_set(bin) ) ( w[i] * ( bin[i] == assigned_bin ) ) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/exactly.mzn0000644000175000017500000000114314536677021020415 0ustar kaolkaolinclude "fzn_exactly_int.mzn"; include "fzn_exactly_int_reif.mzn"; include "fzn_exactly_set.mzn"; include "fzn_exactly_set_reif.mzn"; /** @group globals.deprecated Requires exactly \a n variables in \a x to take the value \a v. This constraint is deprecated. Use count(i in x)(i=v) = n instead. */ predicate exactly(int: n, array[$X] of var $$E: x, $$E: v) = fzn_exactly_int(n, array1d(x), v); /** @group globals.counting Requires exactly \a n variables in \a x to take the value \a v. */ predicate exactly(int: n, array[$X] of var set of $$E: x, set of $$E: v) = fzn_exactly_set(n, array1d(x), v); libminizinc-2.8.2/share/minizinc/std/fzn_sliding_sum_reif.mzn0000644000175000017500000000154714536677021023153 0ustar kaolkaolpredicate fzn_sliding_sum_reif(int: low, int: up, int: seq, array[int] of var int: vs, var bool: b) = /* CS decomposition: see S. Brand, N. Narodytska, C-G. Quimper, P.J. Stuckey, and T. Walsh. Encodings of the sequence constraint. In C. Bessiere, editor, Proceedings of the 13th International Conference on Principles and Practice of Constraint Programming, volume 4741 of LNCS, pages 210–224. Springer-Verlag, 2007. */ let { int: lx = min(index_set(vs)); int: ux = max(index_set(vs)); array[lx-1..ux] of var int: S; } in S[lx-1] = 0 /\ forall (i in lx .. ux) ( S[i] = vs[i] + S[i-1] ) /\ b <-> forall (i in lx-1 .. ux - seq) ( S[i] <= S[i+seq] - low /\ S[i+seq] <= S[i] + up ); libminizinc-2.8.2/share/minizinc/std/arg_max_int.mzn.deprecated.mzn0000644000175000017500000000023714536677021024141 0ustar kaolkaolpredicate maximum_arg_int(array[$$E] of var int: x, var $$E: i) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_disjunctive_opt.mzn0000644000175000017500000000053514536677021023036 0ustar kaolkaolpredicate fzn_disjunctive_opt(array[int] of var opt int: s, array[int] of var int: d) = forall (i,j in index_set(d) where i min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_regular_reif.mzn0000644000175000017500000000036414536677021022273 0ustar kaolkaolpredicate fzn_regular_reif(array[int] of var int: x, int: Q, int: S, array[int,int] of int: d, int: q0, set of int: F, var bool: b) = abort("Reified regular constraint is not supported"); libminizinc-2.8.2/share/minizinc/std/fzn_lex_chain_less_int_reif.mzn0000644000175000017500000000045014536677021024460 0ustar kaolkaolinclude "lex_less.mzn"; predicate fzn_lex_chain_less_int_reif( array[int, int] of var int: a, var bool: b) = let { set of int: is2 = index_set_2of2(a); } in b <-> ( forall(j in is2 where j+1 in is2) ( lex_less(col(a, j), col(a, j+1)) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_cumulative_reif.mzn0000644000175000017500000000366314536677021023015 0ustar kaolkaolpredicate fzn_cumulative_reif(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b, var bool: bb) = let { set of int: Tasks = {i | i in index_set(s) where ub(r[i]) > 0 /\ ub(d[i]) > 0 } } in if 0==card(Tasks) then bb <-> ( 0==card(index_set(s)) \/ b>=0 ) else let { int: early = min([ lb(s[i]) | i in Tasks ]), int: late = max([ ub(s[i]) + ub(d[i]) | i in Tasks ]) } in ( if late - early > 5000 then fzn_cumulative_task_reif(s, d, r, b, bb) else fzn_cumulative_time_reif(s, d, r, b, bb) endif ) endif ; predicate fzn_cumulative_time_reif(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b, var bool: bb) = let { set of int: Tasks = {i | i in index_set(s) where ub(r[i]) > 0 /\ ub(d[i]) > 0 }, int: early = min([ lb(s[i]) | i in Tasks ]), int: late = max([ ub(s[i]) + ub(d[i]) | i in Tasks ]) } in ( bb <-> forall( t in early..late ) ( b >= sum( i in Tasks ) ( (s[i] <= t /\ t < s[i] + d[i]) * r[i] ) ) ); predicate fzn_cumulative_task_reif(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b, var bool: bb) = let { set of int: Tasks = {i | i in index_set(s) where ub(r[i]) > 0 /\ ub(d[i]) > 0 } } in ( bb <-> forall( j in Tasks ) ( b >= r[j] + sum( i in Tasks where i != j ) ( (s[i] <= s[j] /\ s[j] < s[i] + d[i] ) * r[i] ) ) ); libminizinc-2.8.2/share/minizinc/std/sort_fn.mzn0000644000175000017500000000057314536677021020424 0ustar kaolkaolinclude "sort.mzn"; /** @group globals.sort Return a multiset of values that is the same as the multiset of values in \a x but in sorted order. */ function array[int] of var int: sort(array[int] of var int: x) ::promise_total = let { array[1..length(x)] of var lb_array(x)..ub_array(x): y ::is_defined_var; constraint sort(x,y) ::defines_var(y); } in y; libminizinc-2.8.2/share/minizinc/std/bin_packing.mzn0000644000175000017500000000154314536677021021214 0ustar kaolkaolinclude "fzn_bin_packing.mzn"; include "fzn_bin_packing_reif.mzn"; /** @group globals.packing Requires that each item \p i with weight \a w[\p i], be put into \a bin[\p i] such that the sum of the weights of the items in each bin does not exceed the capacity \a c. Assumptions: - forall \p i, \a w[\p i] >=0 - \a c >=0 */ predicate bin_packing(int: c, array[int] of var int: bin, array[int] of int: w) = assert(index_set(bin) == index_set(w), "bin_packing: the bin and weight arrays must have identical index sets", assert(lb_array(w) >= 0, "bin_packing: the weights must be non-negative", assert(c >= 0, "bin_packing: capacity must be non-negative", fzn_bin_packing(c, bin, w) ))); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_closed_set.mzn0000644000175000017500000000054314536677021025653 0ustar kaolkaolinclude "global_cardinality.mzn"; predicate fzn_global_cardinality_closed_set(array[int] of var set of int: x, array[int] of int: cover, array[int] of var int: counts) = global_cardinality(x, cover, counts) /\ forall (v in x) (v subset { d | d in cover }); libminizinc-2.8.2/share/minizinc/std/tree.mzn0000644000175000017500000001055414536677021017711 0ustar kaolkaolinclude "fzn_tree_int.mzn"; include "fzn_tree_int_reif.mzn"; include "fzn_tree_enum.mzn"; include "fzn_tree_enum_reif.mzn"; include "fzn_dtree_int.mzn"; include "fzn_dtree_int_reif.mzn"; include "fzn_dtree_enum.mzn"; include "fzn_dtree_enum_reif.mzn"; /** @group globals.graph Constrains the subgraph \a ns and \a es of a given directed graph to be a tree rooted at \a r. @param N: the number of nodes in the given graph @param E: the number of edges in the given graph @param from: the leaving node 1..\a N for each edge @param to: the entering node 1..\a N for each edge @param r: the root node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate dtree(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: r, array[int] of var bool: ns, array[int] of var bool: es) = assert(index_set(from) = 1..E,"dtree: index set of from must be 1..\(E)") /\ assert(index_set(to) = 1..E,"dtree: index set of to must be 1..\(E)") /\ assert(index_set(ns) = 1..N,"dtree: index set of ns must be 1..\(N)") /\ assert(index_set(es) = 1..E,"dtree: index set of es must be 1..\(E)") /\ fzn_dtree(N,E,from,to,r,ns,es); /** @group globals.graph Constrains the subgraph \a ns and \a es of a given directed graph to be at tree rooted at \a r. @param from: the leaving node for each edge @param to: the entering node for each edge @param r: the root node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate dtree(array[$$E] of $$N: from, array[$$E] of $$N: to, var $$N: r, array[$$N] of var bool: ns, array[$$E] of var bool: es) = assert(index_set(from) = index_set(to),"dreachable: index set of from and to must be identical") /\ assert(index_set(from) = index_set(es),"dreachable: index set of from and es must be identical") /\ assert(dom_array(from) subset index_set(ns),"dreachable: nodes in from must be in index set of ns") /\ assert(dom_array(to) subset index_set(ns),"dreachable: nodes in to must be in index set of ns") /\ fzn_dtree(from,to,r,ns,es); %-----------------------------------------------------------------------------% /** @group globals.graph Constrains the subgraph \a ns and \a es of a given undirected graph to be a tree rooted at \a r. @param N: the number of nodes in the given graph @param E: the number of edges in the given graph @param from: the leaving node 1..\a N for each edge @param to: the entering node 1..\a N for each edge @param r: the root node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate tree(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: r, array[int] of var bool: ns, array[int] of var bool: es) = assert(index_set(from) = 1..E,"tree: index set of from must be 1..\(E)") /\ assert(index_set(to) = 1..E,"tree: index set of to must be 1..\(E)") /\ assert(index_set(ns) = 1..N,"tree: index set of ns must be 1..\(N)") /\ assert(index_set(es) = 1..E,"tree: index set of es must be 1..\(E)") /\ fzn_tree(N,E,from,to,r,ns,es); /** @group globals.graph Constrains the subgraph \a ns and \a es of a given undirected graph to be at tree rooted at \a r. @param from: the leaving node for each edge @param to: the entering node for each edge @param r: the root node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate tree(array[$$E] of $$N: from, array[$$E] of $$N: to, var $$N: r, array[$$N] of var bool: ns, array[$$E] of var bool: es) = assert(index_set(from) = index_set(to),"dreachable: index set of from and to must be identical") /\ assert(index_set(from) = index_set(es),"dreachable: index set of from and es must be identical") /\ assert(dom_array(from) subset index_set(ns),"dreachable: nodes in from must be in index set of ns") /\ assert(dom_array(to) subset index_set(ns),"dreachable: nodes in to must be in index set of ns") /\ fzn_tree(from,to,r,ns,es); libminizinc-2.8.2/share/minizinc/std/neural_net.mzn0000644000175000017500000000674014536677021021110 0ustar kaolkaolinclude "fzn_neural_net.mzn"; include "fzn_neural_net_reif.mzn"; enum NEURON_TYPE = { NT_RELU, NT_STEP, NT_LINEAR, NT_SOFTPLUS }; /** @group globals.learning Constrain the output layer of a neural net to take the value defined by the input layer. @param inputs: an array of float variables @param input_ids: array[int] of node @param outputs: an array of float variables @param output_ids: array[int] of node @param bias: array[node] of float @param edge_weight: array[edge] of float @param edge_parent: array[edge] of neuron (start neuron for edge) @param first_edge: array[node] of 1..m+1 @param neuron_type: { NT_RELU, NT_STEP, NT_LINEAR, NT_SOFTPLUS } */ predicate neural_net(array[int] of var float: inputs, array[int] of int: input_ids, array[int] of var float: outputs, array[int] of int: output_ids, array[int] of float: bias, array[int] of float: edge_weight, array[int] of int: edge_parent, array[int] of int: first_edge, NEURON_TYPE: neuron_type) = assert(index_set(inputs) == index_set(input_ids), "neural_net: number of input vars not equal to number of input_ids") /\ assert(index_set(outputs) == index_set(output_ids), "neural_net: number of output vars not equal to number of output_ids") /\ let { set of int: node = index_set(bias) } in let { set of int: edge = index_set(edge_weight) } in assert(index_set(edge_parent) == edge, "neural_net: index sets of edge_weight and edge_parent do not agree") /\ assert(index_set(first_edge) == node, "neural_new: index sets of bias and first_edge do not agree") /\ forall(i in index_set(input_ids)) (assert(input_ids[i] in node, "neural_net: input_ids\(i) = \(input_ids[i]) not a correct node number")) /\ forall(i in index_set(output_ids)) (assert(output_ids[i] in node, "neural_net: output_ids\(i) = \(output_ids[i]) not a correct node number")) /\ forall(i in index_set(first_edge)) (assert(first_edge[i] in edge, "neural_net: first_edge\(i) = \(first_edge[i]) not a correct edge number")) /\ forall(i in index_set(edge_parent)) (assert(edge_parent[i] in edge, "neural_net: edge_parent\(i) = \(edge_parent[i]) not a correct node number")) /\ assert(mincreasing(first_edge), "neural_net: first_edge array is not in increasing order") /\ fzn_neural_net(inputs,input_ids,outputs,output_ids,bias, edge_weight,edge_parent,first_edge,neuron_type); test mincreasing(array[int] of int: x) = forall(i in index_set(x) diff { max(index_set(x)) }) (x[i] <= x[i+1]); predicate neural_net(array[int] of var float: inputs, array[int] of int: input_ids, array[int] of var float: outputs, array[int] of int: output_ids, array[int] of float: bias, array[int] of float: edge_weight, array[int] of int: edge_parent, array[int] of int: first_edge) = neural_net(inputs,input_ids,outputs,output_ids,bias, edge_weight,edge_parent,first_edge,NT_RELU); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_lex_lesseq_float_reif.mzn0000644000175000017500000000114714536677021024163 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_lesseq_float_reif(array[int] of var float: x, array[int] of var float: y, var bool: c) = c <-> lex_lesseq_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/bin_packing_capa.mzn0000644000175000017500000000172614536677021022203 0ustar kaolkaolinclude "fzn_bin_packing_capa.mzn"; include "fzn_bin_packing_capa_reif.mzn"; /** @group globals.packing Requires that each item \p i with weight \a w[\p i], be put into \a bin[\p i] such that the sum of the weights of the items in each bin \p b does not exceed the capacity \a c[\p b]. Assumptions: - forall \p i, \a w[\p i] >=0 - forall \p b, \a c[\p b] >=0 */ predicate bin_packing_capa(array[int] of int: c, array[int] of var int: bin, array[int] of int: w) = assert(index_set(bin) = index_set(w), "bin_packing_capa: the bin and weight arrays must have identical index sets", assert(lb_array(w) >= 0, "bin_packing_capa: the weights must be non-negative", assert(lb_array(c) >= 0, "bin_packing_capa: the capacities must be non-negative", fzn_bin_packing_capa(c, bin, w) ))); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_sort.mzn0000644000175000017500000000046114536677021020612 0ustar kaolkaolinclude "alldifferent.mzn"; include "increasing.mzn"; predicate fzn_sort(array[int] of var int: x, array[int] of var int: y) = let { array[index_set(x)] of var index_set(y): p } in forall(i in index_set(x)) ( y[p[i]] == x[i] ) /\ alldifferent(p) /\ increasing(y); libminizinc-2.8.2/share/minizinc/std/fzn_diffn_nonstrict.mzn0000644000175000017500000000066114536677021023016 0ustar kaolkaolpredicate fzn_diffn_nonstrict(array[int] of var int: x, array[int] of var int: y, array[int] of var int: dx, array[int] of var int: dy) = forall(i,j in index_set(x) where i < j)( dx[i] = 0 \/ dx[j] = 0 \/ dy[i]=0 \/ dy[j]=0 \/ x[i] + dx[i] <= x[j] \/ y[i] + dy[i] <= y[j] \/ x[j] + dx[j] <= x[i] \/ y[j] + dy[j] <= y[i] ); libminizinc-2.8.2/share/minizinc/std/fzn_bounded_dpath_int_reif.mzn0000644000175000017500000000054314536677021024303 0ustar kaolkaolinclude "path.mzn"; predicate fzn_bounded_dpath_reif(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, var int: s, var int: t, array[int] of var bool: ns, array[int] of var bool: es, var int: K, var bool: b) = b <-> ( dpath(N,E,from,to,s,t,ns,es) /\ K = sum(e in 1..E)(es[e]*w[e]) ); libminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_var_set.mzn0000644000175000017500000000060214536677021023767 0ustar kaolkaolpredicate fzn_if_then_else_var_set(array[int] of var bool: c, array[int] of var set of int: x, var set of int: y) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_write_reif.mzn0000644000175000017500000000046714536677021021770 0ustar kaolkaolpredicate fzn_write_reif(array[int] of var int: I, var int: i, var int: v, array[int] of var int: O, var bool: b) = b <-> forall(j in index_set(I)) (O[j] = if j = i then v else I[j] endif); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_lex_lesseq_set_reif.mzn0000644000175000017500000000115314536677021023646 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_lesseq_set_reif(array[int] of var set of int: x, array[int] of var set of int: y, var bool: c) = c <-> lex_lesseq_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/lex_less_float.mzn.deprecated.mzn0000644000175000017500000000075314536677021024657 0ustar kaolkaolpredicate lex_less_float(array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_monotone) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); predicate lex_lt_float(array[int] of var float: x ::promise_ctx_antitone, array[int] of var float: y ::promise_ctx_monotone) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_set.mzn0000644000175000017500000000043414536677021024321 0ustar kaolkaolpredicate fzn_global_cardinality_set(array[int] of var set of int: x, array[int] of int: cover, array[int] of var int: counts) = forall (i in index_set(cover)) (counts[i] = count (v in x) (cover[i] in v)); libminizinc-2.8.2/share/minizinc/std/fzn_value_precede_int.mzn0000644000175000017500000000107014536677021023275 0ustar kaolkaolpredicate fzn_value_precede_int(int: s, int: t, array[int] of var int: x) = if length(x) = 0 then true else let { int: imin = min(index_set(x)), int: imax = max(index_set(x)), array[imin..imax+1] of var bool: b } in ( forall (i in imin..imax) ( let { var bool: xis = (x[i] == s) } in (xis -> (b[i+1] == true)) /\ ((not xis) -> (b[i] == b[i+1])) /\ ((not b[i]) -> (x[i] != t)) ) /\ b[imin] == false ) endif; libminizinc-2.8.2/share/minizinc/std/count_gt.mzn0000644000175000017500000000176014536677021020573 0ustar kaolkaolinclude "fzn_count_gt_par.mzn"; include "fzn_count_gt.mzn"; include "fzn_count_gt_par_reif.mzn"; include "fzn_count_gt_reif.mzn"; /** @group globals.counting Constrains \a c to be strictly greater than the number of occurrences of \a y in \a x. */ predicate count_gt(array[$X] of var $$E: x, var $$E: y, var int: c) = fzn_count_gt(array1d(x), y, c); /** @group globals.counting Constrains \a c to be strictly greater than the number of occurrences of \a y in \a x. */ predicate count_gt(array[$X] of var opt $$E: x, var $$E: y, var int: c) =let { % Set <> to something not y int: def = if 0 in dom(y) then lb(y)-1 else 0 endif; } in count_gt([i default def | i in x], y, c); /** @group globals.counting Constrains \a c to be strictly greater than the number of occurrences of \a y in \a x. */ predicate count_gt(array[$X] of var $$E: x, $$E: y, int: c) = fzn_count_gt_par(array1d(x), y, c); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_dsteiner.mzn0000644000175000017500000000060614536677021021441 0ustar kaolkaolinclude "tree.mzn"; predicate fzn_dsteiner(int: N, int: E, array[int] of int: from, array[int] of int: to, array[int] of int: w, var int: r, array[int] of var bool: ns, array[int] of var bool: es, var int: K) = dtree(N,E,from,to,r,ns,es) /\ K = sum(e in 1..E)(es[e]*w[e]); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_geost_nonoverlap_k.mzn0000644000175000017500000000044614536677021023524 0ustar kaolkaolpredicate fzn_geost_nonoverlap_k( array[int] of var int : x1, array[int] of int : w1, array[int] of var int : x2, array[int] of int : w2 ) = % Non-overlap constraint exists(j in index_set(x1))( x1[j] + w1[j] <= x2[j] \/ x2[j] + w2[j] <= x1[j] ); libminizinc-2.8.2/share/minizinc/std/cost_mdd.mzn0000644000175000017500000000731014536677021020542 0ustar kaolkaolinclude "fzn_cost_mdd.mzn"; include "fzn_cost_mdd_reif.mzn"; /** @group globals.extensional Requires that \a x defines a path in the cost MDD with total edge weight \a totalcost. @param N: the number of nodes, the root node is node 1 @param level: the level of each node, the root is level 1, T is level \a length(x)+1 @param E: the number of edges @param from: the leaving node (1..\a N)for each edge @param label: the set of value of the x variable for each edge @param cost: the cost for each edge @param to: the entering node for each edge, where 0 = T node @param totalcost: the total cost of the path defined by \a x */ predicate cost_mdd(array[int] of var int: x, % variables constrained by MDD int: N, % number of nodes root is node 1 array[int] of int: level, % level of each node root is level 1, T is level length(x)+1 int: E, % number of edges array[int] of int: from, % edge leaving node 1..N array[int] of set of int: label, % values of variable on edge array[int] of int: cost, % cost of using edge array[int] of int: to, % edge entering node 0..N where 0 = T node var int: totalcost % total cost of path ) = let { set of int: NODE = 1..N; set of int: EDGE = 1..E; int: L = length(x); array[0..N] of int: levele = array1d(0..N,[L+1]++level); } in assert(index_set(level) = NODE, "cost_mdd: level argument must be of length N = \(N)") /\ assert(level[1] = 1, "cost_mdd: level of root (1) must be 1") /\ forall(n in 2..N)(assert(level[n] != 1, "cost_mdd: level of non root node (\(n)) must not be 1")) /\ assert(index_set(from) = EDGE, "cost_mdd: from argument must be of length E = \(E)") /\ assert(index_set(to) = EDGE, "cost_mdd: to argument must be of length E = \(E)") /\ assert(index_set(label) = EDGE, "cost_mdd: label argument must be of length E = \(E)") /\ assert(index_set(cost) = EDGE, "cost_mdd: cost argument must be of length E = \(E)") /\ forall(e in EDGE)(assert(from[e] in NODE, "cost_mdd: from[\(e)] must be in \(NODE)")) /\ forall(e in EDGE)(assert(to[e] in 0..N, "cost_mdd: to[\(e)] must be in 0..\(N)")) /\ forall(e in EDGE)(assert(level[from[e]]+1 = levele[to[e]], "cost_mdd: mdd level of from[\(e)] = \(level[from[e]])" ++ "must be 1 less than level of to[\(e)] = \(levele[to[e]])")) /\ forall(e1,e2 in EDGE where e1 < e2 /\ from[e1] = from[e2]) (assert(label[e1] intersect label[e2] = {}, "cost_mdd: Two edges \(e1) and \(e2) leaving node \(from[e1]) with overlapping labels")) /\ fzn_cost_mdd(x,N,level,E,from,label,cost,to,totalcost); % Example consider an MDD over 3 variables % 5 nodes and 8 edges % level 1 root = 1 % level 2 2 3 % level 3 4 5 % level 4 T % with edges (from,label,cost,to) given by % (1,{1,3},3,2), (1,{2},1,3), % (2,{2},4,4), (2,{3},2,5), % (3,{3},3,4), (3,{2},5,5), % (4,{1,5},2,0), % (5,{2,4,6},4,0) % this is defined by the call % cost_mdd([x1,x2,x3],5,[1,2,2,3,3],8,[1,1,2,2,3,3,4,5], % [{1,3},{2},{2},{3},{3},{2},{1,5},{2,4,6}],[3,1,4,2,3,5,2,4],[2,3,4,5,4,5,0,0],tc) libminizinc-2.8.2/share/minizinc/std/fzn_seq_precede_chain_int_reif.mzn0000644000175000017500000000022414536677021025120 0ustar kaolkaolpredicate fzn_seq_precede_chain_int_reif(array[int] of var int: X, var bool: b) = abort("Reified seq_precede_chain constraint is not supported"); libminizinc-2.8.2/share/minizinc/std/fzn_at_most1_reif.mzn0000644000175000017500000000025714536677021022362 0ustar kaolkaolpredicate fzn_at_most1_reif(array[int] of var set of int: s, var bool: b) = b <-> forall(i,j in index_set(s) where i < j) ( card(s[i] intersect s[j]) <= 1 ); libminizinc-2.8.2/share/minizinc/std/fzn_tree_enum_reif.mzn0000644000175000017500000000052414536677021022613 0ustar kaolkaolpredicate fzn_tree_reif(array[int] of $$N: from, array[int] of $$N: to, var $$N: r, array[$$N] of var bool: ns, array[int] of var bool: es, var bool: b) = abort("Reified tree constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_all_equal_int_reif.mzn0000644000175000017500000000054314536677021023442 0ustar kaolkaol%-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all equal. %-----------------------------------------------------------------------------% predicate fzn_all_equal_int_reif(array[int] of var int: x, var bool: b) = b <-> forall(i, j in index_set(x) where i < j) ( x[i] = x[j] ); libminizinc-2.8.2/share/minizinc/std/cumulative.mzn0000644000175000017500000000254714536677021021133 0ustar kaolkaolinclude "all_different.mzn"; include "disjunctive.mzn"; include "fzn_cumulative.mzn"; include "fzn_cumulative_reif.mzn"; /** @group globals.scheduling Requires that a set of tasks given by start times \a s, durations \a d, and resource requirements \a r, never require more than a global resource bound \a b at any one time. Assumptions: - forall \p i, \a d[\p i] >= 0 and \a r[\p i] >= 0 */ predicate cumulative( array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b ) = assert( index_set(s) == index_set(d) /\ index_set(s) == index_set(r), "cumulative: the 3 array arguments must have identical index sets" ) /\ if length(s) >= 1 then assert( lb_array(d) >= 0 /\ lb_array(r) >= 0, "cumulative: durations and resource usages must be non-negative" ) /\ if let { int: mr = lb_array(r); int: mri = arg_min([ lb(r[i]) | i in index_set(r) ]) } in forall(i in index_set(r)) ( is_fixed(r[i]) /\ (fix(r[i]) + mr > ub(b) \/ i = mri) ) then forall(i in index_set(r))(d[i] = 0 \/ fix(r[i]) <= b) /\ if length(s) = 1 then true elseif forall(i in index_set(d))(is_fixed(d[i]) /\ fix(d[i]) == 1) then all_different(s) else disjunctive(s, d) endif else fzn_cumulative(s, d, r, b) endif endif; libminizinc-2.8.2/share/minizinc/std/fzn_subgraph_enum_reif.mzn0000644000175000017500000000060314536677021023465 0ustar kaolkaolpredicate fzn_subgraph_reif(array[int] of $$N: from, array[int] of $$N: to, array[$$N] of var bool: ns, array[int] of var bool: es, var bool: b) = b <-> forall(e in index_set(from)) ( (es[e] -> ns[from[e]]) /\ (es[e] -> ns[to[e]]) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/redefinitions-2.3.3.mzn0000644000175000017500000000063714536677021022256 0ustar kaolkaol% This file contains redefinitions of standard builtins for version 2.3.3 % that can be overridden by solvers. predicate float_set_in(var float: x, set of float: S) = let { array[int] of float: r1d = set_to_ranges(S); array[int,1..2] of float: r = array2d(1..length(r1d) div 2,1..2,r1d) } in exists (i in index_set_1of2(r)) ( if r[i,1]=r[i,2] then x=r[i,1] else (x>=r[i,1] /\ x<=r[i,2]) endif ); libminizinc-2.8.2/share/minizinc/std/fzn_bin_packing_capa_reif.mzn0000644000175000017500000000113114536677021024053 0ustar kaolkaolpredicate fzn_bin_packing_capa_reif(array[int] of int: c, array[int] of var int: bin, array[int] of int: w, var bool: b) = b <-> ( forall( i in index_set(bin) ) ( min(index_set(c)) <= bin[i] /\ bin[i] <= max(index_set(c)) ) /\ forall( assigned_bin in index_set(c) ) ( c[assigned_bin] >= sum ( i in index_set(bin) ) ( w[i] * ( bin[i] = assigned_bin ) ) )); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_increasing_float_opt.mzn0000644000175000017500000000124114536677021024011 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order %-----------------------------------------------------------------------------% predicate fzn_increasing_float_opt(array[int] of var opt float: x) = let { array[int] of var opt float: xx = array1d(x); array[1..length(xx)] of var float: y; constraint forall(i in 1..length(xx)) ( y[i] = if occurs(xx[i]) then deopt(xx[i]) elseif i = 1 then lb_array(xx) else y[i-1] endif ); } in forall (i in 2..length(y) where occurs(xx[i])) ( deopt(xx[i]) >= y[i-1] ); libminizinc-2.8.2/share/minizinc/std/member.mzn0000644000175000017500000000214514536677021020216 0ustar kaolkaolinclude "fzn_member_bool.mzn"; include "fzn_member_bool_reif.mzn"; include "fzn_member_float.mzn"; include "fzn_member_float_reif.mzn"; include "fzn_member_int.mzn"; include "fzn_member_int_reif.mzn"; include "fzn_member_set.mzn"; include "fzn_member_set_reif.mzn"; include "fzn_set_member.mzn"; include "fzn_set_member_reif.mzn"; /** @group globals.array Requires that \a y occurs in the array \a x. */ predicate member(array[int] of var bool: x, var bool: y) = fzn_member_bool(x, y); /** @group globals.array Requires that \a y occurs in the array \a x. */ predicate member(array[int] of var float: x, var float: y) = fzn_member_float(x, y); /** @group globals.array Requires that \a y occurs in the array \a x. */ predicate member(array[int] of var $$E: x, var $$E: y) = fzn_member_int(x, y); /** @group globals.array Requires that \a y occurs in the array \a x. */ predicate member(array[int] of var set of $$E: x, var set of $$E: y) = fzn_member_set(x, y); /** @group globals.array Requires that \a y occurs in the set \a x. */ predicate member(var set of $$E: x, var $$E: y) = fzn_set_member(x, y); libminizinc-2.8.2/share/minizinc/std/fzn_symmetric_all_different.mzn0000644000175000017500000000023414536677021024513 0ustar kaolkaolinclude "all_different.mzn"; include "inverse.mzn"; predicate fzn_symmetric_all_different(array[int] of var int:x) = all_different(x) /\ inverse(x,x); libminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_var_float.mzn0000644000175000017500000000057214536677021024307 0ustar kaolkaolpredicate fzn_if_then_else_var_float(array[int] of var bool: c, array[int] of var float: x, var float: y) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_exactly_int_reif.mzn0000644000175000017500000000055514536677021023157 0ustar kaolkaolinclude "count_fn.mzn"; %-----------------------------------------------------------------------------% % Requires exactly 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate fzn_exactly_int_reif(int: n, array[int] of var int: x, int: v, var bool: b) = b <-> n == count(x, v); libminizinc-2.8.2/share/minizinc/std/all_equal.mzn0000644000175000017500000000110514536677021020701 0ustar kaolkaolinclude "fzn_all_equal_int.mzn"; include "fzn_all_equal_int_reif.mzn"; include "fzn_all_equal_set.mzn"; include "fzn_all_equal_set_reif.mzn"; /** @group globals.alldifferent Constrain the elements of the array \a x to be all equal. */ predicate all_equal(array[$X] of var int: x) = if length(x) <= 1 then true else fzn_all_equal_int(array1d(x)) endif; /** @group globals.alldifferent Constrain the elements of the array \a x to be all equal. */ predicate all_equal(array[$X] of var set of int: x) = if length(x) <= 1 then true else fzn_all_equal_set(array1d(x)) endif; libminizinc-2.8.2/share/minizinc/std/partition_set.mzn0000644000175000017500000000046114536677021021632 0ustar kaolkaolinclude "fzn_partition_set.mzn"; include "fzn_partition_set_reif.mzn"; /** @group globals.set Constrains the sets in array \a S to partition the \a universe. */ predicate partition_set(array[int] of var set of $$E: S, set of $$E: universe) = fzn_partition_set(S, universe); libminizinc-2.8.2/share/minizinc/std/all_equal_int.mzn.deprecated.mzn0000644000175000017500000000022014536677021024452 0ustar kaolkaolpredicate all_equal_int(array[$X] of var int: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_dreachable_int.mzn0000644000175000017500000000263314536677021022552 0ustar kaolkaolinclude "subgraph.mzn"; predicate fzn_dreachable(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: r, array[int] of var bool: ns, array[int] of var bool: es) = let { set of int: NODE = 1..N; array[NODE] of var 0..N-1: dist; /* distance from root */ array[NODE] of var 0..N: parent; /* parent */ } in ns[r] /\ % the root must be chosen dist[r] = 0 /\ % root is at distance 0 forall(n in NODE) % nonselected nodes have parent 0 (not ns[n] -> parent[n] = 0) /\ forall(n in NODE) % nonselected nodes have distance 0 (not ns[n] -> dist[n] = 0) /\ forall(n in NODE) % each in node except root must have a parent (ns[n] -> (n = r \/ parent[n] > 0)) /\ forall(n in NODE) % each in node with a parent must be in and also its parent (parent[n] > 0 -> (ns[n] /\ ns[parent[n]])) /\ forall(n in NODE) % each except with a parent is one more than its parent (parent[n] > 0 -> dist[n] = dist[parent[n]] + 1) /\ forall(n in NODE) % each node with a parent must have that edge in (parent[n] > 0 -> exists(e in 1..E)(es[e] /\ from[e] = parent[n] /\ to[e] = n)) /\ subgraph(N,E,from,to,ns,es); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_table_bool.mzn0000644000175000017500000000211414536677021021722 0ustar kaolkaol%-----------------------------------------------------------------------------% % A table constraint: table(x, t) represents the constraint x in t where we % consider each row in t to be a tuple and t as a set of tuples. %-----------------------------------------------------------------------------% predicate fzn_table_bool(array[int] of var bool: x, array[int, int] of bool: t) = let { int: l = min(index_set(x)), int: u = max(index_set(x)), int: lt = min(index_set_1of2(t)), int: ut = max(index_set_1of2(t)), var lt..ut: i, array[l..u, lt..ut] of bool: t_transposed = array2d(l..u, lt..ut, [ t[k,j] | j in l..u, k in lt..ut ]) } in forall(j in l..u) ( % Having the variable index component at the left position % means that the nD-to-1D array translation during Mzn-to-Fzn % will generate at most an offset constraint, instead of a % scaling + offset constraint. % t_transposed[j,i] = x[j] % % t[i,j] = x[j] ); libminizinc-2.8.2/share/minizinc/std/fzn_increasing_bool_reif.mzn0000644000175000017500000000061614536677021023767 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate fzn_increasing_bool_reif(array[int] of var bool: x, var bool: b) = b <-> forall(i in index_set(x) diff { min(index_set(x)) }) (x[i-1] <= x[i]); libminizinc-2.8.2/share/minizinc/std/lex_less_int.mzn0000644000175000017500000000147214536677021021441 0ustar kaolkaolinclude "lex_less.mzn"; include "fzn_lex_less_int.mzn"; include "fzn_lex_less_int_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is strictly lexicographically less than array 'y'. % Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate lex_less_int(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) = fzn_lex_less_int(x, y); predicate lex_lt_int(array[int] of var int: x ::promise_ctx_antitone, array[int] of var int: y ::promise_ctx_monotone) = lex_less(x, y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/lex_greatereq.mzn0000644000175000017500000000264714536677021021605 0ustar kaolkaolinclude "lex_lesseq.mzn"; /** @group globals.lexicographic Requires that the array \a x is lexicographically greater than or equal to array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_greatereq(array[int] of var bool: x ::promise_ctx_monotone, array[int] of var bool: y ::promise_ctx_antitone) = lex_lesseq(y, x); /** @group globals.lexicographic Requires that the array \a x is lexicographically greater than or equal to array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_greatereq(array[int] of var int: x ::promise_ctx_monotone, array[int] of var int: y ::promise_ctx_antitone) = lex_lesseq(y, x); /** @group globals.lexicographic Requires that the array \a x is lexicographically greater than or equal to array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_greatereq(array[int] of var float: x ::promise_ctx_monotone, array[int] of var float: y ::promise_ctx_antitone) = lex_lesseq(y, x); /** @group globals.lexicographic Requires that the array \a x is lexicographically greater than or equal to array \a y. Compares them from first to last element, regardless of indices. */ predicate lex_greatereq(array[int] of var set of int: x, array[int] of var set of int: y) = lex_lesseq(y, x); libminizinc-2.8.2/share/minizinc/std/fzn_count_geq_par.mzn0000644000175000017500000000032114536677021022444 0ustar kaolkaolinclude "fzn_count_geq.mzn"; predicate fzn_count_geq_par(array[int] of var int: x, int: y, int: c) = fzn_count_geq(x,y,c); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/lex_chain_less_int.mzn.deprecated.mzn0000644000175000017500000000023314536677021025477 0ustar kaolkaolpredicate lex_chain_less_int(array[int, int] of var int: a) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/analyse_all_different.mzn0000644000175000017500000000010614536677021023254 0ustar kaolkaolpredicate analyse_all_different(array[int] of var opt int: x) = true; libminizinc-2.8.2/share/minizinc/std/fzn_nvalue.mzn0000644000175000017500000000034614536677021021117 0ustar kaolkaolpredicate fzn_nvalue(var int: n, array[int] of var int: x) = let { int: lx = lb_array(x), int: ux = ub_array(x), } in n == sum(j in lx..ux) ( exists(i in index_set(x)) ( x[i] = j ) ); libminizinc-2.8.2/share/minizinc/std/fzn_count_neq_reif.mzn0000644000175000017500000000060114536677021022617 0ustar kaolkaolinclude "count_fn.mzn"; predicate fzn_count_neq_reif(array[int] of var int: x, var int: y, var int: c, var bool: b) = let { var int: z = count(x,y) } in b <-> z != c; % This needs to be written with a let rather than count(x,y) != c % so that the automatic rewriting of the latter doesn't kick in %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_diffn_k_reif.mzn0000644000175000017500000000156114536677021022232 0ustar kaolkaolpredicate fzn_diffn_k_reif(array[int,int] of var int: box_posn, array[int,int] of var int: box_size, var bool: b) = let { set of int: DIMS= index_set_2of2(box_posn) } in b <-> forall(b1, b2 in index_set_1of2(box_posn) where b1 < b2) (fzn_diffn_nonoverlap_k_for_reif([ box_posn[b1,j] | j in DIMS ], [ box_size[b1,j] | j in DIMS ], [ box_posn[b2,j] | j in DIMS ], [ box_size[b2,j] | j in DIMS ] ) ); predicate fzn_diffn_nonoverlap_k_for_reif(array[int] of var int: x1, array[int] of var int: w1, array[int] of var int: x2, array[int] of var int: w2) = exists(j in index_set(x1)) (x1[j] + w1[j] <= x2[j] \/ x2[j] + w2[j] <= x1[j]); libminizinc-2.8.2/share/minizinc/std/decreasing_int.mzn0000644000175000017500000000062114536677021021722 0ustar kaolkaolinclude "fzn_decreasing_int.mzn"; include "fzn_decreasing_int_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is in decreasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate decreasing_int(array[$X] of var int: x) = fzn_decreasing_int(array1d(x)); libminizinc-2.8.2/share/minizinc/std/fzn_arg_min_int.mzn0000644000175000017500000000073014536677021022110 0ustar kaolkaolpredicate fzn_minimum_arg_int(array[int] of var int: x, var int: z) = % general case: min could be 0 or 1 let { int: l = min(index_set(x)) ; int: u = max(index_set(x)) ; int: n = u-l+1; array[int] of var int: xs = array1d(l..u,[ n*x[j]+j | j in l..u ]); var int: Mx = min(xs) ; } in forall (j in l..u) ( (z != j) = (Mx < xs[j]) ); %%% only the new decomposition from argmax paper CP2020 submission libminizinc-2.8.2/share/minizinc/std/redefinitions-2.5.2.mzn0000644000175000017500000000266614536677021022263 0ustar kaolkaol% This file contains redefinitions of standard builtins for version 2.5.2 % that can be overridden by solvers. predicate array_var_int_element2d_nonshifted(var int: idx1, var int: idx2, array[int,int] of var int: x, var int: c) = let { int: dim = card(index_set_2of2(x)); int: min_flat = min(index_set_1of2(x))*dim+min(index_set_2of2(x))-1; } in array_var_int_element_nonshifted((idx1*dim+idx2-min_flat)::domain, array1d(x), c); predicate array_var_bool_element2d_nonshifted(var int: idx1, var int: idx2, array[int,int] of var bool: x, var bool: c) = let { int: dim = card(index_set_2of2(x)); int: min_flat = min(index_set_1of2(x))*dim+min(index_set_2of2(x))-1; } in array_var_bool_element_nonshifted((idx1*dim+idx2-min_flat)::domain, array1d(x), c); predicate array_var_float_element2d_nonshifted(var int: idx1, var int: idx2, array[int,int] of var float: x, var float: c) = let { int: dim = card(index_set_2of2(x)); int: min_flat = min(index_set_1of2(x))*dim+min(index_set_2of2(x))-1; } in array_var_float_element_nonshifted((idx1*dim+idx2-min_flat)::domain, array1d(x), c); predicate array_var_set_element2d_nonshifted(var int: idx1, var int: idx2, array[int,int] of var set of int: x, var set of int: c) = let { int: dim = card(index_set_2of2(x)); int: min_flat = min(index_set_1of2(x))*dim+min(index_set_2of2(x))-1; } in array_var_set_element_nonshifted((idx1*dim+idx2-min_flat)::domain, array1d(x), c); libminizinc-2.8.2/share/minizinc/std/lex_chain_lesseq.mzn0000644000175000017500000000213714536677021022256 0ustar kaolkaolinclude "fzn_lex_chain_lesseq_bool.mzn"; include "fzn_lex_chain_lesseq_bool_reif.mzn"; include "fzn_lex_chain_lesseq_int.mzn"; include "fzn_lex_chain_lesseq_int_reif.mzn"; /** @group globals.lexicographic Requires that the columns of matrix \a a are lexicographically sorted, non-decreasing. */ predicate lex_chain_lesseq(array[int, int] of var bool: a) = if card(index_set_2of2(a)) > 1 then fzn_lex_chain_lesseq_bool(a) endif; /** @group globals.lexicographic Requires that the columns of matrix \a a are lexicographically sorted, non-decreasing. */ predicate lex_chain_lesseq(array[int, int] of var int: a) = if card(index_set_2of2(a)) > 1 then fzn_lex_chain_lesseq_int(a) endif; /** @group globals.lexicographic Requires that the columns of matrix \a a are lexicographically sorted, non-decreasing. */ predicate lex_chain(array[int, int] of var bool: a) = lex_chain_lesseq(a); /** @group globals.lexicographic Requires that the columns of matrix \a a are lexicographically sorted, non-decreasing. */ predicate lex_chain(array[int, int] of var int: a) = lex_chain_lesseq(a); libminizinc-2.8.2/share/minizinc/std/fzn_sum_pred_reif.mzn0000644000175000017500000000044114536677021022444 0ustar kaolkaolpredicate fzn_sum_pred_reif(var int: i, array[int] of set of int: sets, array[int] of int: cs, var int: s, var bool: b) = let { array[index_set(sets)] of int: sums = [ sum(k in sets[j])(cs[k]) | j in index_set(sets) ]; } in b <-> sums[i] = s; libminizinc-2.8.2/share/minizinc/std/path.mzn0000644000175000017500000001107014536677021017700 0ustar kaolkaolinclude "fzn_path_int.mzn"; include "fzn_path_int_reif.mzn"; include "fzn_path_enum.mzn"; include "fzn_path_enum_reif.mzn"; include "fzn_dpath_int.mzn"; include "fzn_dpath_int_reif.mzn"; include "fzn_dpath_enum.mzn"; include "fzn_dpath_enum_reif.mzn"; /** @group globals.graph Constrains the subgraph \a ns and \a es of a given directed graph to be a path from \a s to \a t. @param N: the number of nodes in the given graph @param E: the number of edges in the given graph @param from: the leaving node 1..\a N for each edge @param to: the entering node 1..\a N for each edge @param s: the source node (which may be variable) @param t: the dest node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate dpath(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: s, var int: t, array[int] of var bool: ns, array[int] of var bool: es) = assert(index_set(from) = 1..E,"dpath: index set of from must be 1..\(E)") /\ assert(index_set(to) = 1..E,"dpath: index set of to must be 1..\(E)") /\ assert(index_set(ns) = 1..N,"dpath: index set of ns must be 1..\(N)") /\ assert(index_set(es) = 1..E,"dpath: index set of es must be 1..\(E)") /\ fzn_dpath(N,E,from,to,s,t,ns,es); /** @group globals.graph Constrains the subgraph \a ns and \a es of a given directed graph to be a path from \a s to \a t. @param from: the leaving node for each edge @param to: the entering node for each edge @param s: the source node (which may be variable) @param t: the dest node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate dpath(array[int] of $$N: from, array[int] of $$N: to, var $$N: s, var $$N: t, array[$$N] of var bool: ns, array[int] of var bool: es) = assert(index_set(from) = index_set(to),"dpath: index set of from and to must be identical") /\ assert(index_set(from) = index_set(es),"dpath: index set of from and es must be identical") /\ assert(dom_array(from) subset index_set(ns),"dpath: nodes in from must be in index set of ns") /\ assert(dom_array(to) subset index_set(ns),"dpath: nodes in to must be in index set of ns") /\ fzn_dpath(from,to,s,t,ns,es); %-----------------------------------------------------------------------------% /** @group globals.graph Constrains the subgraph \a ns and \a es of a given undirected graph to be a path from \a s to \a t. @param N: the number of nodes in the given graph @param E: the number of edges in the given graph @param from: the leaving node 1..\a N for each edge @param to: the entering node 1..\a N for each edge @param s: the source node (which may be variable) @param t: the dest node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate path(int: N, int: E, array[int] of int: from, array[int] of int: to, var int: s, var int: t, array[int] of var bool: ns, array[int] of var bool: es) = assert(index_set(from) = 1..E,"path: index set of from must be 1..\(E)") /\ assert(index_set(to) = 1..E,"path: index set of to must be 1..\(E)") /\ assert(index_set(ns) = 1..N,"path: index set of ns must be 1..\(N)") /\ assert(index_set(es) = 1..E,"path: index set of es must be 1..\(E)") /\ fzn_path(N,E,from,to,s,t,ns,es); /** @group globals.graph Constrains the subgraph \a ns and \a es of a given undirected graph to be a path from \a s to \a t. @param from: the leaving node for each edge @param to: the entering node for each edge @param s: the source node (which may be variable) @param t: the dest node (which may be variable) @param ns: a Boolean for each node whether it is in the subgraph @param es: a Boolean for each edge whether it is in the subgraph */ predicate path(array[int] of $$N: from, array[int] of $$N: to, var $$N: s, var $$N: t, array[$$N] of var bool: ns, array[int] of var bool: es) = assert(index_set(from) = index_set(to),"path: index set of from and to must be identical") /\ assert(index_set(from) = index_set(es),"path: index set of from and es must be identical") /\ assert(dom_array(from) subset index_set(ns),"path: nodes in from must be in index set of ns") /\ assert(dom_array(to) subset index_set(ns),"path: nodes in to must be in index set of ns") /\ fzn_path(from,to,s,t,ns,es); libminizinc-2.8.2/share/minizinc/std/table_bool.mzn0000644000175000017500000000105114536677021021044 0ustar kaolkaolinclude "fzn_table_bool.mzn"; include "fzn_table_bool_reif.mzn"; %-----------------------------------------------------------------------------% % A table constraint: table(x, t) represents the constraint x in t where we % consider each row in t to be a tuple and t as a set of tuples. %-----------------------------------------------------------------------------% predicate table_bool( array[$$E] of var bool: x, array[int, $$E] of bool: t ) = fzn_table_bool(x, t); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/value_precede_int.mzn0000644000175000017500000000027414536677021022425 0ustar kaolkaolinclude "fzn_value_precede_int.mzn"; include "fzn_value_precede_int_reif.mzn"; predicate value_precede_int($$E: s, $$E: t, array[int] of var $$E: x) = fzn_value_precede_int(s, t, x); libminizinc-2.8.2/share/minizinc/std/lex_chain_lesseq_bool.mzn.deprecated.mzn0000644000175000017500000000023714536677021026172 0ustar kaolkaolpredicate lex_chain_lesseq_bool(array[int, int] of var bool: a) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_cumulative_opt_reif.mzn0000644000175000017500000000416414536677021023674 0ustar kaolkaolpredicate fzn_cumulative_opt_reif(array[int] of var opt int: s, array[int] of var int: d, array[int] of var int: r, var int: b, var bool: bb) = let { set of int: Tasks = {i | i in index_set(s) where ub(occurs(s[i])) > 0 /\ ub(r[i]) > 0 /\ ub(d[i]) > 0 } } in if 0==card(Tasks) then bb <-> ( 0==card(index_set(s)) \/ b>=0 ) else let { int: early = min([ lb(s[i]) | i in Tasks ]), int: late = max([ ub(s[i]) + ub(d[i]) | i in Tasks ]) } in ( if late - early > 5000 then fzn_cumulative_opt_task_reif(s, d, r, b, bb) else fzn_cumulative_opt_time_reif(s, d, r, b, bb) endif ) endif ; predicate fzn_cumulative_opt_time_reif(array[int] of var opt int: s, array[int] of var int: d, array[int] of var int: r, var int: b, var bool: bb) = let { set of int: Tasks = {i | i in index_set(s) where ub(occurs(s[i])) > 0 /\ ub(r[i]) > 0 /\ ub(d[i]) > 0 }, int: early = min([ lb(s[i]) | i in Tasks ]), int: late = max([ ub(s[i]) + ub(d[i]) | i in Tasks ]) } in ( bb <-> forall( t in early..late ) ( b >= sum( i in Tasks ) ( (occurs(s[i]) /\ deopt(s[i]) <= t /\ t < deopt(s[i]) + d[i]) * r[i] ) ) ); predicate fzn_cumulative_opt_task_reif(array[int] of var opt int: s, array[int] of var int: d, array[int] of var int: r, var int: b, var bool: bb) = let { set of int: Tasks = {i | i in index_set(s) where ub(occurs(s[i])) > 0 /\ ub(r[i]) > 0 /\ ub(d[i]) > 0 } } in ( bb <-> forall( j in Tasks ) ( occurs(s[j]) -> b >= r[j] + sum( i in Tasks where i != j ) ( (occurs(s[i]) /\ deopt(s[i]) <= deopt(s[j]) /\ deopt(s[j]) < deopt(s[i]) + d[i] ) * r[i] ) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_connected_reif.mzn0000644000175000017500000000046214536677021022573 0ustar kaolkaolpredicate fzn_connected_reif(array[int] of $$N: from, array[int] of $$N: to, array[$$N] of var bool: ns, array[int] of var bool: es, var bool: b) = abort("Reified connected is not supported."); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_increasing_set_reif.mzn0000644000175000017500000000062314536677021023625 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate fzn_increasing_set_reif(array[int] of var set of int: x, var bool: b) = b <-> forall(i in index_set(x) diff { min(index_set(x)) }) (x[i-1] <= x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_array_set_union.mzn0000644000175000017500000000074614536677021023032 0ustar kaolkaol/* Constrain z to be the union of the elements in x */ predicate fzn_array_set_union(array[int] of var set of int: x, var set of int: z) = if length(x)=0 then z={} elseif length(x)=1 then z=x[min(index_set(x))] else let { int: l=min(index_set(x)); int: u=max(index_set(x)); array[l..u-1] of var set of ub_array(x): y; } in y[l]=x[l] union x[l+1] /\ forall (i in l+2..u) (y[i-1]=y[i-2] union x[i]) /\ z=y[u-1] endif; libminizinc-2.8.2/share/minizinc/std/member_set.mzn0000644000175000017500000000057414536677021021075 0ustar kaolkaolinclude "fzn_member_set.mzn"; include "fzn_member_set_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array or set 'x'. %-----------------------------------------------------------------------------% predicate member_set(array[int] of var set of $$E: x, var set of $$E: y) = fzn_member_set(x, y); libminizinc-2.8.2/share/minizinc/std/global_cardinality_low_up.mzn0000644000175000017500000000113014536677021024150 0ustar kaolkaolinclude "global_cardinality.mzn"; /** @group globals.deprecated Requires that for all \p i, the value \a cover[\p i] appears at least \a lbound[\p i] and at most \a ubound[\p i] times in the array \a x. This constraint is deprecated. Use global_cardinality(x, cover, lbound, ubound) instead. */ predicate global_cardinality_low_up(array[$X] of var int: x, array[$Y] of int: cover, array[$Y] of int: lbound, array[$Y] of int: ubound) = global_cardinality(x, cover, lbound, ubound); libminizinc-2.8.2/share/minizinc/std/fzn_increasing_float_reif.mzn0000644000175000017500000000062014536677021024134 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate fzn_increasing_float_reif(array[int] of var float: x, var bool: b) = b <-> forall(i in index_set(x) diff { min(index_set(x)) }) (x[i-1] <= x[i]); libminizinc-2.8.2/share/minizinc/std/table_int.mzn.deprecated.mzn0000644000175000017500000000025414536677021023611 0ustar kaolkaolpredicate table_int( array[$$E] of var int: x, array[int, $$E] of int: t ) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_strictly_increasing_int_opt_reif.mzn0000644000175000017500000000132214536677021026440 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in strict increasing order iff b is true %-----------------------------------------------------------------------------% predicate fzn_strictly_increasing_int_opt_reif(array[int] of var opt int: x, var bool: b) = let { array[int] of var opt int: xx = array1d(x); array[1..length(xx)] of var int: y; constraint forall(i in 1..length(xx)) ( y[i] = if occurs(xx[i]) then deopt(xx[i]) elseif i = 1 then lb_array(xx) - 1 else y[i-1] endif ); } in b <-> forall (i in 2..length(y) where occurs(xx[i])) ( deopt(xx[i]) > y[i-1] ); libminizinc-2.8.2/share/minizinc/std/fzn_inverse_in_range.mzn0000644000175000017500000000155414536677021023144 0ustar kaolkaolinclude "global_cardinality.mzn"; predicate fzn_inverse_in_range(array[int] of var int: f, array[int] of var int: invf) = forall(i in index_set(f)) ( f[i] in index_set(invf) -> (invf[f[i]] == i) ) /\ forall(j in index_set(invf)) ( invf[j] in index_set(f) -> (f[invf[j]] == j) ) /\ redundant_constraint( strengthen_injection_for_inverse_in_range(f, invf) ) /\ redundant_constraint( strengthen_injection_for_inverse_in_range(invf, f) ); predicate strengthen_injection_for_inverse_in_range(array[int] of var int: f, array[int] of var int: invf) = let { set of int: sinvf = { i | i in index_set(invf) where dom(invf[i]) subset index_set(f) }, } in global_cardinality(f, [ i | i in sinvf ], [ 1 | i in sinvf ] ); libminizinc-2.8.2/share/minizinc/std/sum_pred.mzn0000644000175000017500000000072214536677021020564 0ustar kaolkaolinclude "fzn_sum_pred.mzn"; include "fzn_sum_pred_reif.mzn"; /** @group globals.math Requires that the sum of \a cs[\p i1]..\a cs[\p iN] equals \a s, where \p i1..\p iN are the elements of the \a i th set in \a sets. Nb: not called 'sum' as in the constraints catalog because 'sum' is a MiniZinc built-in function. */ predicate sum_pred( var $$X: i, array[$$X] of set of $$Y: sets, array[$$Y] of int: cs, var int: s ) = fzn_sum_pred(i, sets, cs, s); libminizinc-2.8.2/share/minizinc/std/fzn_circuit.mzn0000644000175000017500000000120714536677021021264 0ustar kaolkaolinclude "all_different.mzn"; predicate fzn_circuit(array[int] of var int: x) = if length(x) = 0 then true else let { set of int: S = index_set(x), int: l = min(S), int: n = card(S), array[S] of var 1..n: order } in all_different(x) /\ all_different(order) /\ forall(i in S)(x[i] != i) /\ order[l] = 1 /\ %forall(i in S)(order[i] != n -> order[x[i]] = order[i] + 1) /\ %forall(i in S)(order[i] == n -> x[i] = l ); forall(i in S)(order[x[i]] = if order[i] = n then 1 else order[i] + 1 endif) endif; %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_lex_lesseq_float.mzn0000644000175000017500000000104514536677021023153 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_lesseq_float(array[int] of var float: x, array[int] of var float: y) = lex_lesseq_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_alternative_reif.mzn0000644000175000017500000000046114536677021023146 0ustar kaolkaolinclude "span.mzn"; predicate fzn_alternative_reif(var opt int: s0, var int: d0, array[int] of var opt int: s, array[int] of var int: d, var bool: b) = b <-> ( sum(i in index_set(s))(occurs(s[i])) = occurs(s0) /\ span(s0,d0,s,d) ); libminizinc-2.8.2/share/minizinc/std/cumulatives.mzn0000644000175000017500000000305014536677021021304 0ustar kaolkaolinclude "fzn_cumulatives.mzn"; /** @group globals.scheduling We have a set of tasks given by start times \a s, durations \a d, resource requirements \a r, and machines \a m. We also have a set of machines given by resource bounds \a b. Finally, we have a Boolean flag \a upper. The constraint requires that forall \p i, \a m[\p i] is in the index set of \a b and that for each machine \p j and time instant \p t, either no task assigned to \p j executes at \p \t, or the total resource requirement of such tasks is not greater than, if \a upper is true, or not less than, if \a upper is false, the given bound \a b[\a j]. Resource requirements can be positive (for consumption) or negative (for production). Assumptions: - forall \p i, \a d[\p i] >= 0 */ predicate cumulatives( array[$$E] of var int: s, array[$$E] of var int: d, array[$$E] of var int: r, array[$$E] of var $$M: m, array[$$M] of var int: b, bool: upper ) = assert( index_sets_agree(s, d) /\ index_sets_agree(s, r) /\ index_sets_agree(s, m), "cumulatives: the 4 first array arguments must have identical index sets", if length(s) >= 1 then assert( lb_array(d) >= 0, "cumulatives: durations must be non-negative" ) /\ assert( lb_array(m) >= min(index_set(b)) /\ ub_array(m) <= max(index_set(b)), "cumulatives: machines must be in the index set of the 5th argument" ) /\ fzn_cumulatives(s, d, r, m, b, upper, min(index_set(b))) endif ); libminizinc-2.8.2/share/minizinc/std/all_different.mzn0000644000175000017500000000236614536677021021552 0ustar kaolkaolinclude "fzn_all_different_int.mzn"; include "fzn_all_different_int_opt.mzn"; include "fzn_all_different_int_reif.mzn"; include "fzn_all_different_set.mzn"; include "fzn_all_different_set_reif.mzn"; include "analyse_all_different.mzn"; /** @group globals.alldifferent Constrain the elements in the array \a x to be pairwise different. */ predicate all_different(array[$X] of var int: x) = analyse_all_different(array1d(x)) /\ fzn_all_different_int(array1d(x)); /** @group globals.alldifferent Constrain the elements in the array \a x to be pairwise different. */ predicate all_different(array[$X] of var set of int: x) = fzn_all_different_set(array1d(x)); /** @group globals.alldifferent Constrain the non-absent elements in the array \a x to be pairwise different. The absent value <> is allowed to occur multiple times. */ predicate all_different(array[$X] of var opt int: x) = analyse_all_different(array1d(x)) /\ fzn_all_different_int_opt(array1d(x)); % Synonyms for the above. predicate alldifferent(array[$X] of var int: x) = all_different(array1d(x)); predicate alldifferent(array[$X] of var set of int: x) = all_different(array1d(x)); predicate alldifferent(array[$X] of var opt int: x) = all_different(array1d(x)); libminizinc-2.8.2/share/minizinc/std/fzn_lex_chain_lesseq_int.mzn0000644000175000017500000000041514536677021024002 0ustar kaolkaolinclude "lex_lesseq.mzn"; predicate fzn_lex_chain_lesseq_int(array[int, int] of var int: a) = let { set of int: is2 = index_set_2of2(a); } in ( forall(j in is2 where j+1 in is2) ( lex_lesseq(col(a, j), col(a, j+1)) ) ); libminizinc-2.8.2/share/minizinc/std/member_bool.mzn0000644000175000017500000000056414536677021021234 0ustar kaolkaolinclude "fzn_member_bool.mzn"; include "fzn_member_bool_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array or set 'x'. %-----------------------------------------------------------------------------% predicate member_bool(array[int] of var bool: x, var bool: y) = fzn_member_bool(x, y); libminizinc-2.8.2/share/minizinc/std/fzn_arg_max_float.mzn0000644000175000017500000000163514536677021022432 0ustar kaolkaolpredicate fzn_maximum_arg_float(array[int] of var float: x, var int: i) = let { int: l = min(index_set(x)); int: u = max(index_set(x)); float: uy = ub_array(x); } in if exists(j in l..u)(lb(x[j]) = uy) then let { array[l..u] of var bool: d; } in % max is known to be uy x[i] = uy /\ % ith case must be equal to ub forall(j in l..u)(x[j] = uy -> i <= j) /\ % lower bound d[l] = (x[l] = uy) /\ forall(j in l+1..u)(d[j] <-> (d[j-1] \/ (x[j] = uy))) /\ forall(j in l..u)(not d[j] -> i >= j+1) % upper bound else let { float: ly = lb_array(x); array[l..u] of var ly..uy: y; array[l..u] of var l..u: mi; } in y[l] = x[l] /\ mi[l] = l /\ i = mi[u] /\ forall (j in l+1 .. u) ( y[j] == max(x[j],y[j-1]) /\ mi[j] = if y[j-1] >= x[j] then mi[j-1] else j endif ) endif; libminizinc-2.8.2/share/minizinc/std/lex_chain_lesseq_bool.mzn0000644000175000017500000000101114536677021023257 0ustar kaolkaolinclude "fzn_lex_chain_lesseq_bool.mzn"; include "fzn_lex_chain_lesseq_bool_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the columns of matrix \a a are lexicographically sorted, % non-decreasing. %-----------------------------------------------------------------------------% predicate lex_chain_lesseq_bool(array[int, int] of var bool: a) = fzn_lex_chain_lesseq_bool(a); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_lex_lesseq_int_reif.mzn0000644000175000017500000000112514536677021023644 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate fzn_lex_lesseq_int_reif(array[int] of var int: x, array[int] of var int: y, var bool: c) = c <-> lex_lesseq_std_decomposition(x,y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_array_int_union.mzn0000644000175000017500000000045314536677021023024 0ustar kaolkaol/* Constrain y to be the set of the elements in x */ predicate fzn_array_int_union(array[int] of var int: x, var set of int: y) = y = array_union([let { var set of dom(x[i]): s; constraint x[i] in s /\ card(s)=1; } in s | i in index_set(x)]); libminizinc-2.8.2/share/minizinc/std/output/0000755000175000017500000000000014536677021017557 5ustar kaolkaollibminizinc-2.8.2/share/minizinc/std/output/array2d_bool.mzn0000644000175000017500000000161114536677021022663 0ustar kaolkaol/** @group stdlib.output Create string to visualise a 2D boolean array \a x as a checkered board. */ function string: show_array2d_bool(array[int,int] of var bool: x) ::output_only; function string: show_array2d_bool(array[int,int] of bool: x) = if length(x) != 0 then let { int: one_digits = floor(log10(max(index_set_1of2(x)))) + 1; int: two_digits = floor(log10(max(index_set_2of2(x)))) + 1; } in concat(i in 1..two_digits) ( concat(q in 1..one_digits)(" ") ++ " " ++ concat(j in index_set_2of2(x))( let { int: digit = (j div pow(10, two_digits - i)) mod 10; } in if digit != 0 \/ j > pow(10, two_digits - i) then show (digit) else " " endif ) ++ "\n" ) ++ concat(i in index_set_1of2(x))( concat(q in 1..(one_digits - (floor(log10(i)) + 1)))(" ") ++ "\(i) " ++ concat(j in index_set_2of2(x))(if x[i,j] then "█" else " " endif) ++ "\n" ) endif; libminizinc-2.8.2/share/minizinc/std/output/gantt.mzn0000644000175000017500000000363614536677021021432 0ustar kaolkaol/** @group stdlib.output Create string Gantt chart from task \a start times, duration \a dur, and their names \a name. */ function string: show_gantt(array[$$T] of var int: start, array[$$T] of var int: dur, array[$$T] of string: name) ::output_only; function string: show_gantt(array[$$T] of int: start, array[$$T] of int: dur, array[$$T] of string: name) = let { string: dot = "•"; int: n_dots = 80; string: block = "█"; int: final = max([start[i] + dur[i] | i in index_set(start)]); set of int: span = min(start)..final; array[0..n_dots] of int: thresholds = array1d(0..n_dots, [ceil(min(start) + i * length(span) / n_dots) | i in 0..n_dots-1] ++ [final]); int: name_len = max([string_length(name[i]) | i in index_set(start) ]); array[int] of index_set(start): sort = arg_sort(start); string: dot_line = concat(i in 1..name_len + 1)(" ") ++ concat(i in 1..n_dots) (dot); string: legend = concat(i in 1..name_len + 1)(" ") ++ concat(iv in [thresholds[i*10] | i in 0..n_dots div 10 -1]) (show_int(-10, iv)) ++ "\(final)"; } in legend ++ "\n" ++ dot_line ++ "\n" ++ concat(i in index_set(sort)) ( format_justify_string(name_len, name[sort[i]]) ++ " " ++ concat(d in 1..n_dots where thresholds[d] <= start[sort[i]] + dur[sort[i]]) ( if card(thresholds[d-1]..thresholds[d] intersect start[sort[i]]..start[sort[i]] + dur[sort[i]]) > 0 then block else " " endif ) ++ " \(start[sort[i]]) - \(start[sort[i]] + dur[sort[i]])\n" ) ++ dot_line ++ "\n" ++ legend; /** @group stdlib.output Create string Gantt chart from task \a start times and duration \a dur, using the index set as name for the tasks. */ function string: show_gantt(array[$$T] of var int: start, array[$$T] of var int: dur) ::output_only; function string: show_gantt(array[$$T] of int: start, array[$$T] of int: dur) = show_gantt(start, dur, array1d(index_set(start), [show(i) | i in index_set(start)])); libminizinc-2.8.2/share/minizinc/std/fzn_path_enum_reif.mzn0000644000175000017500000000061414536677021022610 0ustar kaolkaolinclude "tree.mzn"; include "subgraph.mzn"; predicate fzn_path_reif(array[int] of $$N: from, array[int] of $$N: to, var $$N: s, var $$N: t, array[$$N] of var bool: ns, array[int] of var bool: es, var bool: b) = abort("Reified path constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_low_up_closed_reif.mzn0000644000175000017500000000120114536677021027362 0ustar kaolkaolpredicate fzn_global_cardinality_low_up_closed_reif(array[int] of var int: x, array[int] of int: cover, array[int] of int: lbound, array[int] of int: ubound, var bool: b) = b <-> ( forall(i in index_set(x))( x[i] in { d | d in array2set(cover) } ) /\ global_cardinality_low_up(x, cover, lbound, ubound) /\ % Implied condition length(x) in sum(lbound)..sum(ubound)); include "global_cardinality_low_up.mzn"; libminizinc-2.8.2/share/minizinc/std/arg_sort_float.mzn.deprecated.mzn0000644000175000017500000000030514536677021024652 0ustar kaolkaolpredicate arg_sort_float(array[int] of var float:x, array[int] of var int:p) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_diffn_nonstrict_k_reif.mzn0000644000175000017500000000177014536677021024337 0ustar kaolkaolpredicate fzn_diffn_nonstrict_k_reif(array[int,int] of var int: box_posn, array[int,int] of var int: box_size, var bool: b) = let { set of int: DIMS= index_set_2of2(box_posn) } in b <-> forall(b1, b2 in index_set_1of2(box_posn) where b1 < b2) (fzn_diffn_nonstrict_nonoverlap_k_for_reif([ box_posn[b1,j] | j in DIMS ], [ box_size[b1,j] | j in DIMS ], [ box_posn[b2,j] | j in DIMS ], [ box_size[b2,j] | j in DIMS ] ) ) ; predicate fzn_diffn_nonstrict_nonoverlap_k_for_reif(array[int] of var int: x1, array[int] of var int: w1, array[int] of var int: x2, array[int] of var int: w2) = exists(j in index_set(x1)) (w1[j] = 0 \/ w2[j] = 0 \/ x1[j] + w1[j] <= x2[j] \/ x2[j] + w2[j] <= x1[j]); libminizinc-2.8.2/share/minizinc/std/fzn_table_int_reif.mzn0000644000175000017500000000716514536677021022601 0ustar kaolkaol%-----------------------------------------------------------------------------% % A table constraint table(x, t) represents the constraint x in t where we % consider each row in t to be a tuple and t as a set of tuples. %-----------------------------------------------------------------------------% %-----------------------------------------------------------------------------% % Reified version % % We only support special cases of a few variables. % % The approach is to add the Boolean variable to the list of variables and % create an extended table. The extended table covers all combinations of % assignments to the original variables, and every entry in it is padded with a % value that depends on whether that entry occurs in the original table. % % For example, the original table constraint % % x y % --- % 2 3 % 5 8 % 4 1 % % reified with a Boolean b is turned into a table constraint of the form % % x y b % --------- % 2 3 true % 5 8 true % 4 1 true % ... false % ... false % for all other pairs (x,y) % ... false % predicate fzn_table_int_reif(array[int] of var int: x, array[int, int] of int: t, var bool: b) = let { int: n_vars = length(x) } in assert(n_vars in 1..5, "'table' constraints in a reified context " ++ "are only supported for 1..5 variables.", if n_vars = 1 then x[1] in { t[it,1] | it in index_set_1of2(t) } <-> b else let { set of int: ix = index_set(x), set of int: full_size = 1..product(i in ix)( dom_size(x[i]) ), array[full_size, 1..n_vars + 1] of int: t_b = array2d(full_size, 1..n_vars + 1, if n_vars = 2 then [ let { array[ix] of int: tpl = [i1,i2] } in (tpl ++ [bool2int(aux_is_in_table(tpl,t))])[p] | i1 in dom(x[1]), i2 in dom(x[2]), p in 1..n_vars + 1 ] else if n_vars = 3 then [ let { array[ix] of int: tpl = [i1,i2,i3] } in (tpl ++ [bool2int(aux_is_in_table(tpl,t))])[p] | i1 in dom(x[1]), i2 in dom(x[2]), i3 in dom(x[3]), p in 1..n_vars + 1 ] else if n_vars = 4 then [ let { array[ix] of int: tpl = [i1,i2,i3,i4] } in (tpl ++ [bool2int(aux_is_in_table(tpl,t))])[p] | i1 in dom(x[1]), i2 in dom(x[2]), i3 in dom(x[3]), i4 in dom(x[4]), p in 1..n_vars + 1 ] else % if n_vars = 5 then [ let { array[ix] of int: tpl = [i1,i2,i3,i4,i5] } in (tpl ++ [bool2int(aux_is_in_table(tpl,t))])[p] | i1 in dom(x[1]), i2 in dom(x[2]), i3 in dom(x[3]), i4 in dom(x[4]), i5 in dom(x[5]), p in 1..n_vars + 1 ] endif endif endif ) } in fzn_table_int(x ++ [bool2int(b)], t_b) endif ); test aux_is_in_table(array[int] of int: e, array[int, int] of int: t) = exists(i in index_set_1of2(t))( forall(j in index_set(e))( t[i,j] = e[j] ) ); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/regular_nfa.mzn0000644000175000017500000000651414536677021021240 0ustar kaolkaolinclude "fzn_regular_nfa.mzn"; include "fzn_regular_nfa_reif.mzn"; include "fzn_regular_nfa_set.mzn"; include "fzn_regular_nfa_set_reif.mzn"; /** @group globals.extensional The sequence of values in array \a x is accepted by the NFA with transition function \a d, initial state \a q0 and accepting states \a F. The transition function maps states (from enumerated type \a State) and values (from type \a Val) to sets of states. */ predicate regular_nfa( array[int] of var $$Val: x, array[$$State,$$Val] of set of $$State: d, $$State: q0, set of $$State: F ) = let { any: State = index_set_1of2(d); any: Val = index_set_2of2(d); any: q_off = min(State) - 1; any: dd = [ (s,v): { i - q_off | i in d[s,v] } | s in State, v in Val ]; any: qq0 = q0 - q_off; any: FF = { i - q_off | i in F }; } in fzn_regular_nfa(x, card(State), Val, dd, qq0, FF); /** @group globals.extensional The sequence of values in array \a x (which must all be in the range 1..\a S) is accepted by the NFA of \a Q states with input 1..\a S and transition function \a d (which maps (1..\a Q, 1..\a S) -> set of 1..\a Q)) and initial state \a q0 (which must be in 1..\a Q) and accepting states \a F (which all must be in 1..\a Q). */ predicate regular_nfa( array[int] of var int: x, int: Q, int: S, array[int,int] of set of int: d, int: q0, set of int: F ) =assert(Q > 0, "regular_nfa: 'Q' must be greater than zero") /\ assert(S > 0, "regular_nfa: 'S' must be greater than zero") /\ assert( index_set_1of2(d) = 1..Q /\ index_set_2of2(d) == 1..S, "regular_nfa: the transition function 'd' must be [1..Q,1..S]", ) /\ assert( forall([d[i, j] subset 1..Q | i in 1..Q, j in 1..S]), "regular_nfa: transition function 'd' points to states outside 1..Q", ) /\ assert( % Nb: we need the parentheses around the expression otherwise the % parser thinks it's a generator call! (q0 in 1..Q), "regular_nfa: start state 'q0' not in 1..Q", ) /\ assert( F subset 1..Q, "regular_nfa: final states in 'F' contain states outside 1..Q", ) /\ fzn_regular_nfa(x, Q, S, d, q0, F); /** @group globals.extensional The sequence of values in array \a x (which must all be in the range \a S) is accepted by the NFA of \a Q states with input \a S and transition function \a d (which maps (1..\a Q, \a S) -> set of 1..\a Q)) and initial state \a q0 (which must be in 1..\a Q) and accepting states \a F (which all must be in 1..\a Q). */ predicate regular_nfa( array[int] of var int: x, int: Q, set of int: S, array[int,int] of set of int: d, int: q0, set of int: F ) = assert(Q > 0, "regular_nfa: 'Q' must be greater than zero") /\ assert(card(S) > 0, "regular_nfa: 'S' must be non empty") /\ assert(S = min(S)..max(S), "regular_nfa: 'S' must be a range") /\ assert( index_set_1of2(d) = 1..Q /\ index_set_2of2(d) == S, "regular_nfa: the transition function 'd' must be [1..Q,S]", ) /\ assert( forall([d[i, j] subset 1..Q | i in 1..Q, j in S]), "regular_nfa: transition function 'd' points to states outside 1..Q", ) /\ assert( % Nb: we need the parentheses around the expression otherwise the % parser thinks it's a generator call! (q0 in 1..Q), "regular_nfa: start state 'q0' not in 1..Q", ) /\ assert( F subset 1..Q, "regular_nfa: final states in 'F' contain states outside 1..Q", ) /\ fzn_regular_nfa(x, Q, S, d, q0, F); libminizinc-2.8.2/share/minizinc/std/lex_lesseq_bool.mzn0000644000175000017500000000147614536677021022134 0ustar kaolkaolinclude "fzn_lex_lesseq_bool.mzn"; include "fzn_lex_lesseq_bool_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate lex_lesseq_bool(array[int] of var bool: x ::promise_ctx_antitone, array[int] of var bool: y ::promise_ctx_monotone) = fzn_lex_lesseq_bool(x, y); predicate lex_leq_bool(array[int] of var bool: x ::promise_ctx_antitone, array[int] of var bool: y ::promise_ctx_monotone) = lex_lesseq_bool(x, y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_lex2_reif.mzn0000644000175000017500000000056114536677021021503 0ustar kaolkaolinclude "lex_lesseq.mzn"; predicate fzn_lex2_reif(array[int, int] of var int: x, var bool: b) = b <-> ( lex_chain_lesseq(x) /\ lex_chain_lesseq( %% transpose array2d(index_set_2of2(x), index_set_1of2(x), [x[i, j] | j in index_set_2of2(x), i in index_set_1of2(x)] ) ) ); libminizinc-2.8.2/share/minizinc/std/increasing_float.mzn0000644000175000017500000000063114536677021022254 0ustar kaolkaolinclude "fzn_increasing_float.mzn"; include "fzn_increasing_float_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate increasing_float(array[$X] of var float: x) = fzn_increasing_float(array1d(x)); libminizinc-2.8.2/share/minizinc/std/globals.mzn0000644000175000017500000001141214536677021020367 0ustar kaolkaol/*** @groupdef globals.alldifferent All-Different and related constraints @groupdef globals.lexicographic Lexicographic constraints @groupdef globals.sort Sorting constraints @groupdef globals.channeling Channeling constraints @groupdef globals.counting Counting constraints These constraints count and restrict how many times certain values occur in an array of variables. MiniZinc will automatically generate the basic counting constraints below from expressions such as \[count(i in x)(i=c) <= d\], so you can write models in this much more readable style instead of using these predicates. However, if your model contains multiple counting constraints over the same array, constraints like \[distribute\] or \[global_cardinality\] below may be useful. @groupdef globals.array Array-related constraints @groupdef globals.set Set-related constraints @groupdef globals.math Mathematical constraints @groupdef globals.packing Packing constraints @groupdef globals.scheduling Scheduling constraints @groupdef globals.graph Graph constraints Many of these constraints operate on graphs that are represented as lists of edges. The constraints take a given (fixed) graph as arguments, which is represented using two arrays, \[from\] and \[to\], representing the graph with edges \[(from[i],to[i])\], where \[from[i]\] and \[to[i]\] are nodes of the graph. @groupdef globals.extensional Extensional constraints (table, regular etc.) @groupdef globals.learning Machine learning constraints @groupdef globals.deprecated Deprecated constraints */ include "all_different.mzn"; include "all_different_except.mzn"; include "all_different_except_0.mzn"; include "all_disjoint.mzn"; include "all_equal.mzn"; include "alternative.mzn"; include "among.mzn"; include "among_fn.mzn"; include "arg_sort.mzn"; include "arg_min.mzn"; include "arg_max.mzn"; include "arg_val.mzn"; include "at_least.mzn"; include "at_most.mzn"; include "at_most1.mzn"; include "bin_packing.mzn"; include "bin_packing_capa.mzn"; include "bin_packing_load.mzn"; include "bin_packing_load_fn.mzn"; include "bounded_path.mzn"; include "circuit.mzn"; include "circuit_opt.mzn"; include "connected.mzn"; include "cost_mdd.mzn"; include "cost_regular.mzn"; include "count.mzn"; include "count_fn.mzn"; include "cumulative.mzn"; include "cumulative_opt.mzn"; include "cumulatives.mzn"; include "dag.mzn"; include "decreasing.mzn"; include "diffn.mzn"; include "diffn_nonstrict.mzn"; include "diffn_k.mzn"; include "diffn_nonstrict_k.mzn"; include "disjoint.mzn"; include "disjunctive.mzn"; include "disjunctive_strict.mzn"; include "disjunctive_opt.mzn"; include "disjunctive_strict_opt.mzn"; include "distribute.mzn"; include "distribute_fn.mzn"; include "element.mzn"; include "exactly.mzn"; include "geost.mzn"; include "global_cardinality.mzn"; include "global_cardinality_fn.mzn"; include "global_cardinality_closed.mzn"; include "global_cardinality_closed_fn.mzn"; include "global_cardinality_low_up.mzn"; include "global_cardinality_low_up_closed.mzn"; include "increasing.mzn"; include "int_set_channel.mzn"; include "inverse.mzn"; include "inverse_fn.mzn"; include "inverse_in_range.mzn"; include "inverse_set.mzn"; include "knapsack.mzn"; include "lex_greatereq.mzn"; include "lex_greater.mzn"; include "lex_lesseq.mzn"; include "lex_less.mzn"; include "lex_chain_lesseq.mzn"; include "lex_chain_greatereq.mzn"; include "lex_chain_lesseq_orbitope.mzn"; include "lex_chain_greatereq_orbitope.mzn"; include "lex_chain_less.mzn"; include "lex_chain_greater.mzn"; include "lex2.mzn"; include "lex2_strict.mzn"; include "link_set_to_booleans.mzn"; include "maximum.mzn"; include "mdd.mzn"; include "mdd_nondet.mzn"; include "member.mzn"; include "minimum.mzn"; include "network_flow.mzn"; include "neural_net.mzn"; include "nvalue.mzn"; include "nvalue_fn.mzn"; include "partition_set.mzn"; include "piecewise_linear.mzn"; include "piecewise_linear_non_continuous.mzn"; include "range.mzn"; include "range_fn.mzn"; include "reachable.mzn"; include "regular.mzn"; include "regular_nfa.mzn"; include "regular_regexp.mzn"; include "roots.mzn"; include "roots_fn.mzn"; include "seq_precede_chain.mzn"; include "sliding_sum.mzn"; include "sort.mzn"; include "sort_fn.mzn"; include "span.mzn"; include "steiner.mzn"; include "strictly_decreasing.mzn"; include "strictly_increasing.mzn"; include "strict_lex2.mzn"; include "subcircuit.mzn"; include "subgraph.mzn"; include "sum_pred.mzn"; include "sum_set.mzn"; include "symmetric_all_different.mzn"; include "table.mzn"; include "tree.mzn"; include "value_precede.mzn"; include "value_precede_chain.mzn"; include "var_sqr_sym.mzn"; include "var_perm_sym.mzn"; include "weighted_spanning_tree.mzn"; include "write.mzn"; include "writes.mzn"; include "writes_seq.mzn"; libminizinc-2.8.2/share/minizinc/std/fzn_dag_reif.mzn0000644000175000017500000000031414536677021021360 0ustar kaolkaolpredicate fzn_dag_reif(array[int] of $$N: from, array[int] of $$N: to, array[$$N] of var bool: ns, array[int] of var bool: es, var bool: b) = abort("Reified dag is not supported"); libminizinc-2.8.2/share/minizinc/std/fzn_cumulative.mzn0000644000175000017500000000362714536677021022010 0ustar kaolkaolpredicate fzn_cumulative(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b) = let { set of int: Tasks = {i | i in index_set(s) where ub(r[i]) > 0 /\ ub(d[i]) > 0 } } in if 0==card(Tasks) then /*true*/ 0==card(index_set(s)) \/ b>=0 else let { int: early = min([ lb(s[i]) | i in Tasks ]), int: late = max([ ub(s[i]) + ub(d[i]) | i in Tasks ]) } in ( if late - early > 5000 then fzn_cumulative_task(s, d, r, b) else fzn_cumulative_time(s, d, r, b) endif ) endif ; predicate fzn_cumulative_time(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b) = let { set of int: Tasks = {i | i in index_set(s) where ub(r[i]) > 0 /\ ub(d[i]) > 0 }, int: early = min([ lb(s[i]) | i in Tasks ]), int: late = max([ ub(s[i]) + ub(d[i]) | i in Tasks ]) } in ( forall( t in early..late ) ( b >= sum( i in Tasks ) ( (s[i] <= t /\ t < s[i] + d[i]) * r[i] ) ) ); predicate fzn_cumulative_task(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b) = let { set of int: Tasks = { i | i in index_set(s) where ub(r[i]) > 0 /\ ub(d[i]) > 0 } } in ( forall(j in Tasks) ( % Note: i can equal j. If j has a duration of 0, then it is not considered. b >= sum(i in Tasks) ( (s[i] <= s[j] /\ s[j] < s[i] + d[i] ) * r[i] ) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_geost_bb.mzn0000644000175000017500000000205014536677021021403 0ustar kaolkaolpredicate fzn_geost_bb( int : k , array[int,int] of int : rect_size , array[int,int] of int : rect_offset , array[int ] of set of int : shape , array[int,int] of var int : x , array[int ] of var int : kind , array[int ] of var int : l , array[int ] of var int : u ) = % Two useful definitions let { set of int: DIMS = 1..k; set of int: OBJECTS = index_set(kind); } in % Posting the geost constraint fzn_geost(k, rect_size, rect_offset, shape, x, kind) /\ % Posting the bounding box constraints forall(o in OBJECTS)( forall(s in dom(kind[o]))( (kind[o] = s -> forall(r in shape[s], j in DIMS)( x[o,j] + rect_offset[r,j] >= l[j] /\ x[o,j] + rect_offset[r,j] + rect_size[r,j] <= u[j] ) ) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_piecewise_linear_reif.mzn0000644000175000017500000000053414536677021024140 0ustar kaolkaolpredicate fzn_piecewise_linear_reif(var float: x, var float: y, array[int] of float: xi, array[int] of float: vi, var bool: b) = abort("Reified piecewise_linear constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/value_precede_chain_set.mzn.deprecated.mzn0000644000175000017500000000027014536677021026466 0ustar kaolkaolpredicate value_precede_chain_set(array[int] of int: c, array[int] of var set of int: x) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/fzn_inverse_set.mzn0000644000175000017500000000057114536677021022153 0ustar kaolkaolpredicate fzn_inverse_set(array[int] of var set of int: f, array[int] of var set of int: invf) = forall(i in index_set(f)) ( f[i] subset index_set(invf) ) /\ forall(j in index_set(invf)) ( invf[j] subset index_set(f) ) /\ forall(i in index_set(f), j in index_set(invf)) ( (j in f[i] <-> i in invf[j]) ); libminizinc-2.8.2/share/minizinc/std/experimental/0000755000175000017500000000000014536677021020714 5ustar kaolkaollibminizinc-2.8.2/share/minizinc/std/experimental/on_restart/0000755000175000017500000000000014536677021023074 5ustar kaolkaollibminizinc-2.8.2/share/minizinc/std/experimental/on_restart/fzn_on_restart_complete.mzn0000644000175000017500000000033714536677021030552 0ustar kaolkaol/* Abandon and mark search as complete when argument variable is assigned `true'. */ predicate fzn_on_restart_complete(var bool: marker) = abort("experimental on_restart feature `complete' not supported by target solver"); libminizinc-2.8.2/share/minizinc/std/experimental/on_restart/fzn_on_restart_uniform_int.mzn0000644000175000017500000000040714536677021031271 0ustar kaolkaol/* Set `out` to be a random value between `low` and `high` (inclusive) from a uniform distribution */ predicate fzn_on_restart_uniform_int(int: low, int: high, var int: out) = abort("experimental on_restart feature `uniform int' not supported by target solver"); libminizinc-2.8.2/share/minizinc/std/experimental/on_restart/fzn_on_restart_sol_int.mzn0000644000175000017500000000033714536677021030411 0ustar kaolkaol/* Set `out` to be a the last solution value of `input` on each restart */ predicate fzn_on_restart_sol_int(var int: input, var int: out) = abort("experimental on_restart feature `sol int' not supported by target solver"); libminizinc-2.8.2/share/minizinc/std/experimental/on_restart/fzn_on_restart_sol_bool.mzn0000644000175000017500000000034314536677021030547 0ustar kaolkaol/* Set `out` to be a the last solution value of `input` on each restart */ predicate fzn_on_restart_sol_bool(var bool: input, var bool: out) = abort("experimental on_restart feature `sol bool' not supported by target solver"); libminizinc-2.8.2/share/minizinc/std/experimental/on_restart/fzn_on_restart_last_val_float.mzn0000644000175000017500000000036114536677021031731 0ustar kaolkaol/* Set `out` to be a the last assigned value of `input` on each restart */ predicate fzn_on_restart_last_val_float(var float: input, var float: out) = abort("experimental on_restart feature `last val float' not supported by target solver"); libminizinc-2.8.2/share/minizinc/std/experimental/on_restart/fzn_on_restart_last_val_int.mzn0000644000175000017500000000035114536677021031415 0ustar kaolkaol/* Set `out` to be a the last assigned value of `input` on each restart */ predicate fzn_on_restart_last_val_int(var int: input, var int: out) = abort("experimental on_restart feature `last val int' not supported by target solver"); libminizinc-2.8.2/share/minizinc/std/experimental/on_restart/fzn_on_restart_last_val_set.mzn0000644000175000017500000000040014536677021031411 0ustar kaolkaolinclude "experimental/on_restart.mzn"; /* Set `out` to be a the last assigned value of `input` on each restart */ predicate fzn_on_restart_last_val_set(var set of int: input, var set of int: out) = out = { m | m in ub(input) where last_val(m in input)} libminizinc-2.8.2/share/minizinc/std/experimental/on_restart/fzn_on_restart_status.mzn0000644000175000017500000000126314536677021030264 0ustar kaolkaol/* Set the variable `s` to one of the following numbers before solving and after each restart to reflect the result of searching since the last restart: - 1 (START) -> The solver has not yet been restarted - 2 (UNKNOWN) -> No solution has been found since the last restart - 3 (UNSAT) -> The search space was (provably) exhausted and no solution was found since the last restart - 4 (SAT) -> A solution was found since the last restart - 5 (OPT) -> The (provably) optimal solution for the search space was found since the last restart */ predicate fzn_on_restart_status(var int: s) = abort("experimental on_restart feature `status' not supported by target solver"); libminizinc-2.8.2/share/minizinc/std/experimental/on_restart/fzn_on_restart_sol_set.mzn0000644000175000017500000000036614536677021030414 0ustar kaolkaolinclude "experimental/on_restart.mzn"; /* Set `out` to be a the last solution value of `input` on each restart */ predicate fzn_on_restart_sol_set(var set of int: input, var set of int: out) = out = { m | m in ub(input) where sol(m in input)} libminizinc-2.8.2/share/minizinc/std/experimental/on_restart/fzn_on_restart_uniform_float.mzn0000644000175000017500000000042114536677021031600 0ustar kaolkaol/* Set `out` to be a random value between `low` and `high` (inclusive) from a uniform distribution */ predicate fzn_on_restart_uniform_float(float: low, float: high, var float: out) = abort("experimental on_restart feature `uniform float' not supported by target solver"); libminizinc-2.8.2/share/minizinc/std/experimental/on_restart/fzn_on_restart_sol_float.mzn0000644000175000017500000000034714536677021030725 0ustar kaolkaol/* Set `out` to be a the last solution value of `input` on each restart */ predicate fzn_on_restart_sol_float(var float: input, var float: out) = abort("experimental on_restart feature `sol float' not supported by target solver"); libminizinc-2.8.2/share/minizinc/std/experimental/on_restart/fzn_on_restart_last_val_bool.mzn0000644000175000017500000000035514536677021031562 0ustar kaolkaol/* Set `out` to be a the last assigned value of `input` on each restart */ predicate fzn_on_restart_last_val_bool(var bool: input, var bool: out) = abort("experimental on_restart feature `last val bool' not supported by target solver"); libminizinc-2.8.2/share/minizinc/std/experimental/on_restart.mzn0000644000175000017500000002061614536677021023627 0ustar kaolkaolinclude "experimental/on_restart/fzn_on_restart_complete.mzn"; include "experimental/on_restart/fzn_on_restart_last_val_bool.mzn"; include "experimental/on_restart/fzn_on_restart_last_val_float.mzn"; include "experimental/on_restart/fzn_on_restart_last_val_int.mzn"; include "experimental/on_restart/fzn_on_restart_last_val_set.mzn"; include "experimental/on_restart/fzn_on_restart_sol_bool.mzn"; include "experimental/on_restart/fzn_on_restart_sol_float.mzn"; include "experimental/on_restart/fzn_on_restart_sol_int.mzn"; include "experimental/on_restart/fzn_on_restart_sol_set.mzn"; include "experimental/on_restart/fzn_on_restart_status.mzn"; include "experimental/on_restart/fzn_on_restart_uniform_float.mzn"; include "experimental/on_restart/fzn_on_restart_uniform_int.mzn"; /*** @groupdef experimental.on_restart On Restart These annotations and functions provide the basic building blocks to implement meta-heuristics triggered on restart and governed search with the use of solver internal values and functionality. */ /** @group experimental.on_restart A search annotation that triggers a function to be executed on restart */ ann: on_restart(string: pred); /** @group experimental.on_restart Reports the status of the solver (before restarting). */ enum STATUS = {START, UNKNOWN, UNSAT, SAT, OPT}; function var STATUS: status() ::promise_total = let { var STATUS: ret; constraint fzn_on_restart_status(ret); } in ret; /** @group experimental.on_restart When complete is set to 'true', then it marks the search as complete. */ predicate complete() = complete_reif(true); predicate complete_reif(var bool: marker) = fzn_on_restart_complete(marker); /** @group experimental.on_restart Returns a new random value between \a low and \a high chosen from a uniform distribution whenver the solver restarts. */ function var $$E: uniform_on_restart($$E: low, $$E: high) ::no_cse ::promise_total = let { var low..high: ret; constraint fzn_on_restart_uniform_int(low, high, ret); } in ret; /** @group experimental.on_restart Returns a new random value from the set \a S chosen from a uniform distribution whenver the solver restarts. */ function var $$E: uniform_on_restart(set of $$E: S) ::no_cse = if card(S) == max(S) - min(S) + 1 then uniform_on_restart(min(S), max(S)) else [ i | i in S ][uniform_on_restart(1, card(S))] endif; /** @group experimental.on_restart Returns a new random value between \a low and \a high chosen from a uniform distribution whenver the solver restarts. */ function var float: uniform_on_restart(float: low, float: high) ::no_cse ::promise_total = let { var low..high: ret; constraint fzn_on_restart_uniform_float(low, high, ret); } in ret; /** @group experimental.on_restart Provides access to last values taken by a model variables. The last_val functions are only safe to use when the STATUS has been SAT or OPT. */ function var bool: last_val(var bool: x) ::promise_total = if is_fixed(x) then fix(x) else let { var bool: ret; constraint fzn_on_restart_last_val_bool(x, ret); } in ret endif; /** @group experimental.on_restart Provides access to last values taken by a model variables. The last_val functions are only safe to use when the STATUS has been SAT or OPT. */ function var float: last_val(var float: x) ::promise_total = if is_fixed(x) then fix(x) else let { var lb(x)..ub(x): ret; constraint fzn_on_restart_last_val_float(x, ret); } in ret endif; /** @group experimental.on_restart Provides access to last values taken by a model variables. The last_val functions are only safe to use when the STATUS has been SAT or OPT. */ function var $$E: last_val(var $$E: x) ::promise_total = if is_fixed(x) then fix(x) else let { var dom(x): ret; constraint fzn_on_restart_last_val_int(x, ret); } in ret endif; /** @group experimental.on_restart Provides access to last values taken by a model variables. The last_val functions are only safe to use when the STATUS has been SAT or OPT. */ function var opt $$E: last_val(var opt $$E: x) ::promise_total = if is_fixed(x) then fix(x) elseif is_fixed(occurs(x)) then if fix(occurs(x)) then last_val(deopt(x)) else <> endif else let { var opt dom(x): ret; constraint occurs(ret) = last_val(occurs(x)); constraint deopt(ret) = last_val(deopt(x)); } in ret endif; /** @group experimental.on_restart Provides access to last values taken by a model variables. The last_val functions are only safe to use when the STATUS has been SAT or OPT. */ function var set of $$E: last_val(var set of $$E: x) ::promise_total = if is_fixed(x) then fix(x) else let { var set of ub(x): ret; constraint fzn_on_restart_last_val_set(x, ret); } in ret endif; /** @group experimental.on_restart Provides access to solution values of model variables. The sol function are only safe to use when the STATUS has been SAT or OPT. */ function var bool: sol(var bool: x) ::promise_total = if is_fixed(x) then fix(x) else let { var bool: ret; constraint fzn_on_restart_sol_bool(x, ret); } in ret endif; /** @group experimental.on_restart Provides access to solution values of model variables. The sol function are only safe to use when the STATUS has been SAT or OPT. */ function var float: sol(var float: x) ::promise_total = if is_fixed(x) then fix(x) else let { var lb(x)..ub(x): ret; constraint fzn_on_restart_sol_float(x, ret); } in ret endif; /** @group experimental.on_restart Provides access to solution values of model variables. The sol function are only safe to use when the STATUS has been SAT or OPT. */ function var $$E: sol(var $$E: x) ::promise_total = if is_fixed(x) then fix(x) else let { var dom(x): ret; constraint fzn_on_restart_sol_int(x, ret); } in ret endif; /** @group experimental.on_restart Provides access to solution values of model variables. The sol function are only safe to use when the STATUS has been SAT or OPT. */ function var opt $$E: sol(var opt $$E: x) ::promise_total = if is_fixed(x) then fix(x) elseif is_fixed(occurs(x)) then if fix(occurs(x)) then sol(deopt(x)) else <> endif else let { var opt dom(x): ret; constraint occurs(ret) = sol(occurs(x)); constraint deopt(ret) = sol(deopt(x)); } in ret endif; /** @group experimental.on_restart Provides access to solution values of model variables. The sol function are only safe to use when the STATUS has been SAT or OPT. */ function var set of $$E: sol(var set of $$E: x) ::promise_total = if is_fixed(x) then fix(x) else let { var set of ub(x): ret; constraint fzn_on_restart_sol_set(x, ret); } in ret endif; /** @group experimental.on_restart Provides access to solution values of model variables. The sol function are only safe to use when the STATUS has been SAT or OPT. */ function array[$$E] of var bool: sol(array[$$E] of var bool: x) = [i: sol(x[i]) | i in index_set(x)]; /** @group experimental.on_restart Provides access to solution values of model variables. The sol function are only safe to use when the STATUS has been SAT or OPT. */ function array[$$E] of var float: sol(array[$$E] of var float: x) = [i: sol(x[i]) | i in index_set(x)]; /** @group experimental.on_restart Provides access to solution values of model variables. The sol function are only safe to use when the STATUS has been SAT or OPT. */ function array[$$E] of var $$F: sol(array[$$E] of var $$F: x) = [i: sol(x[i]) | i in index_set(x)]; /** @group experimental.on_restart round_robin provides a metaheuristic for LNS where each neighbourhood is chosen sequentially. */ predicate round_robin(array[int] of var bool: nbhs) = let { int: len = length(nbhs); % Transposed neighbourhoods in case of index set not starting from 1 array[1..len] of var bool: t_nbhs = [ bv | bv in nbhs]; % Neighbourhood selection var -1..len-1: select; } in forall(i in 1..len) ( (select-1 == i) -> t_nbhs[i]) /\ if status() == START then select = -1 else select = (last_val(select) + 1) mod len endif; /** @group experimental.on_restart 'basic_lns' provides LNS in its simplest form where one nbh is applied on every restart. */ predicate basic_lns(var bool: nbh) = (status() != START) -> nbh; libminizinc-2.8.2/share/minizinc/std/experimental/all.mzn0000644000175000017500000000031614536677021022212 0ustar kaolkaol/*** @groupdef experimental Experimental Features These features are experimental and might significantly change or be removed in future versions of MiniZinc. */ include "experimental/on_restart.mzn"; libminizinc-2.8.2/share/minizinc/std/circuit_opt.mzn0000644000175000017500000000052614536677021021274 0ustar kaolkaolinclude "fzn_circuit_opt.mzn"; include "fzn_circuit_opt_reif.mzn"; /** @group globals.graph Constrains the elements of \a x to define a circuit where \a x[\p i] = \p j means that \p j is the successor of \p i. Absent elements do not take part in the circuit. */ predicate circuit(array[$$E] of var opt $$E: x) = fzn_circuit_opt(x); libminizinc-2.8.2/share/minizinc/std/fzn_range.mzn0000644000175000017500000000065314536677021020722 0ustar kaolkaolpredicate fzn_range(array[int] of var int: x, var set of int: s, var set of int: t) = % All values in 's' must map to a value in 't'. forall(i in ub(s)) ( i in s -> x[i] in t ) /\ % All values in 't' must be mapped from a value in 's'. forall(i in ub(t)) ( i in t -> exists(j in ub(s)) ( j in s /\ x[j] == i ) ); libminizinc-2.8.2/share/minizinc/std/fzn_cumulatives_decomp.mzn0000644000175000017500000000255014536677021023514 0ustar kaolkaol% Decomposition provided by Mats Carlsson predicate fzn_cumulatives_decomp(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, array[int] of var int: m, array[int] of var int: b, bool: upper) = let { set of int: Tasks = index_set(s); } in forall (j in Tasks) ( let { var bool: cov1 = exists(i in Tasks)(fzn_cumulatives_task_at(s[i], d[i], m[i], s[j], m[j])); var bool: cov2 = exists(i in Tasks)(fzn_cumulatives_task_at(s[i], d[i], m[i], s[j] + d[j], m[j])); var int: load1 = sum(i in Tasks)(r[i] * fzn_cumulatives_task_at(s[i], d[i], m[i], s[j], m[j])); var int: load2 = sum(i in Tasks)(r[i] * fzn_cumulatives_task_at(s[i], d[i], m[i], s[j] + d[j], m[j])); } in (upper /\ cov1 -> load1 <= b[m[j]]) /\ (upper /\ cov2 -> load2 <= b[m[j]]) /\ (not upper /\ cov1 -> load1 >= b[m[j]]) /\ (not upper /\ cov2 -> load2 >= b[m[j]]) ); predicate fzn_cumulatives_task_at(var int: si, var int: di, var int: mi, var int: at, var int: mach) = si <= at /\ si + di > at /\ mi = mach; libminizinc-2.8.2/share/minizinc/std/fzn_member_int.mzn0000644000175000017500000000050314536677021021741 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array or set 'x'. %-----------------------------------------------------------------------------% predicate fzn_member_int(array[int] of var int: x, var int: y) = exists(i in index_set(x)) ( x[i] == y ); libminizinc-2.8.2/share/minizinc/std/fzn_increasing_int.mzn0000644000175000017500000000062414536677021022620 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in increasing order (duplicates are allowed). %-----------------------------------------------------------------------------% predicate fzn_increasing_int(array[int] of var int: x) = if length(x) > 1 then forall(i in index_set(x) diff { min(index_set(x)) }) (x[i-1] <= x[i]) endif; libminizinc-2.8.2/share/minizinc/std/bin_packing_load_fn.mzn0000644000175000017500000000141214536677021022671 0ustar kaolkaolinclude "fzn_bin_packing_load.mzn"; /** @group globals.packing Returns the load of each bin resulting from packing each item \p i with weight \a w[\p i] into \a bin[\p i], where the load is defined as the sum of the weights of the items in each bin. Assumptions: - forall \p i, \a w[\p i] >=0 */ function array[int] of var int: bin_packing_load(array[int] of var int: bin, array[int] of int: w) :: promise_total = assert(index_set(bin) == index_set(w), "bin_packing_load: the bin and weight arrays must have identical index sets", let { array[dom_bounds_array(bin)] of var 0..sum(w): load ::is_defined_var; constraint fzn_bin_packing_load(load,bin,w) ::defines_var(load); } in load ); libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_low_up.mzn0000644000175000017500000000107614536677021025036 0ustar kaolkaolinclude "count_fn.mzn"; predicate fzn_global_cardinality_low_up(array[int] of var int: x, array[int] of int: cover, array[int] of int: lbound, array[int] of int: ubound) = forall(i in index_set(cover))( if ubound[i] >= length(x) then count(xi in x)(xi = cover[i]) >= lbound[i] elseif lbound[i] <= 0 then count(xi in x)(xi = cover[i]) <= ubound[i] else count(xi in x)(xi = cover[i]) in lbound[i]..ubound[i] endif ); libminizinc-2.8.2/share/minizinc/std/fzn_geost_reif.mzn0000644000175000017500000000242414536677021021752 0ustar kaolkaolinclude "fzn_geost_nonoverlap_k.mzn"; include "fzn_geost_nonoverlap_k_reif.mzn"; predicate fzn_geost_reif( int : k , array[int,int] of int : rect_size , array[int,int] of int : rect_offset , array[int ] of set of int : shape , array[int,int] of var int : x , array[int ] of var int : kind , var bool: b ) = % A few useful definitions let { set of int: DIMS = 1..k; set of int: SHAPES = 1..length(shape); set of int: OBJECTS = index_set(kind); } in b <-> forall(o1, o2 in OBJECTS where o1 < o2)( forall(s1 in dom(kind[o1]), s2 in dom(kind[o2]))( (kind[o1] = s1 /\ kind[o2] = s2 -> forall(r1 in shape[s1], r2 in shape[s2])( fzn_geost_nonoverlap_k( [ x[o1,j] + rect_offset[r1,j] | j in DIMS ], [ rect_size[r1,j] | j in DIMS ], [ x[o2,j] + rect_offset[r2,j] | j in DIMS ], [ rect_size[r2,j] | j in DIMS ] ) ) ) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_member_set.mzn0000644000175000017500000000052114536677021021742 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array of set 'x'. %-----------------------------------------------------------------------------% predicate fzn_member_set(array[int] of var set of int: x, var set of int: y) = exists(i in index_set(x)) ( x[i] == y ); libminizinc-2.8.2/share/minizinc/std/subcircuit.mzn0000644000175000017500000000066314536677021021126 0ustar kaolkaolinclude "fzn_subcircuit.mzn"; include "fzn_subcircuit_reif.mzn"; /** @group globals.graph Constrains the elements of \a x to define a subcircuit where \a x[\p i] = \p j means that \p j is the successor of \p i and \a x[\p i] = \p i means that \p i is not in the circuit. */ predicate subcircuit(array[$$E] of var $$E: x) = fzn_subcircuit(x); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_sum_set.mzn0000644000175000017500000000026614536677021021305 0ustar kaolkaolpredicate fzn_sum_set(array[int] of int: vs, array[int] of int: ws, var set of int: x, var int: s) = s == sum(j in index_set(vs)) ( (vs[j] in x) * ws[j] ); libminizinc-2.8.2/share/minizinc/std/element_int.mzn0000644000175000017500000000046214536677021021252 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that 'y' is the ith element of the array 'x'. %-----------------------------------------------------------------------------% predicate element_int(var $$E: i, array[$$E] of var $$T: x, var $$T: y) = y = x[i]; libminizinc-2.8.2/share/minizinc/std/stdlib/0000755000175000017500000000000014536677021017500 5ustar kaolkaollibminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_ann.mzn0000644000175000017500000006410214536677021022346 0ustar kaolkaol/*** @groupdef stdlib.annotations Annotations These annotations control evaluation and solving behaviour. */ /*** @groupdef stdlib.annotations.general General annotations */ /** @group stdlib.annotations.general Empty annotation, will be removed during compilation */ annotation empty_annotation; /** @group stdlib.annotations.general Declare function as total, i.e. it does not put any constraints on its arguments. */ annotation promise_total; /** @group stdlib.annotations.general Declare that expression may have undefined result (to avoid warnings) */ annotation maybe_partial; /** @group stdlib.annotations.general Declare that the annotated variable should be added to the output of the model. This annotation only has an effect when the model does not have an output item. */ annotation add_to_output; /** @group stdlib.annotations.general Declare that the annotated variable \a x should be added to the output of the model. This annotation only has an effect when the model does not have an output item. */ annotation 'output'(any $T: x :: annotated_expression); /** @group stdlib.annotations.general Declare that the annotated variable \a x should be added to the output of the model. This annotation only has an effect when the model does not have an output item. */ annotation 'output'(array[$U] of any $T: x :: annotated_expression); /** @group stdlib.annotations.general Declare that the annotated variable should not be added to the output of the model. This annotation only has an effect when the model does not have an output item. */ annotation no_output; /** @group stdlib.annotations.general Declare that the annotated variable should be only used for output. This annotation can be used to define variables that are required for solution checkers, or that are necessary for the output item. The annotated variable must be par. */ annotation output_only; /** @group stdlib.annotations.general Declare that the annotated variable is required for checking solutions. */ annotation mzn_check_var; /** @group stdlib.annotations.general Declare that the annotated variable is required for checking solutions and has an enum type \a x. */ annotation mzn_check_enum_var(array[int] of set of int: x); /** @group stdlib.annotations.general Declare a name \a n for the annotated expression. */ annotation mzn_expression_name(string: n); /** @group stdlib.annotations.general Declare a name \a n for the annotated constraint. */ annotation mzn_constraint_name(string: n); /** @group stdlib.annotations.general Used internally by the compiler to set the output section \a s for an output item. An output item can be annotated directly with a string literal to set its output section as in ``output :: "my_section" ["hello, world\n"]`` or using the syntax ``output ["hello, world\n"] to "my_section``. */ function ann: mzn_output_section(string: s) = mzn_output_section(s, false); function ann: mzn_output_section(ann: x) = x; annotation mzn_output_section(string: s, bool: json); /** @group stdlib.annotations.general State that a function is deprecated since MiniZinc version \a version with humand readable \a explanation. */ annotation mzn_deprecated(string: version, string: explanation); function any $T: mzn_deprecate(string: name, string: version, string: msg, any $T: x); function array[$U] of any $T: mzn_deprecate(string: name, string: version, string: msg, array[$U] of any $T: x); /** @group stdlib.annotations.general Declare the annotated variable as being functionally defined. This annotation is introduced into FlatZinc code by the compiler. */ annotation is_defined_var; /** @group stdlib.annotations.general Declare a variable as being introduced by the compiler. */ annotation var_is_introduced; /** @group stdlib.annotations.general Declare variable: \a c as being functionally defined by the annotated constraint. This annotation is introduced into FlatZinc code by the compiler. */ function ann: defines_var(var opt $T: c) ::mzn_internal_representation; /** @group stdlib.annotations.general Declare an array of variables \a arr as being functionally defined by the annotated constraint. This annotation is introduced into FlatZinc code by the compiler. */ function ann: defines_var(array[$U] of var opt $T: arr) ::mzn_internal_representation; /** @group stdlib.annotations.general Declare that the annotated array should be printed by the solver with the given index sets \a a. This annotation is introduced into FlatZinc code by the compiler. */ function ann: output_array(array[$U] of set of int: a) ::mzn_internal_representation; /** @group stdlib.annotations.general Declare that the annotated variable should be printed by the solver. This annotation is introduced into FlatZinc code by the compiler. */ annotation output_var; /** @group stdlib.annotations.general Declare that the annotated expression is used to map an expression back from FlatZinc to MiniZinc. */ annotation is_reverse_map; /** @group stdlib.annotations.general Document the function or variable declaration item with the string \a s. */ annotation doc_comment(string: s); /** @group stdlib.annotations.general Representation of the call-stack when the annotated item was introduced, as a string \a s. Can be used to uniquely identify variables and constraints across different compilations of a model that may have different names. This annotations is introduced into FlatZinc code by the compiler and is retained if --keep-paths argument is used. */ annotation mzn_path(string: s); /** @group stdlib.annotations.general Used to attach a name \a s to an expression, this should also propagate to any sub-expressions or decomposition of the annotated expression. String annotations on expressions are re-written as expression_name annotations */ annotation expression_name(string: s); /** @group stdlib.annotations.general Used to attach a name \a s to a constraint and its decomposition. String annotations on constraint keywords are re-written as constraint_name annotations */ annotation constraint_name(string: s); /** @group stdlib.annotations.general Used internally by the compiler */ annotation mzn_rhs_from_assignment; /** @group stdlib.annotations.general Marks a constraint as a recorded domain changing constraint (when mzn2fzn called with -g flag */ annotation domain_change_constraint; /** @group stdlib.annotations.general This annotation will prevent calls to the function annotated to be added to the Common Subexpression Elimination map. **WARNING:** using this annotation might result in duplicated constraints when used incorrectly. */ annotation no_cse; /** @group stdlib.annotations.general Declare the function to be commutative, i.e., the function has the same result regardless of the order in which the function parameters are provided. **WARNING:** a commutative function must have only arguments of a single type, or a single array as an argument. */ annotation promise_commutative; /** @group stdlib.annotations.general Mark annotation argument as annotated expression */ annotation annotated_expression; /** @group stdlib.annotations.general Used internally by the compiler */ annotation mzn_add_annotated_expression(int: idx); /** @group stdlib.annotations.general Enables caching of the result of the annotated function declaration such that further calls with the same arguments yield the cached initial result. Currently only supported for par functions with at least one parameter. */ annotation cache_result; /*** @groupdef stdlib.annotations.prop Propagation strength annotations */ /** @group stdlib.annotations.prop Annotate a constraint to use domain propagation */ ann: domain_propagation = domain; /** @group stdlib.annotations.prop Annotate a constraint to use bounds propagation */ ann: bounds_propagation = bounds; /** @group stdlib.annotations.prop Annotate a constraint to use value propagation */ annotation value_propagation; /** @group stdlib.annotations.prop Annotate a constraint to use domain propagation Note: This annotation will be deprecated. Use domain_propagation instead. */ annotation domain; /** @group stdlib.annotations.prop Annotate a constraint to use bounds propagation Note: This annotation will be deprecated. Use bounds_propagation instead. */ annotation bounds; /*** @groupdef stdlib.annotations.search Search annotations */ /** @group stdlib.annotations.search Sequentially perform the searches specified in array \a s */ annotation seq_search(array[int] of ann: s); annotation int_search( array[int] of var int: x, ann: select, ann: choice, ann: explore, ); /** @group stdlib.annotations.search Specify search on variables \a x, with variable selection strategy \a select, value choice strategy \a choice, and exploration strategy \a explore. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation int_search( array[$X] of var int: x, ann: select, ann: choice, ann: explore, ) = int_search(array1d(x), select, choice, explore); /** @group stdlib.annotations.search Specify search on variables \a x, with variable selection strategy \a select, and value choice strategy \a choice. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation int_search( array[$X] of var int: x, ann: select, ann: choice ) = int_search(x,select,choice,complete); /** @group stdlib.annotations.search Search annotation for optional integer variables. Specify search on variables \a x, with variable selection strategy \a select, value choice strategy \a choice, and exploration strategy \a explore. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation int_search(array[$X] of var opt int: x, ann: select, ann: choice, ann: explore) = int_search([if occurs(xi) then deopt(xi) else 0 endif | xi in x],select,choice,explore); /** @group stdlib.annotations.search Search annotation for optional integer variables. Specify search on variables \a x, with variable selection strategy \a select, and value choice strategy \a choice. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation int_search(array[$X] of var opt int: x, ann: select, ann: choice) = int_search([if occurs(xi) then deopt(xi) else 0 endif | xi in x],select,choice); annotation bool_search( array[int] of var bool: x, ann: select, ann: choice, ann: explore ); /** @group stdlib.annotations.search Specify search on variables \a x, with variable selection strategy \a select, value choice strategy \a choice, and exploration strategy \a explore. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation bool_search( array[$X] of var bool: x, ann: select, ann: choice, ann: explore ) = bool_search(array1d(x), select, choice, explore); /** @group stdlib.annotations.search Specify search on variables \a x, with variable selection strategy \a select, and value choice strategy \a choice. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation bool_search( array[$X] of var bool: x, ann: select, ann: choice ) = bool_search(x,select,choice,complete); /** @group stdlib.annotations.search Search annotation for optional Boolean variables. Specify search on variables \a x, with variable selection strategy \a select, value choice strategy \a choice, and exploration strategy \a explore. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation bool_search(array[$X] of var opt bool: x, ann: select, ann: choice, ann: explore) = bool_search([if occurs(xi) then deopt(xi) else false endif | xi in x],select,choice,explore); /** @group stdlib.annotations.search Search annotation for optional Boolean variables. Specify search on variables \a x, with variable selection strategy \a select, and value choice strategy \a choice. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation bool_search(array[$X] of var opt bool: x, ann: select, ann: choice) = bool_search([if occurs(xi) then deopt(xi) else false endif | xi in x],select,choice); annotation float_search( array[int] of var float: x, float: prec, ann: select, ann: choice, ann: explore ); /** @group stdlib.annotations.search Specify search on variables \a x, with precision \a prec, variable selection strategy \a select, value choice strategy \a choice, and exploration strategy \a explore. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation float_search( array[$X] of var float: x, float: prec, ann: select, ann: choice, ann: explore ) = float_search(array1d(x), prec, select, choice, explore); /** @group stdlib.annotations.search Specify search on variables \a x, with precision \a prec, variable selection strategy \a select, and value choice strategy \a choice. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation float_search( array[$X] of var float: x, float: prec, ann: select, ann: choice ) = float_search(x,prec,select,choice,complete); /** @group stdlib.annotations.search Search annotation for optional float variables. Specify search on variables \a x, with precision \a prec, variable selection strategy \a select, value choice strategy \a choice, and exploration strategy \a explore. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation float_search(array[$X] of var opt float: x, float: prec, ann: select, ann: choice, ann: explore) = float_search([if occurs(xi) then deopt(xi) else 0.0 endif | xi in x],prec,select,choice,explore); /** @group stdlib.annotations.search Search annotation for optional float variables. Specify search on variables \a x, with precision \a prec, variable selection strategy \a select, and value choice strategy \a choice. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation float_search(array[$X] of var opt float: x, float: prec, ann: select, ann: choice) = float_search([if occurs(xi) then deopt(xi) else 0.0 endif | xi in x],prec,select,choice); annotation set_search( array[int] of var set of int: x, ann: select, ann: choice, ann: explore ); /** @group stdlib.annotations.search Specify search on variables \a x, with variable selection strategy \a select, value choice strategy \a choice, and exploration strategy \a explore. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation set_search( array[$X] of var set of int: x, ann: select, ann: choice, ann: explore ) = set_search(array1d(x), select, choice, explore); /** @group stdlib.annotations.search Specify search on variables \a x, with variable selection strategy \a select, and value choice strategy \a choice. If \a x is a multi-dimensional array, it is coerced to one-dimensional in row-major order (as with the array1d function). */ annotation set_search( array[$X] of var set of int: x, ann: select, ann: choice ) = set_search(x,select,choice,complete); /*** @groupdef stdlib.annotations.search.varsel Variable selection annotations */ /** @group stdlib.annotations.search.varsel Search variables in the given order */ annotation input_order; /** @group stdlib.annotations.search.varsel Choose the variable with the smallest domain */ annotation first_fail; /** @group stdlib.annotations.search.varsel Choose the variable with the largest domain */ annotation anti_first_fail; /** @group stdlib.annotations.search.varsel Choose the variable with the smallest value in its domain */ annotation smallest; /** @group stdlib.annotations.search.varsel Choose the variable with the largest value in its domain */ annotation largest; /** @group stdlib.annotations.search.varsel Choose the variable with the largest number of attached constraints */ annotation occurrence; /** @group stdlib.annotations.search.varsel Choose the variable with the smallest domain, breaking ties using the number of attached constraints */ annotation most_constrained; /** @group stdlib.annotations.search.varsel Choose the variable with largest difference between the two smallest values in its domain */ annotation max_regret; /** @group stdlib.annotations.search.varsel Choose the variable with largest domain, divided by the number of attached constraints weighted by how often they have caused failure */ annotation dom_w_deg; /** @group stdlib.annotations.search.varsel Choose the variable with the highest impact so far during the search */ annotation impact; /*** @groupdef stdlib.annotations.search.choice Value choice annotations */ /** @group stdlib.annotations.search.choice Assign values in ascending order */ annotation indomain; /** @group stdlib.annotations.search.choice Assign the smallest value in the domain */ annotation indomain_min; /** @group stdlib.annotations.search.choice Assign the largest value in the domain */ annotation indomain_max; /** @group stdlib.annotations.search.choice Assign the value in the domain closest to the mean of its current bounds */ annotation indomain_middle; /** @group stdlib.annotations.search.choice Assign the middle value in the domain, or the smaller of the two middle values in case of an even number of elements in the domain */ annotation indomain_median; /** @group stdlib.annotations.search.choice Assign a random value from the domain */ annotation indomain_random; /** @group stdlib.annotations.search.choice Bisect the domain, excluding the upper half first */ annotation indomain_split; /** @group stdlib.annotations.search.choice Bisect the domain, randomly selecting which half to exclude first */ annotation indomain_split_random; /** @group stdlib.annotations.search.choice Bisect the domain, excluding the lower half first */ annotation indomain_reverse_split; /** @group stdlib.annotations.search.choice If the domain consists of several contiguous intervals, reduce the domain to the first interval. Otherwise bisect the domain. */ annotation indomain_interval; /** @group stdlib.annotations.search.choice Exclude the smallest value from the domain */ annotation outdomain_min; /** @group stdlib.annotations.search.choice Exclude the largest value from the domain */ annotation outdomain_max; /** @group stdlib.annotations.search.choice Exclude the middle value from the domain */ annotation outdomain_median; /** @group stdlib.annotations.search.choice Exclude a random value from the domain */ annotation outdomain_random; /*** @groupdef stdlib.annotations.search.explore Exploration strategy annotations */ /** @group stdlib.annotations.search.explore Perform a complete search */ annotation complete; /*** @groupdef stdlib.annotations.search.restart Restart annotations */ /** @group stdlib.annotations.search.restart Restart with Luby sequence scaled by \a scale */ annotation restart_luby(int: scale); /** @group stdlib.annotations.search.restart Restart with geometric sequence with parameters \a base and \a scale */ annotation restart_geometric(float: base, int: scale); /** @group stdlib.annotations.search.restart Restart with linear sequence scaled by \a scale */ annotation restart_linear(int: scale); /** @group stdlib.annotations.search.restart Restart after constant number of nodes \a scale */ annotation restart_constant(int: scale); /** @group stdlib.annotations.search.restart Do not restart */ annotation restart_none; /*** @groupdef stdlib.annotations.warmstart Warm start annotations To be put on the solve item, similar to search annotations. A variable can be mentioned several times and in different annotations but only one of the values is taken */ /** @group stdlib.annotations.warmstart Specify an array \a w of warm_start annotations or other warm_start_array annotations. Can be useful to keep the annotation order in FlatZinc for manual updating. Note: if you have search annotations as well, put warm_starts into seq_search in order to have precedence between both, which may matter. */ annotation warm_start_array( array[int] of ann: w ); /** @group stdlib.annotations.warmstart Specify warm start values \a v for an array of booleans \a x */ annotation warm_start( array[int] of var bool: x, array[int] of bool: v ); /** @group stdlib.annotations.warmstart Specify warm start values \a v for an array of integers \a x */ annotation warm_start( array[int] of var int: x, array[int] of int: v ); /** @group stdlib.annotations.warmstart Specify warm start values \a v for an array of floats \a x */ annotation warm_start( array[int] of var float: x, array[int] of float: v ); /** @group stdlib.annotations.warmstart Specify warm start values \a v for an array of sets \a x */ annotation warm_start( array[int] of var set of int: x, array[int] of set of int: v ); /*** @groupdef stdlib.annotations.warmstart.optvals Warm start annotations with optional values The value arrays can contain <> elements (absent values). The following decompositions eliminate those elements because FlatZinc 1.6 does not support optionals. */ /** @group stdlib.annotations.warmstart.optvals Specify warm start values \a v for an array of booleans \a x */ annotation warm_start( array[int] of var bool: x, array[int] of opt bool: v ) = if 0==length(x) \/ 0==length(v) then warm_start( x, [] ) else warm_start( [ x[i] | i in index_set(x) where i-min(index_set(x))+min(index_set(v))>length(v) \/ occurs( v[ i-min(index_set(x))+min(index_set(v)) ] ) ], [ deopt(v[i]) | i in index_set(v) where occurs(v[i]) ] ) endif; /** @group stdlib.annotations.warmstart.optvals Specify warm start values \a v for an array of integers \a x */ annotation warm_start( array[int] of var int: x, array[int] of opt int: v ) = if 0==length(x) \/ 0==length(v) then warm_start( x, [] ) else warm_start( [ x[i] | i in index_set(x) where i-min(index_set(x))+min(index_set(v))>length(v) \/ occurs( v[ i-min(index_set(x))+min(index_set(v)) ] ) ], [ deopt(v[i]) | i in index_set(v) where occurs(v[i]) ] ) endif; /** @group stdlib.annotations.warmstart.optvals Specify warm start values \a v for an array of floats \a x */ annotation warm_start( array[int] of var float: x, array[int] of opt float: v ) = if 0==length(x) \/ 0==length(v) then warm_start( x, [] ) else warm_start( [ x[i] | i in index_set(x) where i-min(index_set(x))+min(index_set(v))>length(v) \/ occurs( v[ i-min(index_set(x))+min(index_set(v)) ] ) ], [ deopt(v[i]) | i in index_set(v) where occurs(v[i]) ] ) endif; /** @group stdlib.annotations.warmstart.optvals Specify warm start values \a v for an array of sets \a x */ annotation warm_start( array[int] of var set of int: x, array[int] of opt set of int: v ) = if 0==length(x) \/ 0==length(v) then warm_start( x, [] ) else warm_start( [ x[i] | i in index_set(x) where i-min(index_set(x))+min(index_set(v))>length(v) \/ occurs( v[ i-min(index_set(x))+min(index_set(v)) ] ) ], [ deopt(v[i]) | i in index_set(v) where occurs(v[i]) ] ) endif; /*** @groupdef stdlib.annotations.lns Large Neighbourhood Search annotations These annotations can be used on the solve item (similar to search annotations) to specify Large Neighbourhood Search meta-heuristics. These annotations specify how the search is restricted to a neighbourhood when a solver restarts. The annotations define which variables will be fixed to their values from a previous solution in that case. All other variables will be reset to their initial domains by the restart. The annotations can be used together with search annotations and restart annotations. */ /** @group stdlib.annotations.lns Random neighbourhood over variables \a x with probability \a p percent Upon restart, each variable in \a x is fixed to the value of the incumbent solution with a probability of \a p percent. */ annotation relax_and_reconstruct(array[int] of var int: x, int: p); /*** @groupdef stdlib.annotations.context Context annotations These are used internally by the compiler, and should not be used in models. */ /** @group stdlib.annotations.context Root context */ annotation ctx_root; /** @group stdlib.annotations.context Positive context */ annotation ctx_pos; /** @group stdlib.annotations.context Negative context */ annotation ctx_neg; /** @group stdlib.annotations.context Mixed context */ annotation ctx_mix; /*** @groupdef stdlib.annotations.symm_red Redundant and symmetry breaking constraints These predicates allow users to mark constraints as e.g. symmetry breaking or redundant, so that solvers can choose to implement them differently. We cannot easily use annotations for this purpose, since annotations are propagated to all constraints in a decomposition, which may be incorrect for redundant or symmetry breaking constraints in the presence of common subexpression elimination (CSE). */ /** @group stdlib.annotations.symm_red Mark \a b as a symmetry breaking constraint */ predicate symmetry_breaking_constraint(var bool: b); % Rewritten to mzn_symmetry_breaking_constraint by typechecker /** @group stdlib.annotations.symm_red Mark \a b as a redundant constraint */ predicate redundant_constraint(var bool: b); % Rewritten to mzn_redundant_constraint by typechecker /** @group stdlib.annotations.symm_red Mark \a b as an implied constraint (synonym for redundant_constraint) */ predicate implied_constraint(var bool: b); % Rewritten to mzn_redundant_constraint by typechecker annotation promise_ctx_monotone; annotation promise_ctx_antitone; annotation mzn_internal_representation; annotation mzn_evaluate_once; libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_opt.mzn0000644000175000017500000002601514536677021022375 0ustar kaolkaol/*** @groupdef stdlib.optiontypes Option type support These functions and predicates implement the standard library for working with option types. Note that option type support is still incomplete. */ /** @group stdlib.optiontypes Return value of \a x if \a x is not absent. Returns undefined when evaluated on absent value. */ function $$T: deopt(opt $$T: x); /** @group stdlib.optiontypes Return value of \a x if \a x is not absent. Returns undefined when evaluated on absent value. */ function $T: deopt(opt $T: x); /** @group stdlib.optiontypes Return array of the value of \a x[i] where \a x[i] is not absent. Returns undefined when evaluated with an absent element. */ function array [$$U] of $$T: deopt(array [$$U] of opt $$T: x) = array1d(index_set(x), [deopt(x[i]) | i in index_set(x)]); /** @group stdlib.optiontypes Return array of the value of \a x[i] where \a x[i] is not absent. Returns undefined when evaluated with an absent element. */ function array [$$U] of $T: deopt(array [$$U] of opt $T: x) = array1d(index_set(x), [deopt(x[i]) | i in index_set(x)]); /** @group stdlib.optiontypes Return value \a x unchanged (since \a x is guaranteed to be non-optional). */ function var $T: deopt(var $T: x) = x; /** @group stdlib.optiontypes Return value \a x unchanged (since \a x is guaranteed to be non-optional). */ function $T: deopt($T: x) = x; /** @group stdlib.optiontypes Return value \a x unchanged (since \a x is guaranteed to be non-optional). */ function array [$U] of var $T: deopt(array [$U] of var $T: x) = x; /** @group stdlib.optiontypes Return array of the value of \a x[i] (assumes that \a x[i] is not absent). */ function array [$$U] of var bool : deopt(array [$$U] of var opt bool : x) :: promise_total = array1d(index_set(x), [deopt(x[i]) | i in index_set(x)]); /** @group stdlib.optiontypes Return array of the value of \a x[i] (assumes that \a x[i] is not absent). */ function array [$$U] of var $$E : deopt(array [$$U] of var opt $$E : x) :: promise_total = array1d(index_set(x), [deopt(x[i]) | i in index_set(x)]); /** @group stdlib.optiontypes Return array of the value of \a x[i] (assumes that \a x[i] is not absent). */ function array [$$U] of var float : deopt(array [$$U] of var opt float : x) :: promise_total = array1d(index_set(x), [deopt(x[i]) | i in index_set(x)]); /** @group stdlib.optiontypes Test if \a x is not absent (always returns true) */ test occurs($T: x) = true; /** @group stdlib.optiontypes Test if \a x is not absent (always returns true) */ test occurs(var $T: x) = true; /** @group stdlib.optiontypes Test if \a x is not absent (always returns true) */ test occurs(set of $$T: x) = true; /** @group stdlib.optiontypes Test if \a x is not absent (always returns true) */ test occurs(var set of $$T: x) = true; /** @group stdlib.optiontypes Test if \a x is not absent */ test occurs(opt $T: x); /** @group stdlib.optiontypes Test if \a x is absent (always returns false) */ test absent($T: x) = false; /** @group stdlib.optiontypes Test if \a x is absent (always returns false) */ test absent(var $T: x) = false; /** @group stdlib.optiontypes Test if \a x is absent (always returns false) */ test absent(set of $$T: x) = false; /** @group stdlib.optiontypes Test if \a x is absent (always returns false) */ test absent(var set of $$T: x) = false; /** @group stdlib.optiontypes Test if \a x is absent */ test absent(opt $T: x) = not occurs(x); /*** @groupdef stdlib.optiontypes.bool Option type support for Booleans */ /** @group stdlib.optiontypes.bool True iff \a x is not absent */ function var bool : occurs(var opt bool: x) ::promise_total = occurs_bool(x); function bool : occurs_bool(opt bool: x) ::promise_total = occurs(x); function bool : occurs_bool(var bool: x) ::promise_total = true; function var bool : occurs_bool(var opt bool: x) ::promise_total = let { any: xx = opt_internal_bool(x); any: b = xx.1; any: dx = xx.2; constraint (x = reverse_map_var_opt(b, dx)) :: is_reverse_map; } in xx.1; /** @group stdlib.optiontypes.bool Return value of \a x (assumes that \a x is not absent) */ function var bool : deopt(var opt bool : x) ::promise_total = deopt_bool(x); function bool : deopt_bool(opt bool : x) ::promise_total = deopt(x); function var bool : deopt_bool(var bool : x) ::promise_total = x; function var bool : deopt_bool(var opt bool : x) ::promise_total = let { any: xx = opt_internal_bool(x); any: b = xx.1; any: dx = xx.2; constraint (x = reverse_map_var_opt(b, dx)) :: is_reverse_map; } in xx.2; /** @group stdlib.optiontypes.bool True iff \a x is absent */ predicate absent(var opt bool: x) = not occurs(x); function tuple(var bool, var bool) : opt_internal_bool(var opt bool: x) ::promise_total = let { var bool: b; var bool: y; } in (b, y); predicate mzn_reverse_map_var(var opt bool: x) = let { any: xx = opt_internal_bool(x); any: b = xx.1; any: dx = xx.2; constraint (x = reverse_map_var_opt(b, dx)) :: is_reverse_map; } in true; /*** @groupdef stdlib.optiontypes.int Option type support for integers */ /** @group stdlib.optiontypes.int True iff \a x is not absent */ function var bool : occurs(var opt int : x) ::promise_total = occurs_int(x); function bool : occurs_int(opt int : x) ::promise_total = occurs(x); function bool : occurs_int(var int : x) ::promise_total = true; function var bool : occurs_int(var opt int : x) ::promise_total = let { any: xx = opt_internal_int(x); any: b = xx.1; any: dx = xx.2; constraint (x = reverse_map_var_opt(b, dx)) :: is_reverse_map; } in xx.1; function var bool : occurs_int(var opt bool : x) ::promise_total = occurs(x); function bool : occurs_int(opt bool : x) ::promise_total = occurs(x); function bool : occurs_int(var bool : x) ::promise_total = true; /** @group stdlib.optiontypes.int Return value of \a x (assumes that \a x is not absent) */ function var $$E : deopt(var opt $$E : x) ::promise_total = deopt_int(x); function int : deopt_int(opt int : x) ::promise_total = deopt(x); function var int : deopt_int(var int : x) ::promise_total = x; function var int : deopt_int(var opt int : x) ::promise_total = let { any: xx = opt_internal_int(x); any: b = xx.1; any: dx = xx.2; constraint (x = reverse_map_var_opt(b, dx)) :: is_reverse_map; } in xx.2; function var bool : deopt_int(var opt bool : x) ::promise_total = deopt(x); function var bool : deopt_int(var bool : x) ::promise_total = x; function bool : deopt_int(opt bool : x) ::promise_total = deopt(x); /** @group stdlib.optiontypes.int True iff \a x is absent */ function var bool: absent(var opt int: x) ::promise_total = not occurs(x); /** @group stdlib.optiontypes.int True if \a x had zero in its original domain. Returns true if absent zero representation is disabled or if it is possible that \( \text{occurs}(x) \wedge \text{deopt}(x) = 0 \) */ function bool: had_zero(var opt int: x) :: cache_result = not mzn_check_absent_zero() \/ (0 in dom(x)); /** @group stdlib.optiontypes.int True if \a x had zero in its original domain. Returns true if absent zero representation is disabled or if it is possible that \( \text{occurs}(x) \wedge \text{deopt}(x) = 0 \) */ function bool: had_zero(opt int: x) = not mzn_check_absent_zero() \/ (x = 0); /** @group stdlib.optiontypes.int True if \a x had zero in its original domain. Returns true if absent zero representation is disabled or if it is possible that \( \text{occurs}(x) \wedge \text{deopt}(x) = 0 \) */ function bool: had_zero(array [int] of var opt int: x) = exists (xi in x) (had_zero(xi)); function tuple(var bool, var int): opt_internal_int(var opt int: x) ::promise_total = if dom(x) = {} then (false, 0) else let { var bool: b; var dom(x) union if mzn_check_absent_zero() then {0} else {} endif: y; constraint if mzn_check_absent_zero() then if had_zero(x) then b \/ y = 0 else b <-> y != 0 endif endif; } in (b, y) endif; predicate mzn_reverse_map_var(var opt int: x) = let { any: xx = opt_internal_int(x); any: b = xx.1; any: dx = xx.2; constraint (x = reverse_map_var_opt(b, dx)) :: is_reverse_map; } in true; /* Internal function used to optimize over option type objective */ function var int: objective_deopt_(var opt int: x, bool: direction) = let { int: worst = if direction then lb(x)-1 else ub(x)+1 endif; } in if occurs(x) then deopt(x) else worst endif; /*** @groupdef stdlib.optiontypes.float Option type support for floats */ /** @group stdlib.optiontypes.float True iff \a x is not absent */ function var bool : occurs(var opt float : x) ::promise_total = occurs_float(x); function bool : occurs_float(opt float : x) ::promise_total = occurs(x); function bool : occurs_float(opt int : x) ::promise_total = occurs(x); function bool : occurs_float(opt bool : x) ::promise_total = occurs(x); function bool : occurs_float(var float : x) ::promise_total = true; function var bool : occurs_float(var opt float : x) ::promise_total = let { any: xx = opt_internal_float(x); any: b = xx.1; any: dx = xx.2; constraint (x = reverse_map_var_opt(b, dx)) :: is_reverse_map; } in xx.1; function var bool : occurs_float(var opt int : x) ::promise_total = occurs_int(x); function bool : occurs_float(var int : x) ::promise_total = true; function var bool : occurs_float(var opt bool : x) ::promise_total = occurs_bool(x); function bool : occurs_float(var bool : x) ::promise_total = true; /** @group stdlib.optiontypes.float Return value of \a x (assumes that \a x is not absent) */ function var float : deopt(var opt float : x) ::promise_total = deopt_float(x); function var float : deopt_float(var float : x) ::promise_total = x; function var float : deopt_float(var opt float : x) ::promise_total = let { any: xx = opt_internal_float(x); any: b = xx.1; any: dx = xx.2; constraint (x = reverse_map_var_opt(b, dx)) :: is_reverse_map; } in xx.2; function var int : deopt_float(var opt int : x) ::promise_total = deopt_int(x); function var int : deopt_float(var int : x) ::promise_total = x; function var bool : deopt_float(var opt bool : x) ::promise_total = deopt_bool(x); function var bool : deopt_float(var bool : x) ::promise_total = x; function float : deopt_float(opt float : x) ::promise_total = deopt(x); function int : deopt_float(opt int : x) ::promise_total = deopt(x); function bool : deopt_float(opt bool : x) ::promise_total = deopt(x); /** @group stdlib.optiontypes.float True iff \a x is absent */ function var bool: absent(var opt float: x) ::promise_total = not occurs(x); function tuple(var bool, var float): opt_internal_float(var opt float: x) ::promise_total = let { var bool: b; var lb(x)..ub(x): y; } in (b, y); predicate mzn_reverse_map_var(var opt float: x) = let { any: xx = opt_internal_float(x); any: b = xx.1; any: dx = xx.2; constraint (x = reverse_map_var_opt(b, dx)) :: is_reverse_map; } in true; function var opt $T: reverse_map_var_opt(var bool: b, var $T: dx) ::output_only; function opt $T: reverse_map_var_opt(bool: occ, $T: dx) ::promise_total = if occ then dx else <> endif; libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_set.mzn0000644000175000017500000002312514536677021022365 0ustar kaolkaol/*** @groupdef stdlib.builtins.set Set operations These functions implement the basic operations on sets. */ /** @group stdlib.builtins.set Test if \a x is an element of the set \a y */ function bool: 'in'( int: x, set of int: y) ::mzn_internal_representation; /** @group stdlib.builtins.set \a x is an element of the set \a y */ function var bool: 'in'(var int: x, var set of int: y); /** @group stdlib.builtins.set \a x is an element of the set \a y. False if \a x is absent. */ function var bool: 'in'(var opt int: x, set of int: y) = occurs(x) /\ deopt(x) in y; /** @group stdlib.builtins.set Test if \a x is an element of the set \a y. False if \a x is absent. */ function bool: 'in'(opt int: x, set of int: y) = occurs(x) /\ deopt(x) in y; /** @group stdlib.builtins.set \a x is an element of the set \a y. False if \a x is absent. */ function var bool: 'in'(var opt int: x, var set of int: y) = occurs(x) /\ deopt(x) in y; /** @group stdlib.builtins.set Test if \a x is an element of the set \a y */ function bool: 'in'( float: x, set of float: y) ::mzn_internal_representation; /** @group stdlib.builtins.set Test if \a x is an element of the set \a y */ function var bool: 'in'(var float: x, set of float: y); /** @group stdlib.builtins.set Test if \a x is an element of the set \a y. False if \a x is absent. */ function bool: 'in'(opt float: x, set of float: y) = occurs(x) /\ deopt(x) in y; /** @group stdlib.builtins.set \a x is an element of the set \a y. False if \a x is absent. */ function var bool: 'in'(var opt float: x, set of float: y) = occurs(x) /\ deopt(x) in y; /** @group stdlib.builtins.set Test if \a x is a subset of \a y */ function bool: 'subset'( set of $T: x, set of $T: y) ::mzn_internal_representation; /** @group stdlib.builtins.set \a x is a subset of \a y */ function var bool: 'subset'(var set of int: x, var set of int: y); /** @group stdlib.builtins.set Test if \a x is a superset of \a y */ function bool: 'superset'( set of $T: x, set of $T: y) ::mzn_internal_representation; /** @group stdlib.builtins.set \a x is a superset of \a y */ function var bool: 'superset'(var set of int: x, var set of int: y); /** @group stdlib.builtins.set Return the union of sets \a x and \a y */ function set of $T: 'union'( set of $T: x, set of $T: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.set Return the union of sets \a x and \a y */ function var set of $$T: 'union'(var set of $$T: x, var set of $$T: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.set Return the intersection of sets \a x and \a y */ function set of $T: 'intersect'( set of $T: x, set of $T: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.set Return the intersection of sets \a x and \a y */ function var set of $$T: 'intersect'(var set of $$T: x, var set of $$T: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.set Return the set difference of sets \(\a x \setminus \a y \) */ function set of $T: 'diff'( set of $T: x, set of $T: y) ::mzn_internal_representation; /** @group stdlib.builtins.set Return the set difference of sets \(\a x \setminus \a y \) */ function var set of $$T: 'diff'(var set of $$T: x, var set of $$T: y) ::mzn_internal_representation; /** @group stdlib.builtins.set Return the symmetric set difference of sets \a x and \a y */ function set of $T: 'symdiff'( set of $T: x, set of $T: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.set Return the symmetric set difference of sets \a x and \a y */ function var set of $$T: 'symdiff'(var set of $$T: x, var set of $$T: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.set Return the set \(\{\a a,\ldots,\a b\}\) */ function set of $$E: '..'($$E: a,$$E: b) ::mzn_internal_representation; /** @group stdlib.builtins.set Return the set \(\{\a a,\ldots,\a b\}\) */ function set of float: '..'(float: a,float: b) ::mzn_internal_representation; /** @group stdlib.builtins.set Return the set \(\{\a a,\ldots,\a b\}\) */ function set of bool: '..'(bool: a,bool: b) = if a then if b then {true} else {} endif elseif b then {false,true} else {false} endif; /** @group stdlib.builtins.set Return the set \(\{\a a,\ldots,\a b-1\}\) */ function set of $$E: '..<'($$E: a,$$E: b) = if a >= b then {} else a..enum_prev(b) endif; /** @group stdlib.builtins.set Return the set \(\{\a a+1,\ldots,\a b\}\) */ function set of $$E: '<..'($$E: a,$$E: b) = if a >= b then {} else enum_next(a)..b endif; /** @group stdlib.builtins.set Return the set \(\{\a a+1,\ldots,\a b-1\}\) */ function set of $$E: '<..<'($$E: a,$$E: b) = if b-a <= 1 then {} else enum_next(a)..enum_prev(b) endif; /** @group stdlib.builtins.set Return the set \(\{\a a,\ldots,\a b-1\}\) */ function set of $$E: '..o'($$E: a) = a..max(enum_of(a)); /** @group stdlib.builtins.set Return the set \(\{\a a,\ldots,\a b-1\}\) */ function set of $$E: '.. (a <= i /\ i <= b)); } in s; /** @group stdlib.builtins.set Return the cardinality of the set \a x */ function int: card( set of $T: x); /** @group stdlib.builtins.set Return the cardinality of the set \a x */ function var int: card(var set of int: x) ::promise_total = let { var 0..(if has_ub_set(x) then card(ub(x)) else infinity endif): c; constraint set_card(x,c); } in c; /** @group stdlib.builtins.set Return the union of the sets in array \a x */ function set of $U: array_union(array[$T] of set of $U: x) ::promise_commutative; /** @group stdlib.builtins.set Return the union of the sets in array \a x */ function var set of $$E: array_union(array[$T] of var set of $$E: x) ::promise_total ::promise_commutative = if length(x)=0 then {} elseif length(x)=1 then array1d(x)[1] else let { var set of ub_array(x): y ::is_defined_var; constraint fzn_array_set_union(array1d(x), y) :: defines_var(y); } in y endif; /** @group stdlib.builtins.set Return the intersection of the sets in array \a x */ function set of $U: array_intersect(array[$T] of set of $U: x) ::promise_commutative; /** @group stdlib.builtins.set Return the intersection of the sets in array \a x. Undefined for empty \a x. */ function var set of $$E: array_intersect(array[$T] of var set of $$E: x) ::promise_commutative = let { constraint length(x) > 0 } in array_intersect_t(x); function var set of $$E: array_intersect_t(array[$T] of var set of $$E: x) :: promise_total = if length(x) = 0 then {} elseif length(x) = 1 then array1d(x)[1] else let { var set of ub_array(x): y :: is_defined_var; constraint fzn_array_set_intersect(array1d(x), y) :: defines_var(y); } in y endif; /** @group stdlib.builtins.set Return the minimum of the set \a s */ function var $$E: min(var set of $$E: s); /** @group stdlib.builtins.set Return the maximum of the set \a s */ function var $$E: max(var set of $$E: s); /* Rewrite set membership on float variables to correct FlatZinc builtin */ predicate set_in(var float: x, set of float: S) = float_set_in(x, S); /** @group stdlib.builtins.set Return a sorted list of the non-overlapping ranges in \a S */ function array[int] of int: set_to_ranges(set of int: S); /** @group stdlib.builtins.set Return a sorted list of the non-overlapping ranges in \a S */ function array[int] of float: set_to_ranges(set of float: S); /** @group stdlib.builtins.set Return a sorted list of the non-overlapping ranges in \a S */ function array[int] of bool: set_to_ranges(set of bool: S) = if S={false} then [false,false] elseif S={true} then [true,true] else [false,true] endif; function array[int] of $$E: set_to_sparse_inverse(set of $$E: S); /* set2iter will be used to redefine compehensions over set decision variables when it has a definition. */ function array[int] of var opt $$E: set2iter(var set of $$E: s) ::mzn_internal_representation; libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_coercion.mzn0000644000175000017500000002206114536677021023371 0ustar kaolkaol/*** @groupdef stdlib.builtins.coercion Coercions These functions implement coercions, or channeling, between different types. */ /** @group stdlib.builtins.coercion Return \( \lceil{ \a x} \rceil \) */ function int: ceil(float: x); /** @group stdlib.builtins.coercion Return \( \lfloor{ \a x} \rfloor \) */ function int: floor(float: x); /** @group stdlib.builtins.coercion Return \a x rounded to nearest integer */ function int: round(float: x); /** @group stdlib.builtins.coercion Return \( \lceil{ \a x} \rceil \) */ function var int: ceil(var float: x) ::promise_total = let { var ceil(lb(x))..ceil(ub(x)): r; constraint float_ceil(x, r); } in r; /** @group stdlib.builtins.coercion Return \( \lfloor{ \a x} \rfloor \) */ function var int: floor(var float: x) ::promise_total = let { var floor(lb(x))..floor(ub(x)): r; constraint float_floor(x, r); } in r; /** @group stdlib.builtins.coercion Return \a x rounded to nearest integer */ function var int: round(var float: x) ::promise_total = let { var floor(lb(x))..ceil(ub(x)): r; constraint float_round(x, r); } in r; /** @group stdlib.builtins.coercion Return Boolean \a b coerced to an integer */ function int: bool2int(bool: b); /** @group stdlib.builtins.coercion Return Boolean \a b coerced to an integer */ function opt int: bool2int(opt bool: b) = if occurs(b) then bool2int(deopt(b)) else <> endif; /** @group stdlib.builtins.coercion Return optional 0/1 integer that is absent iff \a x is absent, and 1 iff \a x occurs and is true. */ function var opt int: bool2int(var opt bool: x) ::promise_total = let { var opt 0..1: xi; constraint absent(xi)=absent(x); constraint deopt(xi)=bool2int(deopt(x)); } in xi; /** @group stdlib.builtins.coercion Return Boolean \a b coerced to a float */ function float: bool2float(bool: b) = if b then 1.0 else 0.0 endif; /** @group stdlib.builtins.coercion Return Boolean \a b coerced to a float */ function opt float: bool2float(opt bool: b) = if occurs(b) then bool2float(deopt(b)) else <> endif; /** @group stdlib.builtins.coercion Return array of Booleans \a x coerced to an array of floats */ function array[$T] of float: bool2float(array[$T] of bool: x) ::promise_total = let { array[int] of bool: xx = array1d(x) } in arrayXd(x,[bool2float(xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.coercion Return array of Booleans \a x coerced to an array of floats */ function array[$T] of var float: bool2float(array[$T] of var bool: x) ::promise_total = let { array[int] of var bool: xx = array1d(x) } in arrayXd(x,[bool2float(xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.coercion Return Boolean \a b coerced to an integer */ function var int: bool2int(var bool: b) ::mzn_internal_representation; /** @group stdlib.builtins.coercion Return array of Booleans \a b coerced to an array of integers */ function array[$T] of var int: bool2int(array[$T] of var bool: b); /** @group stdlib.builtins.coercion Return Boolean \a b coerced to a float */ function var float: bool2float(var bool: b) = int2float(bool2int(b)); /** @group stdlib.builtins.coercion Return integer \a x coerced to a float */ function float: int2float(int: x); /** @group stdlib.builtins.coercion Return integer \a x coerced to a float */ function opt float: int2float(opt int: x) = if occurs(x) then int2float(deopt(x)) else <> endif; /** @group stdlib.builtins.coercion Return integer \a x coerced to a float */ function var float: int2float(var int: x) ::promise_total ::mzn_internal_representation; /** @group stdlib.builtins.coercion Return optional 0/1 float that is absent iff \a x is absent, and 1 iff \a x occurs and is true. */ function var opt float: bool2float(var opt bool: x) ::promise_total = let { var opt 0.0..1.0: xi; constraint absent(xi)=absent(x); constraint deopt(xi)=bool2float(deopt(x)); } in xi; /** @group stdlib.builtins.coercion Return optional 0/1 integer that is absent iff \a x is absent, and 1 iff \a x occurs and is true. */ function var opt float: int2float(var opt int: x) ::promise_total = let { var opt int2float(lb(x))..int2float(ub(x)): xi; constraint absent(xi)=absent(x); constraint deopt(xi)=int2float(deopt(x)); } in xi; function set of int: bool2int(set of bool: b) = if b={false,true} then {0,1} elseif b={false} then {0} elseif b={true} then {1} else {} endif; /** @group stdlib.builtins.coercion Return array of Booleans \a x coerced to an array of integers */ function array[$T] of int: bool2int(array[$T] of bool: x) ::promise_total = let { array[int] of bool: xx = array1d(x) } in arrayXd(x,[bool2int(xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.coercion Return array of sets of Booleans \a x coerced to an array of sets of integers */ function array[$T] of set of int: bool2int(array[$T] of set of bool: x) ::promise_total = let { array[int] of set of bool: xx = array1d(x) } in arrayXd(x,[bool2int(xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.coercion Return array of Booleans \a x coerced to an array of integers */ function array[$T] of var int: bool2int(array[$T] of var bool: x) ::promise_total = let { array[int] of var bool: xx = array1d(x) } in arrayXd(x,[bool2int(xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.coercion Return array of Booleans \a x coerced to an array of integers */ function array[$T] of opt int: bool2int(array[$T] of opt bool: x) = let { array[int] of opt bool: xx = array1d(x) } in arrayXd(x,[bool2int(xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.coercion Return array of Booleans \a x coerced to an array of integers */ function array[$T] of var opt int: bool2int(array[$T] of var opt bool: x) ::promise_total = let { array[int] of var opt bool: xx = array1d(x) } in arrayXd(x,[bool2int(xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.coercion Return array of Booleans \a x coerced to an array of floats */ function array[$T] of opt float: bool2float(array[$T] of opt bool: x) = let { array[int] of opt bool: xx = array1d(x) } in arrayXd(x, [bool2float(xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.coercion Return array of Booleans \a x coerced to an array of floats */ function array[$T] of var opt float: bool2float(array[$T] of var opt bool: x) ::promise_total = let { array[int] of var opt bool: xx = array1d(x) } in arrayXd(x,[bool2float(xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.coercion Return array of integers \a x coerced to an array of floats */ function array[$T] of float: int2float(array[$T] of int: x) ::promise_total = let { array[int] of int: xx = array1d(x) } in arrayXd(x,[int2float(xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.coercion Return array of integers \a x coerced to an array of floats */ function array[$T] of opt float: int2float(array[$T] of opt int: x) ::promise_total = let { array[int] of opt int: xx = array1d(x) } in arrayXd(x,[int2float(xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.coercion Return array of integers \a x coerced to an array of floats */ function array[$T] of var float: int2float(array[$T] of var int: x) ::promise_total = let { array[int] of var int: xx = array1d(x) } in arrayXd(x,[int2float(xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.coercion Return array of optional integers \a x coerced to an array of optional floats */ function array[$T] of var opt float: int2float(array[$T] of var opt int: x) ::promise_total = let { array[int] of var opt int: xx = array1d(x) } in arrayXd(x,[int2float(xx[i]) | i in index_set(xx)]); % Only supported for set of int: % function array[int] of $T: set2array(set of $T); /** @group stdlib.builtins.coercion Return a set of integers \a x coerced to an array of integers */ function array[int] of $$E: set2array(set of $$E: x); /** @group stdlib.debug If \a x is defined and not absent, return \a x, otherwise return \a y. */ function $T: 'default'(opt $T:x, $T: y); /** @group stdlib.debug If \a x is defined and not absent, return \a x, otherwise return \a y. */ function opt $T: 'default'(opt $T:x, opt $T: y); /** @group stdlib.debug If \a x is defined and not absent, return \a x, otherwise return \a y. */ function var $T: 'default'(var opt $T:x, var $T: y); /** @group stdlib.debug If \a x is defined and not absent, return \a x, otherwise return \a y. */ function var opt $T: 'default'(var opt $T:x, var opt $T: y); /** @group stdlib.debug If \a x is defined, return \a x, otherwise return \a y. */ function array[$U] of $T: 'default'(array[$U] of $T:x, array[$U] of $T: y); /** @group stdlib.debug If \a x is defined, return \a x, otherwise return \a y. */ function array[$U] of opt $T: 'default'(array[$U] of opt $T:x, array[$U] of opt $T: y); /** @group stdlib.debug If \a x is defined, return \a x, otherwise return \a y. */ function array[$U] of var $T: 'default'(array[$U] of var $T:x, array[$U] of var $T: y); /** @group stdlib.debug If \a x is defined, return \a x, otherwise return \a y. */ function array[$U] of var opt $T: 'default'(array[$U] of var opt $T:x, array[$U] of var opt $T: y); libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_logic.mzn0000644000175000017500000002160614536677021022671 0ustar kaolkaol/*** @groupdef stdlib.builtins.logic Logical operations Logical operations are the standard operators of Boolean logic. */ /** @group stdlib.builtins.logic Return truth value of \a x ∧ \a y */ function bool: '/\'( bool: x, bool: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.logic Return truth value of \a x ∧ \a y with identity <> = True*/ function bool: '/\'(opt bool: x, opt bool: y) ::promise_commutative = (absent(x) \/ deopt(x)) /\ (absent(y) \/ deopt(y)); /** @group stdlib.builtins.logic Return truth value of \a x ∧ \a y */ function var bool: '/\'(var bool: x, var bool: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.logic Return truth value of \a x ∧ \a y with identity <> = True*/ function var bool: '/\'(var opt bool: x, var opt bool: y) ::promise_commutative = (absent(x) \/ deopt(x)) /\ (absent(y) \/ deopt(y)); /** @group stdlib.builtins.logic Return truth value of \a x ∨ \a y */ function bool: '\/'( bool: x, bool: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.logic Return truth value of \a x ∨ \a y with identity <> = False*/ function bool: '\/'(opt bool: x, opt bool: y) ::promise_commutative = (occurs(x) /\ deopt(x)) \/ (occurs(y) /\ deopt(y)); /** @group stdlib.builtins.logic Return truth value of \a x ∨ \a y */ function var bool: '\/'(var bool: x, var bool: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.logic Return truth value of \a x ∨ \a y with identity <> = False*/ function var bool: '\/'(var opt bool: x, var opt bool: y) ::promise_commutative = (occurs(x) /\ deopt(x)) \/ (occurs(y) /\ deopt(y)); /** @group stdlib.builtins.logic Return truth value of \a x implies \a y */ function bool: '->'( bool: x, bool: y) ::mzn_internal_representation; /** @group stdlib.builtins.logic Return truth value of \a x implies \a y */ function bool: '->'(opt bool: x, opt bool: y) = absent(x) \/ absent(y) \/ (deopt(x) -> deopt(y)); /** @group stdlib.builtins.logic Return truth value of \a x implies \a y */ function var bool: '->'(var bool: x, var bool: y); /** @group stdlib.builtins.logic Return truth value of \a x implies \a y */ function var bool: '->'(var opt bool: x, var opt bool: y) = absent(x) \/ absent(y) \/ (deopt(x) -> deopt(y)); /** @group stdlib.builtins.logic Return truth value of \a y implies \a x */ function bool: '<-'( bool: x, bool: y) ::mzn_internal_representation; /** @group stdlib.builtins.logic Return truth value of \a y implies \a x */ function bool: '<-'(opt bool: x, opt bool: y) = absent(x) \/ absent(y) \/ (deopt(x) <- deopt(y)); /** @group stdlib.builtins.logic Return truth value of \a y implies \a x */ function var bool: '<-'(var bool: x, var bool: y); /** @group stdlib.builtins.logic Return truth value of \a y implies \a x */ function var bool: '<-'(var opt bool: x, var opt bool: y) = absent(x) \/ absent(y) \/ (deopt(x) <- deopt(y)); /** @group stdlib.builtins.logic Return truth value of \a x if-and-only-if \a y */ function bool: '<->'( bool: x, bool: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.logic Return truth value of \a x if-and-only-if \a y */ function bool: '<->'(opt bool: x, opt bool: y) ::promise_commutative = absent(x) \/ absent(y) \/ (deopt(x) <-> deopt(y)); /** @group stdlib.builtins.logic Return truth value of \a x if-and-only-if \a y */ function var bool: '<->'(var bool: x, var bool: y) ::promise_commutative; /** @group stdlib.builtins.logic Return truth value of \a x if-and-only-if \a y */ function var bool: '<->'(var opt bool: x, var opt bool: y) ::promise_commutative = absent(x) \/ absent(y) \/ (deopt(x) <-> deopt(y)); /** @group stdlib.builtins.logic Return truth value of \a x xor \a y */ function bool: 'xor'( bool: x, bool: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.logic Return truth value of \a x xor \a y */ function bool: 'xor'(opt bool: x, opt bool: y) ::promise_commutative = absent(x) \/ absent(y) \/ (deopt(x) xor deopt(y)); /** @group stdlib.builtins.logic Return truth value of \a x xor \a y */ function var bool: 'xor'(var bool: x, var bool: y) ::promise_commutative; /** @group stdlib.builtins.logic Return truth value of \a x xor \a y */ function var bool: 'xor'(var opt bool: x, var opt bool: y) ::promise_commutative = absent(x) \/ absent(y) \/ (deopt(x) xor deopt(y)); /** @group stdlib.builtins.logic Return truth value of the negation of \a x */ function bool: 'not'( bool: x) ::mzn_internal_representation; /** @group stdlib.builtins.logic Negation of \a x if it occurs, otherwise absent */ function opt bool: 'not'(opt bool: x) = if absent(x) then <> else not deopt(x) endif; /** @group stdlib.builtins.logic Return truth value of the negation of \a x */ function var bool: 'not'(var bool: x); /** @group stdlib.builtins.logic Negation of \a x if it occurs, otherwise absent */ function var opt bool: 'not'(var opt bool: x) = if absent(x) then <> else not deopt(x) endif; /** @group stdlib.builtins.logic Return truth value of \(\bigwedge_i \a x[i]\) */ function bool: forall(array[$T] of bool: x) ::promise_commutative; /** @group stdlib.builtins.logic Return truth value of \(\bigwedge_i \a x[i]\) */ function var bool: forall(array[$T] of var bool: x) ::promise_commutative; /** @group stdlib.builtins.logic True iff for any \p i, \a x[i] is absent or true */ predicate forall (array[int] of var opt bool: x) ::promise_commutative = forall ([absent(x[i]) \/ deopt(x[i]) | i in index_set(x)]); /** @group stdlib.builtins.logic Return truth value of \(\bigvee_i \a x[i]\) */ function bool: exists(array[$T] of bool: x) ::promise_commutative; /** @group stdlib.builtins.logic Return truth value of \(\bigvee_i \a x[i]\) */ function var bool: exists(array[$T] of var bool: x) ::promise_commutative; /** @group stdlib.builtins.logic True iff for at least one \p i, \a x[i] occurs and is true */ predicate exists (array[int] of var opt bool: x) = exists ([occurs(x[i]) /\ deopt(x[i]) | i in index_set(x)]); /** @group stdlib.builtins.logic Return truth value of \(\oplus_i \a x[i]\) */ function bool: xorall(array[$T] of bool: x) ::promise_commutative; /** @group stdlib.builtins.logic Return truth value of \(\oplus_i \a x[i]\) */ function bool: xorall(array[$T] of opt bool: x) ::promise_commutative = exists(y in array1d(x))(absent(y)) \/ xorall(y in array1d(x))(deopt(y)); /** @group stdlib.builtins.logic Return truth value of \(\oplus_i \a x[i]\) */ function var bool: xorall(array[$T] of var bool: x) ::promise_commutative = array_bool_xor(array1d(x)); /** @group stdlib.builtins.logic Return truth value of \(\oplus_i \a x[i]\) */ function var bool: xorall(array[$T] of var opt bool: x) ::promise_commutative = exists(y in array1d(x))(absent(y)) \/ xorall(y in array1d(x))(deopt(y)); /** @group stdlib.builtins.logic Return truth value of \(\text{true}\oplus (\oplus_i \a x[i])\) */ function bool: iffall(array[$T] of bool: x) ::promise_commutative; /** @group stdlib.builtins.logic Return truth value of \(\text{true}\oplus (\oplus_i \a x[i])\) */ function bool: iffall(array[$T] of opt bool: x) ::promise_commutative = exists(y in array1d(x))(absent(y)) \/ iffall(y in array1d(x))(deopt(y)); /** @group stdlib.builtins.logic Return truth value of \(\text{true}\oplus (\oplus_i \a x[i])\) */ function var bool: iffall(array[$T] of var bool: x) ::promise_commutative = array_bool_xor(array1d(x)++[true]); /** @group stdlib.builtins.logic Return truth value of \(\text{true}\oplus (\oplus_i \a x[i])\) */ function var bool: iffall(array[$T] of var opt bool: x) ::promise_commutative = exists(y in array1d(x))(absent(y)) \/ iffall(y in array1d(x))(deopt(y)); /** @group stdlib.builtins.logic Return truth value of \((\bigvee_i \a x[i]) \lor (\bigvee_j \lnot \a y[j])\) */ function bool: clause(array[$T] of bool: x, array[$T] of bool: y); /** @group stdlib.builtins.logic Return truth value of \((\bigvee_i \a x[i]) \lor (\bigvee_j \lnot \a y[j])\) */ function bool: clause(array[$T] of opt bool: x, array[$T] of opt bool: y) = exists(z in array1d(x))(absent(z)) \/ exists(z in array1d(y))(absent(z)) \/ clause([deopt(z) | z in array1d(x)], [deopt(z) | z in array1d(y)]); /** @group stdlib.builtins.logic Return truth value of \((\bigvee_i \a x[i]) \lor (\bigvee_j \lnot \a y[j])\) */ function var bool: clause(array[$T] of var bool: x, array[$T] of var bool: y); /** @group stdlib.builtins.logic Return truth value of \((\bigvee_i \a x[i]) \lor (\bigvee_j \lnot \a y[j])\) */ function var bool: clause(array[$T] of var opt bool: x, array[$T] of var opt bool: y) = exists(z in array1d(x))(absent(z)) \/ exists(z in array1d(y))(absent(z)) \/ clause([deopt(z) | z in array1d(x)], [deopt(z) | z in array1d(y)]); /** @group stdlib.builtins.logic Return negation of \a b */ function var bool: bool_not(var bool: b); libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_debug.mzn0000644000175000017500000001064114536677021022657 0ustar kaolkaol/*** @groupdef stdlib.debug Assertions and debugging functions These functions help debug models and check that input data conforms to the expectations. */ /** @group stdlib.debug If \a b is true, return \a x, otherwise abort with message \a msg. */ function any $T: assert(bool: b, string: msg, any $T: x); /** @group stdlib.debug If \a b is true, return \a x, otherwise abort with message \a msg. */ function array[$U] of any $T: assert(bool: b, string: msg, array[$U] of any $T: x); /** @group stdlib.debug If \a b is true, return true, otherwise abort with message \a msg. */ function bool: assert(bool: b, string: msg); /** @group stdlib.debug Return true, when the ``--debug`` flag is set, check if \a b is true, otherwise abort with message \a msg. */ function bool: assert_dbg(bool: b, string: msg); /** @group stdlib.debug Return \a x, and print message \a msg. */ function any $T: trace(string: msg, any $T: x); /** @group stdlib.debug Return \a x, and print message \a msg. */ function array [$U] of any $T: trace(string: msg, array [$U] of any $T: x); /** @group stdlib.debug Return \a x, and print a string representation of it. */ function any $T: trace_exp(any $T: x); /** @group stdlib.debug Return \a x, and print a string representation of it. */ function array[$U] of any $T: trace_exp(array[$U] of any $T: x); /** @group stdlib.debug Return true, and print message \a msg. */ function bool: trace(string: msg); /** @group stdlib.debug Return true, and when ``--debug`` flag is set print message \a msg. */ function bool: trace_dbg(string: msg); /** @group stdlib.debug Return \a x, and print message \a msg to section \a section. */ function any $T: trace_to_section(string: section, string: msg, any $T: x) = let { constraint mzn_trace_to_section(section, msg, false); } in x; /** @group stdlib.debug Return \a x, and print message \a msg to section \a section. */ function array [$U] of any $T: trace_to_section(string: section, string: msg, array [$U] of any $T: x) = let { constraint mzn_trace_to_section(section, msg, false); } in x; /** @group stdlib.debug Return true, and print message \a msg to section \a section. */ function bool: trace_to_section(string: section, string: msg) = mzn_trace_to_section(section, msg, false); /** @group stdlib.debug Return true, and print \a x to the JSON section \a section. */ function bool: trace_to_json_section(string: section, opt $T: x) = mzn_trace_to_section(section, showJSON(x) ++ "\n", true); /** @group stdlib.debug Return true, and print \a x to the JSON section \a section. */ function bool: trace_to_json_section(string: section, array [$U] of opt $T: x) = mzn_trace_to_section(section, showJSON(x) ++ "\n", true); function bool: mzn_trace_to_section(string: section, string: x, bool: json) :: mzn_internal_representation; /** @group stdlib.debug Return \a x, and print message \a msg. */ function any $T: trace_stdout(string: msg, any $T: x); /** @group stdlib.debug Return \a x, and print message \a msg. */ function array [$U] of any $T: trace_stdout(string: msg, array [$U] of any $T: x); /** @group stdlib.debug Return true, and print message \a msg. */ function bool: trace_stdout(string: msg); /** @group stdlib.debug Return \a x, and print message \a msg to logging stream. */ function any $T: trace_logstream(string: msg, any $T: x); /** @group stdlib.debug Return \a x, and print message \a msg to logging stream. */ function array [$U] of any $T: trace_logstream(string: msg, array [$U] of any $T: x); /** @group stdlib.debug Return true, and print message \a msg to logging stream. */ function bool: trace_logstream(string: msg); /** @group stdlib.debug Return logging stream as string */ function string: logstream_to_string(); /** @group stdlib.debug With debug build of the MiniZinc compiler, call MiniZinc::mzn_break_here when flattening this expression to make debugging easier. This annotation is ignored by the release build. */ annotation mzn_break_here; /** @group stdlib.debug Used to attach a ``expression_name`` annotation with name \a s to an expression when --debug is enabled. */ annotation expression_name_dbg(string: s) = expression_name(s); /** @group stdlib.debug Abort evaluation and print message \a msg. */ function bool: abort(string: msg); /** @group stdlib.debug Set to true iff ``--debug`` flag is set. */ bool: debug_mode = mzn_internal_check_debug_mode(); /** @group stdlib.debug Returns true iff ``--debug`` flag is set. */ test mzn_internal_check_debug_mode(); libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_ite.mzn0000644000175000017500000001536614536677021022363 0ustar kaolkaol/*** @groupdef stdlib.ifthenelse Conditionals These functions implement conditional (if-then-else-endif) constraints. */ /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of int: x, var int: y) = fzn_if_then_else_int(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of var int: x, var int: y) = fzn_if_then_else_var_int(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of opt int: x, var opt int: y) = fzn_if_then_else_opt_int(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of var opt int: x, var opt int: y) = fzn_if_then_else_var_opt_int(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of bool: x, var bool: y) = fzn_if_then_else_bool(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of var bool: x, var bool: y) = fzn_if_then_else_var_bool(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of opt bool: x, var opt bool: y) = fzn_if_then_else_opt_bool(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of var opt bool: x, var opt bool: y) = fzn_if_then_else_var_opt_bool(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of float: x, var float: y) = fzn_if_then_else_float(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of var float: x, var float: y) = fzn_if_then_else_var_float(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of opt float: x, var opt float: y) = fzn_if_then_else_opt_float(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of var opt float: x, var opt float: y) = fzn_if_then_else_var_opt_float(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of set of int: x, var set of int: y) = fzn_if_then_else_set(c, x, y); /** @group stdlib.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ \a y=\a x[i] \}\) This constraint is generated by the compiler for if-then-else expressions. The last entry in the \a c array is always the constant true, corresponding to the else case. */ predicate if_then_else(array[int] of var bool: c, array[int] of var set of int: x, var set of int: y) = fzn_if_then_else_var_set(c, x, y); /** @group stdlib.ifthenelse Conditional partiality constraint This constraint is generated by the compiler for if-then-else expressions with potentially undefined cases. The last entry in the \a c array is always the constant true, corresponding to the else case. The \a d[i] variable represents whether case \p i is defined. Constrains that if \b is defined, then the selected case must be defined, and if the selected case is undefined, then \a b must be undefined. */ predicate if_then_else_partiality(array[int] of var bool: c, array[int] of var bool: d, var bool: b) = fzn_if_then_else_partiality(c, d, b); libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_math.mzn0000644000175000017500000010536614536677021022533 0ustar kaolkaol/*** @groupdef stdlib.builtins.arithmetic Arithmetic Builtins These builtins implement arithmetic operations. */ /** @group stdlib.builtins.arithmetic Return \a x + \a y */ function int: '+'( int: x, int: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.arithmetic Return \a x + \a y */ function var int: '+'(var int: x, var int: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.arithmetic Return \a x + \a y */ function float: '+'( float: x, float: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.arithmetic Return \a x + \a y */ function var float: '+'(var float: x,var float: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.arithmetic Optional addition. Return sum of \a x and \a y, with absent replaced by 0. */ function var int: '+'(var opt int: x, var opt int: y) ::promise_total ::promise_commutative = if occurs(x) then deopt(x) else 0 endif + if occurs(y) then deopt(y) else 0 endif; /** @group stdlib.builtins.arithmetic Optional addition. Return sum of \a x and \a y, with absent replaced by 0. */ function int: '+'(opt int: x, opt int: y) ::promise_total ::promise_commutative = if occurs(x) then deopt(x) else 0 endif + if occurs(y) then deopt(y) else 0 endif; /** @group stdlib.builtins.arithmetic Optional addition. Return sum of \a x and \a y, with absent replaced by 0. */ function var float: '+'(var opt float: x, var opt float: y) ::promise_total ::promise_commutative = if occurs(x) then deopt(x) else 0 endif + if occurs(y) then deopt(y) else 0 endif; /** @group stdlib.builtins.arithmetic Optional addition. Return sum of \a x and \a y, with absent replaced by 0. */ function float: '+'(opt float: x, opt float: y) ::promise_total ::promise_commutative = if occurs(x) then deopt(x) else 0 endif + if occurs(y) then deopt(y) else 0 endif; /** @group stdlib.builtins.arithmetic Return \a x - \a y */ function int: '-'( int: x, int: y) ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Return \a x - \a y */ function var int: '-'(var int: x, var int: y) ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Return \a x - \a y */ function float: '-'( float: x, float: y) ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Return \a x - \a y */ function var float: '-'(var float: x,var float: y) ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Optional subtraction. Return absent if \a x is absent, \a x if \a y is absent, difference of \a x and \a y if both are present. */ function var opt int: '-'(var opt int: x, var opt int: y) ::promise_total = if absent(x) then <> elseif absent(y) then deopt(x) else deopt(x)-deopt(y) endif; function var int: '-'(var int: x, var opt int: y) ::promise_total = if absent(y) then x else x-deopt(y) endif; /** @group stdlib.builtins.arithmetic Optional subtraction. Return absent if \a x is absent, \a x if \a y is absent, difference of \a x and \a y if both are present. */ function var opt float: '-'(var opt float: x, var opt float: y) ::promise_total = if absent(x) then <> elseif absent(y) then deopt(x) else deopt(x)-deopt(y) endif; function var float: '-'(var float: x, var opt float: y) ::promise_total = if absent(y) then x else x-deopt(y) endif; /** @group stdlib.builtins.arithmetic Optional subtraction. Return absent if \a x is absent, \a x if \a y is absent, difference of \a x and \a y if both are present. */ function opt int: '-'(opt int: x, opt int: y) ::promise_total = if absent(x) then <> elseif absent(y) then deopt(x) else deopt(x)-deopt(y) endif; function int: '-'(int: x, opt int: y) ::promise_total = if absent(y) then x else x-deopt(y) endif; /** @group stdlib.builtins.arithmetic Optional subtraction. Return absent if \a x is absent, \a x if \a y is absent, difference of \a x and \a y if both are present. */ function opt float: '-'(opt float: x, opt float: y) ::promise_total = if absent(x) then <> elseif absent(y) then deopt(x) else deopt(x)-deopt(y) endif; function float: '-'(float: x, opt float: y) ::promise_total = if absent(y) then x else x-deopt(y) endif; /** @group stdlib.builtins.arithmetic Weak addition. Return sum of \a x and \a y if both are present, otherwise return absent. */ function var opt int: '~+'(var opt int: x, var opt int: y) ::promise_total ::promise_commutative = let { int: l = if lb(x)=-infinity \/ lb(y)=-infinity then -infinity else lb(x)+lb(y) endif; int: u = if ub(x)=infinity \/ ub(y)=infinity then infinity else ub(x)+ub(y) endif; var opt l..u: result; constraint absent(x) \/ absent(y) -> result = <>; constraint absent(x) \/ absent(y) \/ result = deopt(x)+deopt(y); } in result; /** @group stdlib.builtins.arithmetic Weak addition. Return sum of \a x and \a y if both are present, otherwise return absent. */ function opt int: '~+'(opt int: x, opt int: y) ::promise_total ::promise_commutative = if occurs(x) /\ occurs(y) then deopt(x) + deopt(y) else <> endif; /** @group stdlib.builtins.arithmetic Weak subtraction. Return difference of \a x and \a y if both are present, otherwise return absent. */ function var opt int: '~-'(var opt int: x, var opt int: y) ::promise_total = let { int: l = if lb(x)=-infinity \/ ub(y)=infinity then -infinity else lb(x)-ub(y) endif; int: u = if ub(x)=infinity \/ lb(y)=-infinity then infinity else ub(x)-lb(y) endif; var opt l..u: result; constraint absent(x) \/ absent(y) -> result = <>; constraint absent(x) \/ absent(y) \/ result = deopt(x)-deopt(y); } in result; /** @group stdlib.builtins.arithmetic Weak subtraction. Return difference of \a x and \a y if both are present, otherwise return absent. */ function opt int: '~-'(opt int: x, opt int: y) ::promise_total = if occurs(x) /\ occurs(y) then deopt(x) - deopt(y) else <> endif; /** @group stdlib.builtins.arithmetic Weak multiplication. Return product of \a x and \a y if both are present, otherwise return absent. */ function var opt int: '~*'(var opt int: x, var opt int: y) ::promise_total ::promise_commutative = if absent(x) \/ absent(y) then <> else deopt(x)*deopt(y) endif; /** @group stdlib.builtins.arithmetic Weak multiplication. Return product of \a x and \a y if both are present, otherwise return absent. */ function opt int: '~*'(opt int: x, opt int: y) ::promise_total ::promise_commutative = if occurs(x) /\ occurs(y) then deopt(x) * deopt(y) else <> endif; /** @group stdlib.builtins.arithmetic Weak addition. Return sum of \a x and \a y if both are present, otherwise return absent. */ function var opt float: '~+'(var opt float: x, var opt float: y) ::promise_total ::promise_commutative = let { float: l = if lb(x)=-infinity \/ lb(y)=-infinity then -infinity else lb(x)+lb(y) endif; float: u = if ub(x)=infinity \/ ub(y)=infinity then infinity else ub(x)+ub(y) endif; var opt l..u: result; constraint absent(x) \/ absent(y) -> result = <>; constraint absent(x) \/ absent(y) \/ result = deopt(x)+deopt(y); } in result; /** @group stdlib.builtins.arithmetic Weak subtraction. Return difference of \a x and \a y if both are present, otherwise return absent. */ function var opt float: '~-'(var opt float: x, var opt float: y) ::promise_total = let { float: l = if lb(x)=-infinity \/ ub(y)=infinity then -infinity else lb(x)-ub(y) endif; float: u = if ub(x)=infinity \/ lb(y)=-infinity then infinity else ub(x)-lb(y) endif; var opt l..u: result; constraint absent(x) \/ absent(y) -> result = <>; constraint absent(x) \/ absent(y) \/ result = deopt(x)-deopt(y); } in result; /** @group stdlib.builtins.arithmetic Weak multiplication. Return product of \a x and \a y if both are present, otherwise return absent. */ function var opt float: '~*'(var opt float: x, var opt float: y) ::promise_total ::promise_commutative = if absent(x) \/ absent(y) then <> else deopt(x)*deopt(y) endif; /** @group stdlib.builtins.arithmetic Return \a x * \a y */ function int: '*'( int: x, int: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.arithmetic Return \a x * \a y */ function var int: '*'(var int: x, var int: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.arithmetic Optional multiplication. Return product of \a x and \a y, with absent replaced by 1. */ function var int: '*'(var opt int: x, var opt int: y) ::promise_total ::promise_commutative = if occurs(x) then deopt(x) else 1 endif * if occurs(y) then deopt(y) else 1 endif; /** @group stdlib.builtins.arithmetic Optional multiplication. Return product of \a x and \a y, with absent replaced by 1. */ function int: '*'(opt int: x, opt int: y) ::promise_total ::promise_commutative = if occurs(x) then deopt(x) else 1 endif * if occurs(y) then deopt(y) else 1 endif; /** @group stdlib.builtins.arithmetic Optional multiplication. Return product of \a x and \a y, with absent replaced by 1. */ function var float: '*'(var opt float: x, var opt float: y) ::promise_total ::promise_commutative = if occurs(x) then deopt(x) else 1 endif * if occurs(y) then deopt(y) else 1 endif; /** @group stdlib.builtins.arithmetic Optional multiplication. Return product of \a x and \a y, with absent replaced by 1. */ function float: '*'(opt float: x, opt float: y) ::promise_total ::promise_commutative = if occurs(x) then deopt(x) else 1 endif * if occurs(y) then deopt(y) else 1 endif; /** @group stdlib.builtins.arithmetic Return \(\a x ^ {\a y}\) */ function int: '^'( int: x, int: y) ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Return \(\a x ^ {\a y}\) */ function var int: '^'(var int: x, var int: y) ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Return \a x * \a y */ function float: '*'( float: x, float: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.arithmetic Return \a x * \a y */ function var float: '*'(var float: x,var float: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.arithmetic Return \(\a x ^ {\a y}\) */ function float: '^'( float: x, float: y) ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Return \(\a x ^ {\a y}\) */ function var float: '^'(var float: x,var float: y) ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Return negative \a x */ function int: '-'( int: x) ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Return negative \a x */ function var int: '-'(var int: x) ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Return negative \a x */ function float: '-'( float: x) ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Return negative \a x */ function var float: '-'(var float: x) ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Return result of integer division \a x / \a y */ function int: 'div'(int: x,int: y); /** @group stdlib.builtins.arithmetic Return result of integer division \a x / \a y */ function var int: 'div'(var int: x,var int: y) = if mzn_in_root_context(y) then div_t(x,y) elseif not (0 in dom(y)) then div_t(x,y) else let { constraint y != 0 } in div_mt(x,y) endif; /** @group stdlib.builtins.arithmetic Optional division. Return absent if \a x is absent, \a x if \a y is absent, \a x divided by \a y if both are present. */ function var opt int: 'div'(var opt int: x, var opt int: y) = if absent(x) then <> elseif absent(y) then deopt(x) else deopt(x) div deopt(y) endif; function var int: 'div'(var int: x, var opt int: y) = if absent(y) then x else x div deopt(y) endif; /** @group stdlib.builtins.arithmetic Optional division. Return absent if \a x is absent, \a x if \a y is absent, \a x divided by \a y if both are present. */ function opt int: 'div'(opt int: x, opt int: y) = if absent(x) then <> elseif absent(y) then deopt(x) else deopt(x) div deopt(y) endif; function int: 'div'(int: x, opt int: y) = if absent(y) then x else x div deopt(y) endif; /** @group stdlib.builtins.arithmetic Weak optional division. Return absent if \a x or \a y is absent, \a x divided by \a y if both are present. */ function var opt int: '~div'(var opt int: x, var opt int: y) = if absent(x) \/ absent(y) then <> else deopt(x) div deopt(y) endif; /** @group stdlib.builtins.arithmetic Weak optional division. Return absent if \a x or \a y is absent, \a x divided by \a y if both are present. */ function opt int: '~div'(opt int: x, opt int: y) = if absent(x) \/ absent(y) then <> else deopt(x) div deopt(y) endif; /** @group stdlib.builtins.arithmetic Return remainder of integer division \a x % \a y */ function int: 'mod'(int: x,int: y); /** @group stdlib.builtins.arithmetic Return remainder of integer division \a x % \a y */ function var int: 'mod'(var int: x,var int: y) = if mzn_in_root_context(y) then mod_t(x,y) elseif not (0 in dom(y)) then mod_t(x,y) else let { constraint y != 0 } in mod_mt(x,y) endif; /** @group stdlib.builtins.arithmetic Optional modulo. Return absent if \a x or \a y is absent, \a x modulo \a y if both are present. */ function var opt int: 'mod'(var opt int: x, var opt int: y) = if occurs(x) /\ occurs(y) then deopt(x) mod deopt(y) else <> endif; /** @group stdlib.builtins.arithmetic Optional modulo. Return absent if \a x or \a y is absent, \a x modulo \a y if both are present. */ function opt int: 'mod'(opt int: x, opt int: y) = if occurs(x) /\ occurs(y) then deopt(x) mod deopt(y) else <> endif; /** @group stdlib.builtins.arithmetic Return result of floating point division \a x / \a y */ function float: '/'( float: x, float: y); /** @group stdlib.builtins.arithmetic Return result of floating point division \a x / \a y */ function var float: '/'(var float: x,var float: y) = if mzn_in_root_context(y) then fldiv_t(x,y) elseif lb(y) > 0.0 \/ ub(y) < 0.0 then fldiv_t(x,y) else let { constraint y != 0.0 } in fldiv_mt(x,y) endif; /** @group stdlib.builtins.arithmetic Optional division. Return absent if \a x is absent, \a x if \a y is absent, \a x divided by \a y if both are present. */ function var opt float: '/'(var opt float: x, var opt float: y) = if absent(x) then <> elseif absent(y) then deopt(x) else deopt(x) / deopt(y) endif; function var float: '/'(var float: x, var opt float: y) = if absent(y) then x else x / deopt(y) endif; /** @group stdlib.builtins.arithmetic Optional division. Return absent if \a x is absent, \a x if \a y is absent, \a x divided by \a y if both are present. */ function opt float: '/'(opt float: x, opt float: y) = if absent(x) then <> elseif absent(y) then deopt(x) else deopt(x) / deopt(y) endif; function float: '/'(float: x, opt float: y) = if absent(y) then x else x / deopt(y) endif; /** @group stdlib.builtins.arithmetic Weal optional division. Return absent if \a x or \a y is absent, \a x divided by \a y if both are present. */ function var opt float: '~/'(var opt float: x, var opt float: y) = if absent(x) \/ absent(y) then <> else deopt(x) / deopt(y) endif; /** @group stdlib.builtins.arithmetic Weal optional division. Return absent if \a x or \a y is absent, \a x divided by \a y if both are present. */ function opt float: '~/'(opt float: x, opt float: y) = if absent(x) \/ absent(y) then <> else deopt(x) / deopt(y) endif; /** @group stdlib.builtins.arithmetic Return number of true elments in array \a x */ function int: count(array[$T] of bool: x) ::promise_commutative = sum([bool2int(y) | y in array1d(x)]); /** @group stdlib.builtins.arithmetic Return number of true elments in array \a x */ function var int: count(array[$T] of var bool: x :: promise_ctx_monotone) ::promise_commutative = let { array[int] of var bool: xx :: promise_ctx_monotone = array1d(x); } in sum([bool2int(y) | y in xx]); /** @group stdlib.builtins.arithmetic Return number of true elments in array \a x */ function var int: count(array[$T] of var opt bool: x :: promise_ctx_monotone) ::promise_commutative = count(i in x)(i default false); /** @group stdlib.builtins.arithmetic Return sum of elements in array \a x */ function int: sum(array[$T] of int: x) ::promise_commutative; /** @group stdlib.builtins.arithmetic Return sum of elements in array \a x */ function var int: sum(array[$T] of var int: x) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.arithmetic Return sum of elements in array \a x */ function float: sum(array[$T] of float: x) ::promise_commutative; /** @group stdlib.builtins.arithmetic Return sum of elements in array \a x */ function var float: sum(array[$T] of var float: x) ::promise_commutative ::mzn_internal_representation; /** @group stdlib.builtins.arithmetic Return sum of non-absent elements of \a x. */ function var int: sum(array[int] of var opt int: x) ::promise_commutative = sum (i in index_set(x)) (x[i] default 0); /** @group stdlib.builtins.arithmetic Return sum of non-absent elements of \a x. */ function int: sum(array[int] of opt int: x) ::promise_commutative = sum (i in index_set(x)) (x[i] default 0); /** @group stdlib.builtins.arithmetic Return sum of non-absent elements of \a x. */ function var float: sum(array[int] of var opt float: x) ::promise_commutative = sum (i in index_set(x)) (x[i] default 0.0); /** @group stdlib.builtins.arithmetic Return sum of non-absent elements of \a x. */ function float: sum(array[int] of opt float: x) ::promise_commutative = sum (i in index_set(x)) (x[i] default 0.0); /** @group stdlib.builtins.arithmetic Return product of elements in array \a x */ function int: product(array[$T] of int: x) ::promise_commutative; /** @group stdlib.builtins.arithmetic Return product of elements in array \a x */ function var int: product(array[$T] of var int: x) ::promise_commutative = product_rec(array1d(x)); /** @group stdlib.builtins.arithmetic Return product of elements in array \a x */ function float: product(array[$T] of float: x) ::promise_commutative; /** @group stdlib.builtins.arithmetic Return product of elements in array \a x */ function var float: product(array[$T] of var float: x) ::promise_commutative = product_rec(array1d(x)); /** @group stdlib.builtins.arithmetic Return product of non-absent elements of \a x. */ function int: product(array[$T] of opt int: x) ::promise_commutative = product (xi in x) (xi default 1); /** @group stdlib.builtins.arithmetic Return product of non-absent elements of \a x. */ function var int: product(array[$T] of var opt int: x) ::promise_commutative = product (xi in x) (xi default 1); /** @group stdlib.builtins.arithmetic Return product of non-absent elements of \a x. */ function float: product(array[$T] of opt float: x) ::promise_commutative = product (xi in x) (xi default 1.0); /** @group stdlib.builtins.arithmetic Return product of non-absent elements of \a x. */ function var float: product(array[$T] of var opt float: x) ::promise_commutative = product (xi in x) (xi default 1.0); /** @group stdlib.builtins.arithmetic Return minimum of \a x and \a y */ function $T: min( $T: x, $T: y) ::promise_commutative; /** @group stdlib.builtins.arithmetic Return minimum of \a x and \a y */ function var int: min(var int: x, var int: y) :: promise_total :: promise_commutative = let { var min(lb(x),lb(y))..min(ub(x),ub(y)): m ::is_defined_var; constraint int_min(x,y,m) ::defines_var(m); } in m; /** @group stdlib.builtins.arithmetic Return minimum of \a x and \a y */ function var float: min(var float: x, var float: y) :: promise_total :: promise_commutative = if has_bounds(x) /\ has_bounds(y) then let { var min(lb(x),lb(y))..min(ub(x),ub(y)): m ::is_defined_var; constraint float_min(x,y,m) ::defines_var(m); } in m else let { var float: m ::is_defined_var; constraint float_min(x,y,m) ::defines_var(m); } in m endif; /** @group stdlib.builtins.arithmetic Return minimum of elements in array \a x */ function $T: min(array[$U] of par $T: x) :: promise_commutative; /** @group stdlib.builtins.arithmetic Return minimum of elements in array \a x */ function var int: min(array[$U] of var int: x) :: promise_commutative = let { array[int] of var int: xx = array1d(x); constraint length(x) >= 1; } in min_t(xx); /** @group stdlib.builtins.arithmetic Return minimum of elements in array \a x */ function var float: min(array[$U] of var float: x) :: promise_commutative = let { array[int] of var float: xx = array1d(x); constraint length(x) >= 1; } in min_t(xx); /** @group stdlib.builtins.arithmetic Return minimum of elements in \a x that are not absent. Result is undefined when all values are absent. */ function var int: min(array[$X] of var opt int: x) :: promise_commutative = let { int: xub = max(0, ub_array(x)); constraint exists (xi in x) (occurs(xi)); } in min (xi in x) (xi default xub); /** @group stdlib.builtins.arithmetic Return minimum of elements in \a x that are not absent. Result is absent when all values are absent. */ function var opt int: min_weak(array[$X] of var opt int: x) ::promise_commutative = let { int: xub = max(0, ub_array(x)); } in if exists (xi in x) (occurs(xi)) then min (xi in x) (xi default xub) else <> endif; /** @group stdlib.builtins.arithmetic Return minimum of elements in \a x that are not absent. Result is undefined when all values are absent. */ function var float: min(array[$X] of var opt float: x) ::promise_commutative = let { float: xub = max(0.0, ub_array(x)); constraint exists (xi in x) (occurs(xi)); } in min (xi in x) (xi default xub); /** @group stdlib.builtins.arithmetic Return minimum of elements in \a x that are not absent. Result is absent when all values are absent. */ function var opt float: min_weak(array[$X] of var opt float: x) :: promise_commutative = let { float: xub = max(0.0, ub_array(x)); } in if exists (xi in x) (occurs(xi)) then min (xi in x) (xi default xub) else <> endif; /** @group stdlib.builtins.arithmetic Return minimum of elements in set \a x */ function $$E: min(set of $$E: x); /** @group stdlib.builtins.arithmetic Return maximum of \a x and \a y */ function $T: max( $T: x, $T: y) :: promise_commutative; /** @group stdlib.builtins.arithmetic Return maximum of \a x and \a y */ function var int: max(var int: x, var int: y) :: promise_total :: promise_commutative = let { var max(lb(x),lb(y))..max(ub(x),ub(y)): m ::is_defined_var; constraint int_max(x,y,m) ::defines_var(m); } in m; /** @group stdlib.builtins.arithmetic Return maximum of \a x and \a y */ function var float: max(var float: x, var float: y) :: promise_total :: promise_commutative = if has_bounds(x) /\ has_bounds(y) then let { var max(lb(x),lb(y))..max(ub(x),ub(y)): m ::is_defined_var; constraint float_max(x,y,m) ::defines_var(m); } in m else let { var float: m ::is_defined_var; constraint float_max(x,y,m) ::defines_var(m); } in m endif; /** @group stdlib.builtins.arithmetic Return maximum of elements in array \a x */ function $T: max(array[$U] of $T: x) :: promise_commutative; /** @group stdlib.builtins.arithmetic Return maximum of elements in array \a x */ function var int: max(array[$U] of var int: x) :: promise_commutative = let { array[int] of var int: xx = array1d(x); constraint length(x) >= 1; } in max_t(xx); /** @group stdlib.builtins.arithmetic Return maximum of elements in array \a x */ function var float: max(array[$U] of var float: x) :: promise_commutative = let { array[int] of var float: xx = array1d(x); constraint length(x) >= 1; } in max_t(xx); /** @group stdlib.builtins.arithmetic Return maximum of elements in \a x that are not absent. Result is undefined when all values are absent. */ function var int: max(array[$X] of var opt int: x) :: promise_commutative = let { int: xlb = min(0, lb_array(x)); constraint exists (xi in x) (occurs(xi)); } in max (xi in x) (xi default xlb); /** @group stdlib.builtins.arithmetic Return maximum of elements in \a x that are not absent. Result is absent when all values are absent. */ function var opt int: max_weak(array[$X] of var opt int: x) :: promise_commutative = let { int: xlb = min(0, lb_array(x)); } in if exists (xi in x) (occurs(xi)) then max (xi in x) (xi default xlb) else <> endif; /** @group stdlib.builtins.arithmetic Return maximum of elements in \a x that are not absent. Result is undefined when all values are absent. */ function var float: max(array[$X] of var opt float: x) :: promise_commutative = let { float: xlb = min(0.0, lb_array(x)); constraint exists (xi in x) (occurs(xi)); } in max (xi in x) (xi default xlb); /** @group stdlib.builtins.arithmetic Return maximum of elements in \a x that are not absent. Result is absent when all values are absent. */ function var opt float: max_weak(array[$X] of var opt float: x) :: promise_commutative = let { float: xlb = min(0.0, lb_array(x)); } in if exists (xi in x) (occurs(xi)) then max (xi in x) (xi default xlb) else <> endif; /** @group stdlib.builtins.arithmetic Return maximum of elements in set \a x */ function $$E: max(set of $$E: x); % Floating point min and max % TODO: add bounds reasoning /** @group stdlib.builtins.arithmetic Returns the index of the minimum value in the array \a x. When breaking ties the least index is returned. */ function $$E: arg_min(array[$$E] of bool: x); /** @group stdlib.builtins.arithmetic Returns the index of the minimum value in the array \a x. When breaking ties the least index is returned. */ function $$E: arg_min(array[$$E] of int: x); /** @group stdlib.builtins.arithmetic Returns the index of the minimum value in the array \a x. When breaking ties the least index is returned. */ function $$E: arg_min(array[$$E] of float: x); /** @group stdlib.builtins.arithmetic Returns the index of the maximum value in the array \a x. When breaking ties the least index is returned. */ function $$E: arg_max(array[$$E] of bool: x); /** @group stdlib.builtins.arithmetic Returns the index of the maximum value in the array \a x. When breaking ties the least index is returned. */ function $$E: arg_max(array[$$E] of int: x); /** @group stdlib.builtins.arithmetic Returns the index of the maximum value in the array \a x. When breaking ties the least index is returned. */ function $$E: arg_max(array[$$E] of float: x); /** @group stdlib.builtins.arithmetic Return absolute value of \a x */ function int: abs(int: x); /** @group stdlib.builtins.arithmetic Return absolute value of \a x */ function var int: abs(var int: x) :: promise_total = if has_bounds(x) /\ lb(x) >= 0 then x elseif has_bounds(x) /\ ub(x) <= 0 then -x else let { var 0..max(-lb(x),ub(x)): m ::is_defined_var; constraint int_abs(x,m) ::defines_var(m); } in m endif; /** @group stdlib.builtins.arithmetic Return absolute value of \a x */ function float: abs(float: x); /** @group stdlib.builtins.arithmetic Return absolute value of \a x */ function var float: abs(var float: x) :: promise_total = if has_bounds(x) then if lb(x) >= 0.0 then x elseif ub(x) <= 0.0 then -x else let { var 0.0..max(-lb(x),ub(x)): m ::is_defined_var; constraint float_abs(x,m) ::defines_var(m); } in m endif else let { var float: m ::is_defined_var; constraint m >= 0.0; constraint float_abs(x,m) ::defines_var(m); } in m endif; /** @group stdlib.builtins.arithmetic Return \(\sqrt{\a x}\) */ function float: sqrt(float: x); /** @group stdlib.builtins.arithmetic Return \(\sqrt{\a x}\) */ function var float: sqrt(var float: x) = if mzn_in_root_context(x) then sqrt_t(x) elseif lb(x) >= 0.0 then sqrt_t(x) else let { constraint x >= 0.0; } in sqrt_mt(x) endif; /** @group stdlib.builtins.arithmetic Return \(\a x ^ {\a y}\), when \(\a y < 0 \) it returns ``1 div pow(x, abs(y))``. */ function int: pow(int: x, int: y); /** @group stdlib.builtins.arithmetic Return \(\a x ^ {\a y}\), when \(\a y < 0 \) it returns ``1 div pow(x, abs(y))``. */ function var int: pow(var int: x, int: y) = if y = 0 then 1 elseif y = 1 then x elseif dom(x) = 0..1 /\ y >= 0 then x elseif dom(x) = -1..1 /\ y mod 2 = 1 then x elseif not (0 in dom(x) \/ -1 in dom(x)) /\ y < 0 then bool2int(x = 1) elseif y >= 0 \/ not (0 in dom(x)) then pow_fixed_t(x, y) elseif mzn_in_root_context(x) then pow_fixed_t(x, y) else let { constraint x != 0; } in pow_fixed_mt(x, y) endif; /** @group stdlib.builtins.arithmetic Return \(\a x ^ {\a y}\), when \(\a y < 0 \) it returns ``1 div pow(x, abs(y))``. */ function var int: pow(var int: x, var int: y) = if lb(y) > 0 /\ dom(x) = 0..1 then x elseif lb(y) >= 0 then pow_t(x, y) elseif not (0 in dom(x)) then if ub(y) < 0 /\ not (-1 in dom(x)) then bool2int(x = 1) else pow_t(x, y) endif elseif mzn_in_root_context(x) then pow_t(x, y) else let { constraint y < 0 -> x != 0; } in pow_mt(x, y) endif; /** @group stdlib.builtins.arithmetic Return \(\a x ^ {\a y}\) */ function float: pow(float: x, float: y); /** @group stdlib.builtins.arithmetic Return \(\a x ^ {\a y}\) */ function var float: pow(var float: x, var float: y) ::promise_total = let { float: yy = if is_fixed(y) then fix(y) else -1.0 endif } in if yy = 0.0 then 1.0 elseif yy = 1.0 then x else let { var float: r ::is_defined_var; constraint float_pow(x,y,r) ::defines_var(r); } in r endif; /*** @groupdef stdlib.builtins.explog Exponential and logarithmic builtins These builtins implement exponential and logarithmic functions. */ /** @group stdlib.builtins.explog Return \(e ^ {\a x}\) */ function float: exp(float: x); /** @group stdlib.builtins.explog Return \(e ^ {\a x}\) */ function var float: exp(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_exp(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.explog Return \(\ln \a x\) */ function float: ln(float: x); /** @group stdlib.builtins.explog Return \(\ln \a x\) */ function var float: ln(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_ln(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.explog Return \(\log_{10} \a x\) */ function float: log10(float: x); /** @group stdlib.builtins.explog Return \(\log_{10} \a x\) */ function var float: log10(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_log10(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.explog Return \(\log_{2} \a x\) */ function float: log2(float: x); /** @group stdlib.builtins.explog Return \(\log_{2} \a x\) */ function var float: log2(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_log2(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.explog Return \(\log_{\a x} \a y\) */ function float: log(float: x, float: y); /*** @groupdef stdlib.builtins.trigonometric Trigonometric functions These builtins implement the standard trigonometric functions. */ /** @group stdlib.builtins.trigonometric Return \(\sin \a x\) */ function float: sin(float: x); /** @group stdlib.builtins.trigonometric Return \(\sin \a x\) */ function var float: sin(var float: x) ::promise_total = let { var -1.0..1.0: r ::is_defined_var; constraint float_sin(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.trigonometric Return \(\cos \a x\) */ function float: cos(float: x); /** @group stdlib.builtins.trigonometric Return \(\cos \a x\) */ function var float: cos(var float: x) ::promise_total = let { var -1.0..1.0: r ::is_defined_var; constraint float_cos(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.trigonometric Return \(\tan \a x\) */ function float: tan(float: x); /** @group stdlib.builtins.trigonometric Return \(\tan \a x\) */ function var float: tan(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_tan(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.trigonometric Return \(\mbox{asin}\ \a x\) */ function float: asin(float: x); /** @group stdlib.builtins.trigonometric Return \(\mbox{asin}\ \a x\) */ function var float: asin(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_asin(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.trigonometric Return \(\mbox{acos}\ \a x\) */ function float: acos(float: x); /** @group stdlib.builtins.trigonometric Return \(\mbox{acos}\ \a x\) */ function var float: acos(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_acos(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.trigonometric Return \(\mbox{atan}\ \a x\) */ function float: atan(float: x); /** @group stdlib.builtins.trigonometric Return \(\mbox{atan}\ \a x\) */ function var float: atan(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_atan(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.trigonometric Return \(\sinh \a x\) */ function float: sinh(float: x); /** @group stdlib.builtins.trigonometric Return \(\sinh \a x\) */ function var float: sinh(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_sinh(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.trigonometric Return \(\cosh \a x\) */ function float: cosh(float: x); /** @group stdlib.builtins.trigonometric Return \(\cosh \a x\) */ function var float: cosh(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_cosh(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.trigonometric Return \(\tanh \a x\) */ function float: tanh(float: x); /** @group stdlib.builtins.trigonometric Return \(\tanh \a x\) */ function var float: tanh(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_tanh(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.trigonometric Return \(\mbox{asinh}\ \a x\) */ function float: asinh(float: x); /** @group stdlib.builtins.trigonometric Return \(\mbox{asinh}\ \a x\) */ function var float: asinh(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_asinh(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.trigonometric Return \(\mbox{acosh}\ \a x\) */ function float: acosh(float: x); /** @group stdlib.builtins.trigonometric Return \(\mbox{acosh}\ \a x\) */ function var float: acosh(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_acosh(x,r) ::defines_var(r); } in r; /** @group stdlib.builtins.trigonometric Return \(\mbox{atanh}\ \a x\) */ function float: atanh(float: x); /** @group stdlib.builtins.trigonometric Return \(\mbox{atanh}\ \a x\) */ function var float: atanh(var float: x) ::promise_total = let { var float: r ::is_defined_var; constraint float_atanh(x,r) ::defines_var(r); } in r; libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_reflect.mzn0000644000175000017500000001431014536677021023212 0ustar kaolkaol/*** @groupdef stdlib.reflect Reflection operations These functions return information about declared or inferred variable bounds and domains. */ /** @group stdlib.reflect Return lower bound of \a x */ function $$E: lb(var $$E: x); /** @group stdlib.reflect Return upper bound of \a x */ function $$E: ub(var $$E: x); /** @group stdlib.reflect Return lower bound of \a x */ function $$E: lb(var opt $$E: x); /** @group stdlib.reflect Return upper bound of \a x */ function $$E: ub(var opt $$E: x); /** @group stdlib.reflect Return lower bound of \a x */ function float: lb(var float: x); /** @group stdlib.reflect Return upper bound of \a x */ function float: ub(var float: x); /** @group stdlib.reflect Return lower bound of \a x */ function float: lb(var opt float: x); /** @group stdlib.reflect Return upper bound of \a x */ function float: ub(var opt float: x); /** @group stdlib.reflect Return lower bound of \a x */ function set of $$E: lb(var set of $$E: x); /** @group stdlib.reflect Return upper bound of \a x */ function set of $$E: ub(var set of $$E: x); /** @group stdlib.reflect Return array of lower bounds of the elements in array \a x */ function array[$U] of $$E: lb(array[$U] of var $$E: x) = arrayXd(x,[lb(xx) | xx in array1d(x)]); /** @group stdlib.reflect Return array of upper bounds of the elements in array \a x */ function array[$U] of $$E: ub(array[$U] of var $$E: x) = arrayXd(x,[ub(xx) | xx in array1d(x)]); /** @group stdlib.reflect Return array of lower bounds of the elements in array \a x */ function array[$U] of float: lb(array[$U] of var float: x) = arrayXd(x,[lb(xx) | xx in array1d(x)]); /** @group stdlib.reflect Return array of upper bounds of the elements in array \a x */ function array[$U] of float: ub(array[$U] of var float: x) = arrayXd(x,[ub(xx) | xx in array1d(x)]); /** @group stdlib.reflect Return array of lower bounds of the elements in array \a x */ function array[$U] of set of $$E: lb(array[$U] of var set of $$E: x) = arrayXd(x,[lb(xx) | xx in array1d(x)]); /** @group stdlib.reflect Return array of upper bounds of the elements in array \a x */ function array[$U] of set of $$E: ub(array[$U] of var set of $$E: x) = arrayXd(x,[ub(xx) | xx in array1d(x)]); /** @group stdlib.reflect Return minimum of all lower bounds of the elements in array \a x */ function $$E: lb_array(array[$U] of var opt $$E: x); /** @group stdlib.reflect Return maximum of all upper bounds of the elements in array \a x */ function $$E: ub_array(array[$U] of var opt $$E: x); /** @group stdlib.reflect Return minimum of all lower bounds of the elements in array \a x */ function float: lb_array(array[$U] of var opt float: x); /** @group stdlib.reflect Return maximum of all upper bounds of the elements in array \a x */ function float: ub_array(array[$U] of var opt float: x); /** @group stdlib.reflect Return intersection of all lower bounds of the elements in array \a x */ function set of $$E: lb_array(array[$U] of var set of $$E: x); /** @group stdlib.reflect Return union of all upper bounds of the elements in array \a x */ function set of $$E: ub_array(array[$U] of var set of $$E: x); /** @group stdlib.reflect Return domain of \a x */ function set of $$E: dom(var $$E: x); /** @group stdlib.reflect Return domain of \a x */ function set of $$E: dom(var opt $$E: x); function set of int: dom(var bool: b) = if is_fixed(b) then if fix(b) then {1} else {0} endif else {0,1} endif; /** @group stdlib.reflect Return union of all domains of the elements in array \a x */ function set of $$E: dom_array(array[$T] of var $$E: x); /** @group stdlib.reflect Return union of all domains of the elements in array \a x */ function set of $$E: dom_array(array[$T] of var opt $$E: x); /** @group stdlib.reflect Return union of all domains of the elements in array \a x, ignoring absent elements */ function set of int: dom_array_occurring(array[$T] of var opt int: x) = array_union([if is_fixed(xi) /\ absent(fix(xi)) then {} else dom(xi) endif | xi in array1d(x)]); /** @group stdlib.reflect Return approximation of union of all domains of the elements in array \a x */ function set of int: dom_bounds_array(array[$T] of var int: x); /** @group stdlib.reflect Return approximation of union of all domains of the elements in array \a x */ function set of int: dom_bounds_array(array[$T] of var opt int: x); /** @group stdlib.reflect Return cardinality of the domain of \a x */ function int: dom_size(var int: x) = card(dom(x)); /** @group stdlib.reflect Test if variable \a x has declared, finite bounds */ function par bool: has_bounds(var int: x); /** @group stdlib.reflect Test if variable \a x has declared, finite bounds */ function par bool: has_bounds(var float: x); /** @group stdlib.reflect Test if variable \a x has a declared, finite upper bound */ function par bool: has_ub_set(var set of int: x); /** @group stdlib.reflect Check if the value of \a x is fixed at this point in evaluation. If it is fixed, return its value, otherwise abort. */ function $T: fix(var $T: x); /** @group stdlib.reflect Check if the value of \a x is fixed at this point in evaluation. If it is fixed, return its value, otherwise abort. */ function opt $T: fix(var opt $T: x); function $T: fix($T: x) = x; function opt $T: fix(opt $T: x) = x; /** @group stdlib.reflect Check if the value of every element of the array \a x is fixed at this point in evaluation. If all are fixed, return an array of their values, otherwise abort. */ function array[$U] of $T: fix(array[$U] of var $T: x); /** @group stdlib.reflect Check if the value of every element of the array \a x is fixed at this point in evaluation. If all are fixed, return an array of their values, otherwise abort. */ function array[$U] of opt $T: fix(array[$U] of var opt $T: x); /** @group stdlib.reflect Test if \a x is fixed */ function bool: is_fixed(any $T: x); /** @group stdlib.reflect Test if every element of array \a x is fixed */ function bool: is_fixed(array[$U] of any $T: x); /** @group stdlib.reflect Test if \a x is annotated \a a */ function bool: has_ann(any $T: x, ann: a); /** @group stdlib.reflect Annotate declaration of \a x with annotation \a a */ function bool: annotate(any $T: x, ann: a); /** @group stdlib.reflect Test if \a x and \a y are the same variable */ function bool: is_same(any $T: x, any $U: y); libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_array.mzn0000644000175000017500000004036114536677021022711 0ustar kaolkaol/*** @groupdef stdlib.builtins.array Array operations These functions implement the basic operations on arrays. */ /** @group stdlib.builtins.array Return the concatenation of arrays \a x and \a y */ function array[int] of any $T: '++'(array[int] of any $T: x, array[int] of any $T: y) ::mzn_internal_representation; /** @group stdlib.builtins.array Return the length of array \a x Note that the length is defined as the number of elements in the array, regardless of its dimensionality. */ function int: length(array[$T] of any $U: x); /** @group stdlib.builtins.array Return the array \a x in reverse order The resulting array has the same index set as \a x. */ function array[$$E] of $T: reverse(array[$$E] of $T: x) = if length(x)=0 then [] else let { int: l = max(index_set(x))+min(index_set(x)) } in array1d(index_set(x),[x[l-i] | i in index_set(x)]) endif; /** @group stdlib.builtins.array Return the array \a x in reverse order The resulting array has the same index set as \a x. */ function array[$$E] of opt $T: reverse(array[$$E] of opt $T: x) = if length(x)=0 then [] else let { int: l = max(index_set(x))+min(index_set(x)) } in array1d(index_set(x),[x[l-i] | i in index_set(x)]) endif; /** @group stdlib.builtins.array Return the array \a x in reverse order The resulting array has the same index set as \a x. */ function array[$$E] of any $T: reverse(array[$$E] of any $T: x) = if length(x)=0 then [] else let { int: l = max(index_set(x))+min(index_set(x)) } in array1d(index_set(x),[x[l-i] | i in index_set(x)]) endif; /** @group stdlib.builtins.array Test if \a x and \a y have the same index sets */ test index_sets_agree(array[$T] of any $U: x, array[$T] of any $W: y); /** @group stdlib.builtins.array Return index set of one-dimensional array \a x */ function set of $$E: index_set(array[$$E] of any $U: x); /** @group stdlib.builtins.array Return index set of first dimension of two-dimensional array \a x */ function set of $$E: index_set_1of2(array[$$E,int] of any $U: x); /** @group stdlib.builtins.array Return index set of second dimension of two-dimensional array \a x */ function set of $$E: index_set_2of2(array[int,$$E] of any $U: x); /** @group stdlib.builtins.array Return index set of first dimension of 3-dimensional array \a x */ function set of $$E: index_set_1of3(array[$$E,int,int] of any $U: x); /** @group stdlib.builtins.array Return index set of second dimension of 3-dimensional array \a x */ function set of $$E: index_set_2of3(array[int,$$E,int] of any $U: x); /** @group stdlib.builtins.array Return index set of third dimension of 3-dimensional array \a x */ function set of $$E: index_set_3of3(array[int,int,$$E] of any $U: x); /** @group stdlib.builtins.array Return index set of first dimension of 4-dimensional array \a x */ function set of $$E: index_set_1of4(array[$$E,int,int,int] of any $U: x); /** @group stdlib.builtins.array Return index set of second dimension of 4-dimensional array \a x */ function set of $$E: index_set_2of4(array[int,$$E,int,int] of any $U: x); /** @group stdlib.builtins.array Return index set of third dimension of 4-dimensional array \a x */ function set of $$E: index_set_3of4(array[int,int,$$E,int] of any $U: x); /** @group stdlib.builtins.array Return index set of fourth dimension of 4-dimensional array \a x */ function set of $$E: index_set_4of4(array[int,int,int,$$E] of any $U: x); /** @group stdlib.builtins.array Return index set of first dimension of 5-dimensional array \a x */ function set of $$E: index_set_1of5(array[$$E,int,int,int,int] of any $U: x); /** @group stdlib.builtins.array Return index set of second dimension of 5-dimensional array \a x */ function set of $$E: index_set_2of5(array[int,$$E,int,int,int] of any $U: x); /** @group stdlib.builtins.array Return index set of third dimension of 5-dimensional array \a x */ function set of $$E: index_set_3of5(array[int,int,$$E,int,int] of any $U: x); /** @group stdlib.builtins.array Return index set of fourth dimension of 5-dimensional array \a x */ function set of $$E: index_set_4of5(array[int,int,int,$$E,int] of any $U: x); /** @group stdlib.builtins.array Return index set of fifth dimension of 5-dimensional array \a x */ function set of $$E: index_set_5of5(array[int,int,int,int,$$E] of any $U: x); /** @group stdlib.builtins.array Return index set of first dimension of 6-dimensional array \a x */ function set of $$E: index_set_1of6(array[$$E,int,int,int,int,int] of any $U: x); /** @group stdlib.builtins.array Return index set of second dimension of 6-dimensional array \a x */ function set of $$E: index_set_2of6(array[int,$$E,int,int,int,int] of any $U: x); /** @group stdlib.builtins.array Return index set of third dimension of 6-dimensional array \a x */ function set of $$E: index_set_3of6(array[int,int,$$E,int,int,int] of any $U: x); /** @group stdlib.builtins.array Return index set of fourth dimension of 6-dimensional array \a x */ function set of $$E: index_set_4of6(array[int,int,int,$$E,int,int] of any $U: x); /** @group stdlib.builtins.array Return index set of fifth dimension of 6-dimensional array \a x */ function set of $$E: index_set_5of6(array[int,int,int,int,$$E,int] of any $U: x); /** @group stdlib.builtins.array Return index set of sixth dimension of 6-dimensional array \a x */ function set of $$E: index_set_6of6(array[int,int,int,int,int,$$E] of any $U: x); /** @group stdlib.builtins.array Return array \a x coerced to index set 1..length(\a x). Coercions are performed by considering the array \a x in row-major order. */ function array[int] of any $V: array1d(array[$U] of any $V: x); /** @group stdlib.builtins.array Return array \a x coerced to one-dimensional array with index set \a S. Coercions are performed by considering the array \a x in row-major order. */ function array[$$E] of any $V: array1d(set of $$E: S, array[$U] of any $V: x); /** @group stdlib.builtins.array Return array \a x coerced to two-dimensional array with index sets \a S1 and \a S2. Coercions are performed by considering the array \a x in row-major order. */ function array[$$E,$$F] of any $V: array2d(set of $$E: S1, set of $$F: S2, array[$U] of any $V: x); function array[$$E,$$F] of any $V: array2d(array[int] of $$E: S1, array[int] of $$F: S2, array[int] of any $V: x) = let { int: d = length(S2); } in [ (S1[(i - 1) div d + 1],S2[(i - 1) mod d + 1]) : x[i] | i in index_set(x)]; function array[$$E] of any $V: arrayNd(array[int] of $$E: S1, array[int] of any $V: x) = if length(S1)=1 /\ length(x)>1 then array1d(S1[1]..to_enum(enum_of(S1[1]),S1[1]+length(x)-1), x) else [ S1[i] : x[i] | i in index_set(x)] endif; function array[$$E,$$F] of any $V: arrayNd(array[int] of $$E: S1, array[int] of $$F: S2, array[int] of any $V: x) = [ (S1[i], S2[i]) : x[i] | i in index_set(x)]; function array[$$E,$$F,$$G] of any $V: arrayNd(array[int] of $$E: S1, array[int] of $$F: S2, array[int] of $$G: S3, array[int] of any $V: x) = [ (S1[i], S2[i], S3[i]) : x[i] | i in index_set(x)]; function array[$$E,$$F,$$G,$$H] of any $V: arrayNd(array[int] of $$E: S1, array[int] of $$F: S2, array[int] of $$G: S3, array[int] of $$H: S4, array[int] of any $V: x) = [ (S1[i], S2[i], S3[i], S4[i]) : x[i] | i in index_set(x)]; function array[$$E,$$F,$$G,$$H,$$I] of any $V: arrayNd(array[int] of $$E: S1, array[int] of $$F: S2, array[int] of $$G: S3, array[int] of $$H: S4, array[int] of $$I: S5, array[int] of any $V: x) = [ (S1[i], S2[i], S3[i], S4[i], S5[i]) : x[i] | i in index_set(x)]; function array[$$E,$$F,$$G,$$H,$$I,$$J] of any $V: arrayNd(array[int] of $$E: S1, array[int] of $$F: S2, array[int] of $$G: S3, array[int] of $$H: S4, array[int] of $$I: S5, array[int] of $$J: S6, array[int] of any $V: x) = [ (S1[i], S2[i], S3[i], S4[i], S5[i], S6[i]) : x[i] | i in index_set(x)]; /** @group stdlib.builtins.array Return array \a x coerced to three-dimensional array with index sets \a S1, \a S2 and \a S3. Coercions are performed by considering the array \a x in row-major order. */ function array[$$E,$$F,$$G] of any $V: array3d(set of $$E: S1, set of $$F: S2, set of $$G: S3, array[$U] of any $V: x); /** @group stdlib.builtins.array Return array \a x coerced to 4-dimensional array with index sets \a S1, \a S2, \a S3 and \a S4. Coercions are performed by considering the array \a x in row-major order. */ function array[$$E,$$F,$$G,$$H] of any $V: array4d(set of $$E: S1, set of $$F: S2, set of $$G: S3, set of $$H: S4, array[$U] of any $V: x); /** @group stdlib.builtins.array Return array \a x coerced to 5-dimensional array with index sets \a S1, \a S2, \a S3, \a S4 and \a S5. Coercions are performed by considering the array \a x in row-major order. */ function array[$$E,$$F,$$G,$$H,$$I] of any $V: array5d(set of $$E: S1, set of $$F: S2, set of $$G: S3, set of $$H: S4, set of $$I: S5, array[$U] of any $V: x); /** @group stdlib.builtins.array Return array \a x coerced to 6-dimensional array with index sets \a S1, \a S2, \a S3, \a S4, \a S5 and \a S6. Coercions are performed by considering the array \a x in row-major order. */ function array[$$E,$$F,$$G,$$H,$$I,$$J] of any $V: array6d(set of $$E: S1, set of $$F: S2, set of $$G: S3, set of $$H: S4, set of $$I: S5, set of $$J: S6, array[$U] of any $V: x); /** @group stdlib.builtins.array Forces a arrayNd call to throw an error if the new index sets are offsets of the current index sets. */ annotation array_check_form; /** @group stdlib.builtins.array Return array \a y coerced to array with same number of dimensions and same index sets as array \a x. Coercions are performed by considering the array \a y in row-major order. */ function array[$T] of any $V: arrayXd(array[$T] of any $X: x, array[$U] of any $V: y); /** @group stdlib.builtins.array Return row \a r of array \a x */ function array[$$E] of any $T: row(array[int, $$E] of any $T: x, int: r) = x[r,..]; /** @group stdlib.builtins.array Return column \a c of array \a x */ function array[$$E] of any $T: col(array[$$E,int] of any $T: x, int: c) = x[..,c]; /** @group stdlib.builtins.array Return slice of array \a x specified by sets \a s, coerced to new 1d array with index set \a dims1 */ function array[$$F] of any $T: slice_1d(array[$E] of any $T: x, array[int] of set of int: s, set of $$F: dims1); /** @group stdlib.builtins.array Return slice of array \a x specified by sets \a s, coerced to new 2d array with index sets \a dims1 and \a dims2 */ function array[$$F,$$G] of any $T: slice_2d(array[$E] of any $T: x, array[int] of set of int: s, set of $$F: dims1, set of $$G: dims2); /** @group stdlib.builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2 and \a dims3 */ function array[$$F,$$G,$$H] of any $T: slice_3d(array[$E] of any $T: x, array[int] of set of int: s, set of $$F: dims1, set of $$G: dims2, set of $$H: dims3); /** @group stdlib.builtins.array Return slice of array \a x specified by sets \a s, coerced to new 4d array with index sets \a dims1, \a dims2, \a dims3, \a dims4 */ function array[$$F,$$G,$$H,$$I] of any $T: slice_4d(array[$E] of any $T: x, array[int] of set of int: s, set of $$F: dims1, set of $$G: dims2, set of $$H: dims3, set of $$I: dims4); /** @group stdlib.builtins.array Return slice of array \a x specified by sets \a s, coerced to new 5d array with index sets \a dims1, \a dims2, \a dims3, \a dims4, \a dims5 */ function array[$$F,$$G,$$H,$$I,$$J] of any $T: slice_5d(array[$E] of any $T: x, array[int] of set of int: s, set of $$F: dims1, set of $$G: dims2, set of $$H: dims3, set of $$I: dims4, set of $$J: dims5); /** @group stdlib.builtins.array Return slice of array \a x specified by sets \a s, coerced to new 6d array with index sets \a dims1, \a dims2, \a dims3, \a dims4, \a dims5, \a dims6 */ function array[$$F,$$G,$$H,$$I,$$J,$$K] of any $T: slice_6d(array[$E] of any $T: x, array[int] of set of int: s, set of $$F: dims1, set of $$G: dims2, set of $$H: dims3, set of $$I: dims4, set of $$J: dims5, set of $$K: dims6); /** @group stdlib.builtins.array Test if \a i is in the index set of \a x */ test has_index(int: i, array[int] of any $T: x) = i in index_set(x); /** @group stdlib.builtins.array Test if \a e is an element of array \a x */ test has_element($T: e, array[int] of $T: x) = exists (i in index_set(x)) (x[i]=e); /** @group stdlib.builtins.array Test if \a e is an element of array \a x */ test has_element($T: e, array[int] of opt $T: x) = exists (i in index_set(x)) (x[i]=e); /** @group stdlib.builtins.array Test if \a e is an element of array \a x */ predicate has_element($T: e, array[$$E] of any $T: x) = exists (i in index_set(x)) (x[i]=e); /** @group stdlib.builtins.array Return the set containing the elements of \a x */ function var set of $$T: array2set(array[int] of var $$T: x) ::promise_total = if length(x) = 0 then {} else let { set of int: D = dom_array(x); constraint assert(min(D) > -infinity /\ max(D) < infinity, "array2set needs finite bounds on argument array"); var set of D: y; constraint fzn_array_int_union(x, y); } in y endif; function var set of $$T: array2set(array[int] of var opt $$T: x) ::promise_total = if length(x) = 0 then {} else let { set of int: D = dom_array_occurring(x); constraint assert(min(D) > -infinity /\ max(D) < infinity, "array2set needs finite bounds on argument array"); var set of D: y; constraint fzn_array_opt_int_union(x, y); } in y endif; /** @group stdlib.builtins.array Return the set containing the elements of \a x */ function set of $$T: array2set(array[int] of $$T: x) = { x[i] | i in index_set(x) }; /** @group stdlib.builtins.array Return the set containing the elements of \a x */ function set of $$T: array2set(array[int] of opt $$T: x) = { deopt(x[i]) | i in index_set(x) where occurs(x[i]) }; /** @group stdlib.builtins.array Return the set containing the elements of \a x */ function set of bool: array2set(array[int] of bool: x) = let { bool: f = exists(b in x)(not b); bool: t = exists(b in x)(b); } in if f /\ t then {false,true} elseif f then {false} elseif t then {true} else {} endif; /** @group stdlib.builtins.array Return the set containing the elements of \a x */ function set of float: array2set(array[int] of float: x) = { x[i] | i in index_set(x) }; /** @group stdlib.builtins.array Return if \a y contains \a x */ function bool: 'in'($X: x, array[$T] of $X: y) = exists (z in array1d(y)) (z=x); /** @group stdlib.builtins.array Return if \a y contains \a x */ function bool: 'in'(opt $X: x, array[$T] of opt $X: y) = exists (z in array1d(y)) (z=x); /** @group stdlib.builtins.array Return if \a y contains \a x */ function var bool: 'in'(var $X: x, array[$T] of var $X: y) = exists (z in array1d(y)) (z=x); /** @group stdlib.builtins.array Return if \a y contains \a x */ function var bool: 'in'(var opt $X: x, array[$T] of var opt $X: y) = exists (z in array1d(y)) (z=x); /** @group stdlib.builtins.array Return if \a y contains \a x */ function bool: 'in'(set of $X: x, array[$T] of set of $X: y) = exists (z in array1d(y)) (z=x); /** @group stdlib.builtins.array Return if \a y contains \a x */ function var bool: 'in'(var set of $X: x, array[$T] of var set of $X: y) = exists (z in array1d(y)) (z=x); libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_random.mzn0000644000175000017500000001061214536677021023047 0ustar kaolkaol/*** @groupdef stdlib.random Random Number Generator builtins These functions implement random number generators from different probability distributions. */ /** @group stdlib.random Return a sample from the normal distribution defined by \(\a mean, \a std\) */ function float: normal(float: mean, float: std); /** @group stdlib.random Return a sample from the normal distribution defined by \(\a mean, \a std\) */ function float: normal(int: mean, float: std); /** @group stdlib.random Return a sample from the uniform distribution defined by \(\a lowerbound, \a upperbound\) */ function float: uniform(float: lowerbound, float: upperbound); /** @group stdlib.random Return a sample from the uniform distribution defined by \(\a lowerbound, \a upperbound\) */ function int: uniform(int: lowerbound, int: upperbound); /** @group stdlib.random Return a sample from the uniform distribution defined by \a S */ function int: uniform(set of int: S) = if card(S) == max(S) - min(S) + 1 then uniform(min(S),max(S)) else [ i | i in S ][uniform(1,card(S))] endif; /** @group stdlib.random Return a sample from the poisson distribution defined by \a mean */ function int: poisson(float: mean); /** @group stdlib.random Return a sample from the poisson distribution defined by an integer \a mean */ function int: poisson(int: mean); /** @group stdlib.random Return a sample from the gamma distribution defined by \(\a alpha, \a beta\) */ function float: gamma(float: alpha, float: beta); /** @group stdlib.random Return a sample from the gamma distribution defined by \(\a alpha, \a beta\) */ function float: gamma(int: alpha, float: beta); /** @group stdlib.random Return a sample from the Weibull distribution defined by \(\a shape, \a scale\) */ function float: weibull(float: shape, float: scale); /** @group stdlib.random Return a sample from the Weibull distribution defined by \(\a shape, \a scale\) */ function float: weibull(int: shape, float: scale); /** @group stdlib.random Return a sample from the exponential distribution defined by \(\a lambda\) */ function float: exponential(int: lambda); /** @group stdlib.random Return a sample from the exponential distribution defined by \(\a lambda\) */ function float: exponential(float: lambda); /** @group stdlib.random Return a sample from the lognormal distribution defined by \(\a mean, \a std\) */ function float: lognormal(float: mean, float: std); /** @group stdlib.random Return a sample from the lognormal distribution defined by \(\a mean, \a std\) */ function float: lognormal(int: mean, float: std); /** @group stdlib.random Return a sample from the chi-squared distribution defined by the degree of freedom \(\a n\) */ function float: chisquared(int: n); /** @group stdlib.random Return a sample from the chi-squared distribution defined by the degree of freedom \(\a n\) */ function float: chisquared(float: n); /** @group stdlib.random Return a sample from the cauchy distribution defined by \(\a mean, \a scale\) */ function float: cauchy(float: mean, float: scale); /** @group stdlib.random Return a sample from the cauchy distribution defined by \(\a mean, \a scale\) */ function float: cauchy(int: mean, float: scale); /** @group stdlib.random Return a sample from the Fisher-Snedecor F-distribution defined by the degrees of freedom \(\a d1, \a d2\) */ function float: fdistribution(float: d1, float: d2); /** @group stdlib.random Return a sample from the Fisher-Snedecor F-distribution defined by the degrees of freedom \(\a d1, \a d2\) */ function float: fdistribution(int: d1, int: d2); /** @group stdlib.random Return a sample from the student's t-distribution defined by the sample size \(\a n\) */ function float: tdistribution(float: n); /** @group stdlib.random Return a sample from the student's t-distribution defined by the sample size \(\a n\) */ function float: tdistribution(int: n); /** @group stdlib.random Return a sample from the discrete distribution defined by the array of weights \(\a weights\) that assigns a weight to each integer starting from zero */ function int: discrete_distribution(array[int] of int: weights); /** @group stdlib.random Return a boolean sample from the Bernoulli distribution defined by probability \(\a p\) */ function bool: bernoulli(float: p); /** @group stdlib.random Return a sample from the binomial distribution defined by sample number \a t and probability \a p */ function int: binomial(int: t, float: p); libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_sort.mzn0000644000175000017500000000356414536677021022566 0ustar kaolkaol/*** @groupdef stdlib.sort Array sorting operations */ /** @group stdlib.sort Return array \a x sorted by the values in \a y in non-decreasing order The sort is stable, i.e. if \a y[\p i] = \a y[\p j] with \p i < \p j, then \a x[\p i] will appear in the output before \a x[\p j]. */ function array[$$E] of any $T: sort_by(array[$$E] of any $T: x, array[$$E] of int: y); /** @group stdlib.sort Return array \a x sorted by the values in \a y in non-decreasing order The sort is stable, i.e. if \a y[\p i] = \a y[\p j] with \p i < \p j, then \a x[\p i] will appear in the output before \a x[\p j]. */ function array[$$E] of any $T: sort_by(array[$$E] of any $T: x, array[$$E] of float: y); /** @group stdlib.sort Return values from array \a x sorted in non-decreasing order */ function array[$$E] of int: sort(array[$$E] of int: x); /** @group stdlib.sort Return values from array \a x sorted in non-decreasing order */ function array[$$E] of float: sort(array[$$E] of float: x); /** @group stdlib.sort Return values from array \a x sorted in non-decreasing order */ function array[$$E] of bool: sort(array[$$E] of bool: x); /** @group stdlib.sort Returns the permutation \a p which causes \a x to be in sorted order hence \a x[\a p[\p i]] <= \a x[\a p[\p i+1]]. The permutation is the stable sort hence \a x[\a p[\p i]] = \a x[\a p[\p i+1]] \(\rightarrow\) \a p[\p i] < \a p[\p i+1]. */ function array[int] of $$E: arg_sort(array[$$E] of int:x) = sort_by(array1d(index_set(x), [i | i in index_set(x)]), x); /** @group stdlib.sort Returns the permutation \a p which causes \a x to be in sorted order hence \a x[\a p[\p i]] <= \a x[\a p[\p i+1]]. The permutation is the stable sort hence \a x[\a p[\p i]] = \a x[\a p[\p i+1]] \(\rightarrow\) \a p[\p i] < \a p[\p i+1]. */ function array[int] of $$E: arg_sort(array[$$E] of float:x) = sort_by(array1d(index_set(x), [i | i in index_set(x)]), x); libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_string.mzn0000644000175000017500000002110214536677021023071 0ustar kaolkaol/*** @groupdef stdlib.builtins.string String operations These functions implement operations on strings. */ /** @group stdlib.builtins.string Convert \a x into a string */ function string: show(any $T: x); /** @group stdlib.builtins.string Convert \a x into a string */ function string: show(array[$U] of any $T: x); function string: show_indexed(array[int] of string: idx, array[int] of string: x) = "[" ++ join(", ", [idx[i]++": "++x[i] | i in index_set(x)]) ++ "]"; function string: showDzn(any $T: x) ::mzn_internal_representation; function string: showDzn(array[$U] of any $T: x) ::mzn_internal_representation; function string: showDznId(string: x) ::mzn_internal_representation; function string: showCheckerOutput(); /** @group stdlib.builtins.string Formatted to-string conversion for integers Converts the integer \a x into a string right justified by the number of characters given by \a w, or left justified if \a w is negative. */ function string: show_int(int: w, var int: x); /** @group stdlib.builtins.string Formatted to-string conversion for floats. Converts the float \a x into a string right justified by the number of characters given by \a w, or left justified if \a w is negative. The number of digits to appear after the decimal point is given by \a p. It is a run-time error for \a p to be negative. */ function string: show_float(int: w, int: p, var float: x); /** @group stdlib.builtins.string Convert two-dimensional array \a vs into a string with row and column headers \a row_hdr and \a col_hdr */ function string: show2d_indexed(array[int] of string: row_hdr, array[int] of string: col_hdr, array[int,int] of string: vs) = let { int: row_hdr_max = max([0]++[string_length(r)+1 | r in row_hdr]); string: row_hdr_offset = if row_hdr_max = 0 then " " else concat([" " | _ in 1..row_hdr_max+2]) endif; array[int] of int: col_hdr_max = [ j : max([if length(col_hdr)=0 then 0 else string_length(col_hdr[j]) endif]++ [string_length(vs[i,j]) | i in index_set_1of2(vs)]) | j in index_set_2of2(vs)]; } in if length(vs) = 0 then "[| |]" else if length(col_hdr)=0 then "[" else "[|"++row_hdr_offset++concat(i in index_set(col_hdr))(format_justify_string(col_hdr_max[i],col_hdr[i])++": ")++"\n " endif ++concat([ "| "++ if length(row_hdr) > 0 then format_justify_string(row_hdr_max-1, row_hdr[i])++": " endif++ join(", ", [format_justify_string(col_hdr_max[j], vs[i,j]) | j in index_set_2of2(vs)])++"\n " | i in index_set_1of2(vs) ])++"|]" endif; /** @group stdlib.builtins.string Convert two-dimensional array \a x into a string */ function string: show2d(array[$$E,$$F] of any $T: x) = let { bool: idx1_is_enum = if length(x) != 0 then min(enum_of(min(index_set_1of2(x)))) != -infinity else false endif; bool: idx1_is_needed = if length(x) != 0 then idx1_is_enum \/ min(index_set_1of2(x)) != 1 else false endif; bool: idx2_is_enum = if length(x) != 0 then min(enum_of(min(index_set_2of2(x)))) != -infinity else false endif; bool: idx2_is_needed = if length(x) != 0 then idx2_is_enum \/ min(index_set_2of2(x)) != 1 else false endif; array[int] of string: col_hdr = if idx2_is_needed then [i : show(i) | i in index_set_2of2(x)] else [] endif; array[int] of string: row_hdr = if idx1_is_needed then [i : show(i) | i in index_set_1of2(x)] else [] endif; } in show2d_indexed(row_hdr, col_hdr, [ (i,j) : show(x[i,j]) | i in index_set_1of2(x), j in index_set_2of2(x) ]); /** @group stdlib.builtins.string Convert three-dimensional array \a x into a string */ function string: show3d(array[int,int,int] of any $T: x) = let { int: len1=card(index_set_1of3(x)); int: len2=card(index_set_2of3(x)); int: len3=card(index_set_3of3(x)); array[int] of string: s = [show(x[i,j,k]) | i in index_set_1of3(x), j in index_set_2of3(x), k in index_set_3of3(x)]; int: max_length = if length(s) > 0 then max([string_length(s[i]) | i in index_set(s)]) else 0 endif; } in "[| | "++ concat([ format_justify_string(max_length,s[(i - 1) * len2 * len3 + (j - 1) * len3 + k]) ++ if k < len3 then ", " elseif j < len2 then " |\n " elseif i < len1 then " |,\n\n | " else " | |]\n" endif | i in 1..len1, j in 1..len2, k in 1..len3 ]) ++ if len1 = 0 then "| |]" else "" endif; /** @group stdlib.builtins.string Convert \a x into JSON string */ function string: showJSON(any $T: x); /** @group stdlib.builtins.string Convert \a x into JSON string */ function string: showJSON(array[$U] of any $T: x); /** @group stdlib.builtins.string Create a JSON object from an array of key-value pairs \a obj. \a obj[\p i, \p 1] is the key name for the \p i-th entry \a obj[\p i, \p 2] is the JSON value for the \o i-th entry (usually generated using showJSON) */ function string: json_object(array [int, 1..2] of string: obj) = concat([ "{", join(",", [ join(":", [showJSON(obj[i, 1]), obj[i, 2]]) | i in index_set_1of2(obj) ]), "}" ]); /** @group stdlib.builtins.string Create a JSON array from an array of JSON strings \a arr. The elements are assumed to be strings already in JSON format (usually generated using showJSON) */ function string: json_array(array [int] of string: arr) = concat(["[", join(",", arr), "]"]); /** @group stdlib.builtins.string Return length of \a s */ function int: string_length(string: s); /** @group stdlib.builtins.string Return concatenation of \a s1 and \a s2 */ function string: '++'(string: s1, string: s2) ::mzn_internal_representation; /** @group stdlib.builtins.string Return concatenation of strings in array \a s */ function string: concat(array[$T] of string: s); /** @group stdlib.builtins.string Join string in array \a s using delimiter \a d */ function string: join(string: d, array[$T] of string: s); /** @group stdlib.builtins.string Convert \a x into a string */ function string: format(any $T: x) = show(x); /** @group stdlib.builtins.string Convert \a x into a string */ function string: format(array[$U] of any $T: x) = show(x); /** @group stdlib.builtins.string Return array for output of all variables in JSON format */ function array[int] of string: outputJSON(); /** @group stdlib.builtins.string Return array for output of all variables in JSON format, including objective if \a b is true */ function array[int] of string: outputJSON(bool: b); /** @group stdlib.builtins.string Return array for output of all parameters in JSON format */ function array[int] of string: outputJSONParameters(); /** @group stdlib.builtins.string Formatted to-string conversion Converts the value \a x into a string right justified by the number of characters given by \a w, or left justified if \a w is negative. The maximum length of the string representation of \a x is given by \a p, or the maximum number of digits after the decimal point for floating point numbers. It is a run-time error for \a p to be negative. */ function string: format(int: w, int: p, any $T: x); /** @group stdlib.builtins.string Formatted to-string conversion Converts the value \a x into a string right justified by the number of characters given by \a w, or left justified if \a w is negative. The maximum length of the string representation of \a x is given by \a p. It is a run-time error for \a p to be negative. */ function string: format(int: w, int: p, array[$U] of any $T: x); /** @group stdlib.builtins.string Formatted to-string conversion Converts the value \a x into a string right justified by the number of characters given by \a w, or left justified if \a w is negative. */ function string: format(int: w, any $T: x); /** @group stdlib.builtins.string Formatted to-string conversion Converts the value \a x into a string right justified by the number of characters given by \a w, or left justified if \a w is negative. */ function string: format(int: w, array[$U] of any $T: x); /** @group stdlib.builtins.string String justification Returns the string \a x right justified by the number of characters given by \a w, or left justified if \a w is negative. */ function string: format_justify_string(int: w, string: x); /** @group stdlib.builtins.string Return path of file where this function is called */ function string: file_path(); /** @group stdlib.builtins.string Add \a o to the output section \a s */ test output_to_section(string: s, string: o); /** @group stdlib.builtins.string Output \a o to the JSON section \a s */ test output_to_json_section(string: s, any $T: o); /** @group stdlib.builtins.string Output \a o to the JSON section \a s */ test output_to_json_section(string: s, array [$U] of any $T: o); libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_compare.mzn0000644000175000017500000004631714536677021023230 0ustar kaolkaol/*** @groupdef stdlib.builtins.compare Comparison Builtins These builtins implement comparison operations. */ /** @group stdlib.builtins.compare Return if \a x is less than \a y */ function bool: '<'( $T: x, $T: y) ::mzn_internal_representation; /** @group stdlib.builtins.compare Return if \a x is less than \a y */ function var bool: '<'(var $T: x,var $T: y) ::mzn_internal_representation; /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is less than the value of \a y. */ function var bool: '<'(var opt int: x, var opt int: y) = absent(x) \/ absent(y) \/ deopt(x) < deopt(y); /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is less than the value of \a y. */ function bool: '<'(opt int: x, opt int: y) = absent(x) \/ absent(y) \/ deopt(x) < deopt(y); /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is less than the value of \a y. */ function var bool: '<'(var opt float: x, var opt float: y) = absent(x) \/ absent(y) \/ deopt(x) < deopt(y); /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is less than the value of \a y. */ function bool: '<'(opt float: x, opt float: y) = absent(x) \/ absent(y) \/ deopt(x) < deopt(y); /** @group stdlib.builtins.compare Return if \a x is greater than \a y */ function bool: '>'( $T: x, $T: y) ::mzn_internal_representation; /** @group stdlib.builtins.compare Return if \a x is greater than \a y */ function var bool: '>'(var $T: x,var $T: y) ::mzn_internal_representation; /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is greater than the value of \a y. */ function var bool: '>'(var opt int: x, var opt int: y) = absent(x) \/ absent(y) \/ deopt(x) > deopt(y); /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is greater than the value of \a y. */ function bool: '>'(opt int: x, opt int: y) = absent(x) \/ absent(y) \/ deopt(x) > deopt(y); /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is greater than the value of \a y. */ function var bool: '>'(var opt float: x, var opt float: y) = absent(x) \/ absent(y) \/ deopt(x) > deopt(y); /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is greater than the value of \a y. */ function bool: '>'(opt float: x, opt float: y) = absent(x) \/ absent(y) \/ deopt(x) > deopt(y); /** @group stdlib.builtins.compare Return if \a x is less than or equal to \a y */ function bool: '<='( $T: x, $T: y) ::mzn_internal_representation; /** @group stdlib.builtins.compare Return if \a x is less than or equal to \a y */ function var bool: '<='(var $T: x, var $T: y) ::mzn_internal_representation; /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is less than or equal to the value of \a y. */ function var bool: '<='(var opt int: x, var opt int: y) = absent(x) \/ absent(y) \/ deopt(x) <= deopt(y); /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is less than or equal to the value of \a y. */ function bool: '<='(opt int: x, opt int: y) = absent(x) \/ absent(y) \/ deopt(x) <= deopt(y); /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is less than or equal to the value of \a y. */ function var bool: '<='(var opt float: x, var opt float: y) = absent(x) \/ absent(y) \/ deopt(x) <= deopt(y); /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is less than or equal to the value of \a y. */ function bool: '<='(opt float: x, opt float: y) = absent(x) \/ absent(y) \/ deopt(x) <= deopt(y); /** @group stdlib.builtins.compare Return if \a x is greater than or equal to \a y */ function bool: '>='( $T: x, $T: y) ::mzn_internal_representation; /** @group stdlib.builtins.compare Return if \a x is greater than or equal to \a y */ function var bool: '>='(var $T: x,var $T: y) ::mzn_internal_representation; /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is greater than or equal to the value of \a y. */ function var bool: '>='(var opt int: x, var opt int: y) = absent(x) \/ absent(y) \/ deopt(x) >= deopt(y); /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is greater than or equal to the value of \a y. */ function bool: '>='(opt int: x, opt int: y) = absent(x) \/ absent(y) \/ deopt(x) >= deopt(y); /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is greater than or equal to the value of \a y. */ function var bool: '>='(var opt float: x, var opt float: y) = absent(x) \/ absent(y) \/ deopt(x) >= deopt(y); /** @group stdlib.builtins.compare Weak comparison: true iff either \a x or \a y is absent, or both occur and the value of \a x is greater than or equal to the value of \a y. */ function bool: '>='(opt float: x, opt float: y) = absent(x) \/ absent(y) \/ deopt(x) >= deopt(y); /** @group stdlib.builtins.compare Return if \a x is equal to \a y */ function bool: '='( $T: x, $T: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.compare Return if \a x is equal to \a y */ function bool: '='(opt $T: x, opt $T: y) ::promise_commutative = absent(x) /\ absent(y) \/ occurs(x) /\ occurs(y) /\ deopt(x) = deopt(y); /** @group stdlib.builtins.compare Return if \a x is equal to \a y */ function var bool: '='(any $T: x,any $T: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.compare Weak equality. True if either \a x or \a y are absent, or present and equal.*/ function var bool: '~='(var opt bool: x, var opt bool: y) ::promise_total ::promise_commutative = absent(x) \/ absent(y) \/ deopt(x)=deopt(y); /** @group stdlib.builtins.compare Weak disequality. True if either \a x or \a y are absent, or present and not equal.*/ function var bool: '~!='(var opt bool: x, var opt bool: y) ::promise_total ::promise_commutative = absent(x) \/ absent(y) \/ deopt(x)!=deopt(y); /** @group stdlib.builtins.compare Weak equality. True if either \a x or \a y are absent, or present and equal.*/ function var bool: '~='(var opt int: x, var opt int: y) ::promise_total ::promise_commutative = absent(x) \/ absent(y) \/ deopt(x)=deopt(y); /** @group stdlib.builtins.compare Weak disequality. True if either \a x or \a y are absent, or present and not equal.*/ function var bool: '~!='(var opt int: x, var opt int: y) ::promise_total ::promise_commutative = absent(x) \/ absent(y) \/ deopt(x)!=deopt(y); /** @group stdlib.builtins.compare Weak equality. True if either \a x or \a y are absent, or present and equal.*/ function var bool: '~='(var opt float: x, var opt float: y) ::promise_total ::promise_commutative = absent(x) \/ absent(y) \/ deopt(x)=deopt(y); /** @group stdlib.builtins.compare Weak disequality. True if either \a x or \a y are absent, or present and not equal.*/ function var bool: '~!='(var opt float: x, var opt float: y) ::promise_total ::promise_commutative = absent(x) \/ absent(y) \/ deopt(x)!=deopt(y); /** @group stdlib.builtins.compare Return if \a x is not equal to \a y */ function bool: '!='( $T: x, $T: y) ::mzn_internal_representation ::promise_commutative; /** @group stdlib.builtins.compare Return if \a x is not equal to \a y */ function bool: '!='(opt $T: x, opt $T: y) ::promise_commutative = not (x = y); /** @group stdlib.builtins.compare Return if \a x is not equal to \a y */ function var bool: '!='(any $T: x, any $T: y) ::mzn_internal_representation ::promise_commutative; % Special case comparison operators for integer variable and float constant function var bool: '<='(var int: x, float: y) = (x <= floor(y)); function var bool: '>='(var int: x, float: y) = (x >= ceil(y)); function var bool: '<='(float: x, var int: y) = (y >= ceil(x)); function var bool: '>='(float: x, var int: y) = (y <= floor(x)); function var bool: '<'(var int: x, float: y) = (x <= ceil(y)-1); function var bool: '>'(float: x, var int: y) = (y <= ceil(x)-1); function var bool: '>'(var int: x, float: y) = (x >= floor(y)+1); function var bool: '<'(float: x, var int: y) = (y >= floor(x)+1); function var bool: '='(var int: x, float: y) = if ceil(y)=floor(y) then x=ceil(y) else false endif; function var bool: '='(float: x, var int: y) = if ceil(x)=floor(x) then y=ceil(x) else false endif; function var bool: '!='(var int: x, float: y) = if ceil(y)=floor(y) then x != ceil(y) else true endif; function var bool: '!='(float: x, var int: y) = if ceil(x)=floor(x) then y != ceil(x) else true endif; function bool: '<='(int: x, float: y) = (x <= floor(y)); function bool: '>='(int: x, float: y) = (x >= ceil(y)); function bool: '<='(float: x, int: y) = (y >= ceil(x)); function bool: '>='(float: x, int: y) = (y <= floor(x)); function bool: '<'(int: x, float: y) = (x <= ceil(y)-1); function bool: '>'(float: x, int: y) = (y <= ceil(x)-1); function bool: '>'(int: x, float: y) = (x >= floor(y)+1); function bool: '<'(float: x, int: y) = (y >= floor(x)+1); function bool: '='(int: x, float: y) = if ceil(y)=floor(y) then x=ceil(y) else false endif; function bool: '='(float: x, int: y) = if ceil(x)=floor(x) then y=ceil(x) else false endif; function bool: '!='(int: x, float: y) = if ceil(y)=floor(y) then x != ceil(y) else true endif; function bool: '!='(float: x, int: y) = if ceil(x)=floor(x) then y != ceil(x) else true endif; test lex_less(array[int] of $T: x,array[int] of $T: y) = if length(x)=1 /\ length(y)=1 then x[min(index_set(x))] < y[min(index_set(y))] elseif length(x)=0 then length(y)>0 elseif length(y)=0 then false else let { int: lx = min(index_set(x)), int: ux = max(index_set(x)), int: ly = min(index_set(y)), int: uy = max(index_set(y)), int: size = min(ux - lx, uy - ly), int: first_not_equal = arg_max(i in 0..size)(x[lx+i] != y[ly+i]); } in if x[lx+first_not_equal-1]=y[ly+first_not_equal-1] then length(x) < length(y) else x[lx+first_not_equal-1]'(array[$U] of $T: x,array[$U] of $T: y) = matching_index_sets(x, y) /\ lex_less(array1d(y),array1d(x)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically greater than array \a y */ function var bool: '>'(array[$U] of var int: x,array[$U] of var int: y) = matching_index_sets(x, y) /\ lex_less(array1d(y),array1d(x)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically greater than array \a y */ function var bool: '>'(array[$U] of var bool: x,array[$U] of var bool: y) = matching_index_sets(x, y) /\ lex_less(array1d(y),array1d(x)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically greater than array \a y */ function var bool: '>'(array[$U] of var float: x,array[$U] of var float: y) = matching_index_sets(x, y) /\ lex_less(array1d(y),array1d(x)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically greater than array \a y */ function var bool: '>'(array[$U] of var set of int: x,array[$U] of var set of int: y) = matching_index_sets(x, y) /\ lex_less(array1d(y),array1d(x)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically smaller than or equal to array \a y */ function bool: '<='(array[$U] of $T: x,array[$U] of $T: y) = matching_index_sets(x, y) /\ lex_lesseq(array1d(x),array1d(y)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically smaller than or equal to array \a y */ function var bool: '<='(array[$U] of var int: x,array[$U] of var int: y) = matching_index_sets(x, y) /\ lex_lesseq(array1d(x),array1d(y)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically smaller than or equal to array \a y */ function var bool: '<='(array[$U] of var bool: x,array[$U] of var bool: y) = matching_index_sets(x, y) /\ lex_lesseq(array1d(x),array1d(y)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically smaller than or equal to array \a y */ function var bool: '<='(array[$U] of var float: x,array[$U] of var float: y) = matching_index_sets(x, y) /\ lex_lesseq(array1d(x),array1d(y)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically smaller than or equal to array \a y */ function var bool: '<='(array[$U] of var set of int: x,array[$U] of var set of int: y) = matching_index_sets(x, y) /\ lex_lesseq(array1d(x),array1d(y)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically greater than or equal to array \a y */ function bool: '>='(array[$U] of $T: x,array[$U] of $T: y) = matching_index_sets(x, y) /\ lex_lesseq(array1d(y),array1d(x)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically greater than or equal to array \a y */ function var bool: '>='(array[$U] of var int: x,array[$U] of var int: y) = matching_index_sets(x, y) /\ lex_lesseq(array1d(y),array1d(x)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically greater than or equal to array \a y */ function var bool: '>='(array[$U] of var bool: x,array[$U] of var bool: y) = matching_index_sets(x, y) /\ lex_lesseq(array1d(y),array1d(x)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically greater than or equal to array \a y */ function var bool: '>='(array[$U] of var float: x,array[$U] of var float: y) = matching_index_sets(x, y) /\ lex_lesseq(array1d(y),array1d(x)); /** @group stdlib.builtins.compare Return if array \a x is lexicographically greater than or equal to array \a y */ function var bool: '>='(array[$U] of var set of int: x,array[$U] of var set of int: y) = matching_index_sets(x, y) /\ lex_lesseq(array1d(y),array1d(x)); /** @group stdlib.builtins.compare Return if array \a x is equal to array \a y */ function bool: '='(array[$U] of $T: x, array[$U] of $T: y) ::promise_commutative = matching_index_sets(x, y) /\ let { any: xx = array1d(x); any: yy = array1d(y); } in forall (i in index_set(xx)) (xx[i]=yy[i]); /** @group stdlib.builtins.compare Return if array \a x is equal to array \a y */ function bool: '='(array[$U] of opt $T: x, array[$U] of opt $T: y) ::promise_commutative = matching_index_sets(x, y) /\ let { any: xx = array1d(x); any: yy = array1d(y); } in forall (i in index_set(xx)) (xx[i]=yy[i]); /** @group stdlib.builtins.compare Return if array \a x is equal to array \a y */ function var bool: '='(array[$U] of var $T: x, array[$U] of var $T: y) ::promise_commutative = matching_index_sets(x, y) /\ let { any: xx = array1d(x); any: yy = array1d(y); } in forall (i in index_set(xx)) (xx[i]=yy[i]); /** @group stdlib.builtins.compare Return if array \a x is equal to array \a y */ function var bool: '='(array[$U] of var opt $T: x,array[$U] of var opt $T: y) ::promise_commutative = matching_index_sets(x, y) /\ let { any: xx = array1d(x); any: yy = array1d(y); } in forall (i in index_set(xx)) (xx[i]=yy[i]); /** @group stdlib.builtins.compare Return if array \a x is not equal to array \a y */ function bool: '!='(array[$U] of $T: x, array[$U] of $T: y) ::promise_commutative = matching_index_sets(x, y) /\ let { any: xx = array1d(x); any: yy = array1d(y); } in exists (i in index_set(xx)) (xx[i]!=yy[i]); /** @group stdlib.builtins.compare Return if array \a x is not equal to array \a y */ function bool: '!='(array[$U] of opt $T: x, array[$U] of opt $T: y) ::promise_commutative = matching_index_sets(x, y) /\ let { any: xx = array1d(x); any: yy = array1d(y); } in exists (i in index_set(xx)) (xx[i]!=yy[i]); /** @group stdlib.builtins.compare Return if array \a x is not equal to array \a y */ function var bool: '!='(array[$U] of var $T: x, array[$U] of var $T: y) ::promise_commutative = matching_index_sets(x, y) /\ let { any: xx = array1d(x); any: yy = array1d(y); } in exists (i in index_set(xx)) (xx[i]!=yy[i]); /** @group stdlib.builtins.compare Return if array \a x is not equal to array \a y */ function var bool: '!='(array[$U] of var opt $T: x, array[$U] of var opt $T: y) ::promise_commutative = matching_index_sets(x, y) /\ let { any: xx = array1d(x); any: yy = array1d(y); } in exists (i in index_set(xx)) (xx[i]!=yy[i]); test matching_index_sets(array[$U] of any $T: x, array[$U] of any $T: y) = assert(index_sets_agree(x,y), "Index set mismatch. The index set of the left hand side value is " ++ show_index_sets(x) ++ ", but index set of the right hand side value is " ++ show_index_sets(y) ++ ". You may need to coerce the index sets using an array transformation."); function string: show_index_sets(array[$U] of any $T: x); libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_enum.mzn0000644000175000017500000001373714536677021022546 0ustar kaolkaol/*** @groupdef stdlib.builtins.enum Functions for enums */ %TODO: Document these function set of int: anon_enum(int: n) = 1..n; function set of int: anon_enum_set(set of int: S) = 1..card(S); function set of int: anon_enum(array[int] of string: x) ::mzn_internal_representation; /** @group stdlib.builtins.enum Return enum set of \a x */ function set of $$E: enum_of(var opt $$E: x) ::mzn_internal_representation; /** @group stdlib.builtins.enum Return enum set of \a x */ function set of $$E: enum_of(var set of $$E: x) ::mzn_internal_representation; /** @group stdlib.builtins.enum Return enum set of \a x */ function set of $$E: enum_of(array[$T] of var opt $$E: x) ::mzn_internal_representation; /** @group stdlib.builtins.enum Return enum set of \a x */ function set of $$E: enum_of(array[$T] of var set of $$E: x) ::mzn_internal_representation; function set of $$E: enum_of_internal(set of $$E: e) = e; /** @group stdlib.builtins.enum Return next greater enum value of \a x */ function $$E: enum_next($$E: x) = enum_next(enum_of(x), x); /** @group stdlib.builtins.enum Return next greater enum value of \a x */ function opt $$E: enum_next(opt $$E: x) = enum_next(enum_of(x), x); /** @group stdlib.builtins.enum Return next greater enum value of \a x */ function var $$E: enum_next(var $$E: x) = enum_next(enum_of(x), x); /** @group stdlib.builtins.enum Return next greater enum value of \a x */ function var opt $$E: enum_next(var opt $$E: x) = enum_next(enum_of(x), x); /** @group stdlib.builtins.enum Return next greater enum value of \a x in enum \a e */ function $$E: enum_next(set of $$E: e, $$E: x); /** @group stdlib.builtins.enum Return next greater enum value of \a x in enum \a e */ function opt $$E: enum_next(set of $$E: e, opt $$E: x) = if occurs(x) then enum_next(e,deopt(x)) else <> endif; /** @group stdlib.builtins.enum Return next greater enum value of \a x in enum \a e */ function var $$E: enum_next(set of $$E: e, var $$E: x) = let { constraint x < max(e) } in x+1; /** @group stdlib.builtins.enum Return next greater enum value of \a x in enum \a e */ function var opt $$E: enum_next(set of $$E: e, var opt $$E: x) = if occurs(x) then enum_next(e,deopt(x)) else <> endif; /** @group stdlib.builtins.enum Return next smaller enum value of \a x */ function $$E: enum_prev($$E: x) = enum_prev(enum_of(x), x); /** @group stdlib.builtins.enum Return next smaller enum value of \a x */ function opt $$E: enum_prev(opt $$E: x) = enum_prev(enum_of(x), x); /** @group stdlib.builtins.enum Return next smaller enum value of \a x */ function var $$E: enum_prev(var $$E: x) = enum_prev(enum_of(x), x); /** @group stdlib.builtins.enum Return next smaller enum value of \a x */ function var opt $$E: enum_prev(var opt $$E: x) = enum_prev(enum_of(x), x); /** @group stdlib.builtins.enum Return next smaller enum value of \a x in enum \a e */ function $$E: enum_prev(set of $$E: e, $$E: x); /** @group stdlib.builtins.enum Return next smaller enum value of \a x in enum \a e */ function opt $$E: enum_prev(set of $$E: e, opt $$E: x) = if occurs(x) then enum_prev(e,deopt(x)) else <> endif; /** @group stdlib.builtins.enum Return next smaller enum value of \a x in enum \a e */ function var $$E: enum_prev(set of $$E: e, var $$E: x) = let { constraint x > min(e) } in x-1; /** @group stdlib.builtins.enum Return next smaller enum value of \a x in enum \a e */ function var opt $$E: enum_prev(set of $$E: e, var opt $$E: x) = if occurs(x) then enum_prev(e,deopt(x)) else <> endif; /** @group stdlib.builtins.enum Convert \a x to enum type \a X */ function $$E: to_enum(set of $$E: X, int: x); /** @group stdlib.builtins.enum Convert \a x to enum type \a X */ function opt $$E: to_enum(set of $$E: X, opt int: x) = if occurs(x) then to_enum(X, deopt(x)) else <> endif; /** @group stdlib.builtins.enum Convert \a x to enum type \a X */ function var $$E: to_enum(set of $$E: X, var int: x) = let { constraint x in X } in x; /** @group stdlib.builtins.enum Convert \a x to enum type \a X */ function var opt $$E: to_enum(set of $$E: X, var opt int: x) = if occurs(x) then to_enum(X, deopt(x)) else <> endif; /** @group stdlib.builtins.enum Convert \a x to enum type \a X */ function array[$U] of $$E: to_enum(set of $$E: X, array[$U] of int: x) = let { array[int] of int: xx = array1d(x) } in arrayXd(x, [ to_enum(X,xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.enum Convert \a x to enum type \a X */ function array[$U] of opt $$E: to_enum(set of $$E: X, array[$U] of opt int: x) = let { array[int] of opt int: xx = array1d(x) } in arrayXd(x, [ to_enum(X,xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.enum Convert \a x to enum type \a X */ function array[$U] of var $$E: to_enum(set of $$E: X, array[$U] of var int: x) = let { array[int] of var int: xx = array1d(x) } in arrayXd(x, [ to_enum(X,xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.enum Convert \a x to enum type \a X */ function array[$U] of var opt $$E: to_enum(set of $$E: X, array[$U] of var opt int: x) = let { array[int] of var opt int: xx = array1d(x) } in arrayXd(x, [ to_enum(X,xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.enum Convert \a x to enum type \a X */ function set of $$E: to_enum(set of $$E: X, set of int: x) = { to_enum(X,i) | i in x }; %/** @group stdlib.builtins.enum Convert \a x to enum type \a X */ function var set of $$E: to_enum(set of $$E: X, var set of int: x) = let { var set of X: y; constraint x subset X; constraint forall (i in X) (i in x <-> i in y); } in y; /** @group stdlib.builtins.enum Convert \a x to enum type \a X */ function array[$U] of set of $$E: to_enum(set of $$E: X, array[$U] of set of int: x) = let { array[int] of set of int: xx = array1d(x) } in arrayXd(x, [ to_enum(X, xx[i]) | i in index_set(xx)]); /** @group stdlib.builtins.enum Convert \a x to enum type \a X */ function array[$U] of var set of $$E: to_enum(set of $$E: X, array[$U] of var set of int: x) = let { array[int] of var set of int: xx = array1d(x) } in arrayXd(x, [ to_enum(X, xx[i]) | i in index_set(xx)]); libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_language.mzn0000644000175000017500000000754614536677021023366 0ustar kaolkaol/*** @groupdef stdlib.language Language information These functions return information about the MiniZinc system. */ /** @group stdlib.language Return MiniZinc version encoded as an integer (major*10000+minor*1000+patch). */ function int: mzn_compiler_version(); /** @group stdlib.language Return string representation of \a v given an integer major*10000+minor*1000+patch */ function string: mzn_version_to_string(int: v) = show(v div 10000)++"."++show((v div 1000) mod 10)++"."++show(v mod 100); /** @group stdlib.language If defined, this can be used to check that the MiniZinc compiler supports all the features used in the model. */ opt int: mzn_min_version_required; constraint assert(absent(mzn_min_version_required) \/ deopt(mzn_min_version_required) <= mzn_compiler_version(), "This model requires MiniZinc version "++mzn_version_to_string(deopt(mzn_min_version_required))++" but you are running version "++mzn_version_to_string(mzn_compiler_version())); /*** @groupdef stdlib.options Compiler options */ % TODO: Is this still in use? /** @group stdlib.options Whether to only generate domains that are contiguous ranges */ opt bool: mzn_opt_only_range_domains; /** @group stdlib.options Check whether to only generate domains that are contiguous ranges */ test mzn_check_only_range_domains() = if absent(mzn_opt_only_range_domains) then false else deopt(mzn_opt_only_range_domains) endif; /** @group stdlib.options Whether to generate defines_var annotations */ opt bool: mzn_opt_annotate_defines_var; /** @group stdlib.options Check whether to generate defines_var annotations */ test mzn_check_annotate_defines_var() = if absent(mzn_opt_annotate_defines_var) then true else deopt(mzn_opt_annotate_defines_var) endif; /** @group stdlib.options Whether to ignore symmetry breaking constraints If not specified or set to false, it depends on the solver library whether constraints that are wrapped in a symmetry_breaking_constraint call are in fact compiled. If set to true, they are not compiled, independent of the solver library. */ opt bool: mzn_ignore_symmetry_breaking_constraints; /** @group stdlib.options Check whether to ignore symmetry breaking constraints */ test mzn_check_ignore_symmetry_breaking_constraints() = if absent(mzn_ignore_symmetry_breaking_constraints) then false else deopt(mzn_ignore_symmetry_breaking_constraints) endif; /** @group stdlib.options Whether to ignore redundant constraints If not specified or set to false, it depends on the solver library whether constraints that are wrapped in a redundant_constraint call are in fact compiled. If set to true, they are not compiled, independent of the solver library. */ opt bool: mzn_ignore_redundant_constraints; /** @group stdlib.options Check whether to ignore redundant constraints */ test mzn_check_ignore_redundant_constraints() = if absent(mzn_ignore_redundant_constraints) then false else deopt(mzn_ignore_redundant_constraints) endif; /** @group stdlib.options Whether to use zero as the underlying representation for absent optional variables. If not specified or set to true, zero is used as the underlying representation for absent optional variables, breaking symmetry. If set to false, the underlying representation of absent optional variables is left unconstrained. */ opt bool: mzn_absent_zero; /** @group stdlib.options Check whether to use zero as the underlying representation of absent optional variables */ test mzn_check_absent_zero() = if absent(mzn_absent_zero) then true else deopt(mzn_absent_zero) endif; /** @group stdlib.options Whether to half reify bool_clause constraints */ opt bool: mzn_half_reify_clause; /** @group stdlib.options Check to half reify bool_clause constraints */ test mzn_check_half_reify_clause() = if absent(mzn_half_reify_clause) then true else deopt(mzn_half_reify_clause) endif; libminizinc-2.8.2/share/minizinc/std/stdlib/stdlib_internal.mzn0000644000175000017500000027012014536677021023405 0ustar kaolkaol%-----------------------------------------------------------------------------% % % Internal compiler functions % % These functions are used internally by the compiler. % % domain constraints predicate var_dom(var int: x, set of int: s) = if has_bounds(x) /\ dom(x) subset s then true else x in s endif; predicate var_dom(var opt int:x, set of int: s) = if is_fixed(x) /\ absent(fix(x)) then true else let { var int: dx = deopt(x); set of int: new_dom = dom(dx) intersect s; } in if new_dom = {} then absent(x) else var_dom(dx, new_dom union if mzn_check_absent_zero() then {0} else {} endif) endif endif; predicate var_dom(array[$T] of var opt int: x, set of int: d) = let { array[int] of var opt int: xx = array1d(x) } in forall (i in index_set(xx)) (var_dom(xx[i],d)); test var_dom(opt int:x, set of int: s) = absent(x) \/ deopt(x) in s; test var_dom(array[$T] of opt int: x, set of int: d) = forall (xx in array1d(x)) (var_dom(xx,d)); predicate var_dom(var set of int: x, set of int: s) = if has_ub_set(x) /\ ub(x) subset s then true else set_subset(x,s) endif; predicate var_dom(set of int: x, set of int: s) = x subset s; predicate var_dom(var float:x, float: l, float: u) = if has_bounds(x) /\ lb(x) >= l /\ ub(x) <= u then true else x >= l /\ x <= u endif; predicate var_dom(var float:x, set of float: d) = x in d; test var_dom(float:x, float: l, float: u) = x >= l /\ x <= u; test var_dom(float:x, set of float: d) = x in d; predicate var_dom(array[$T] of var set of int: x, set of int: d) = let { array[int] of var set of int: xx = array1d(x) } in forall (i in index_set(xx)) (var_dom(xx[i],d)); predicate var_dom(array[$T] of var int: x, set of int: d) = let { array[int] of var int: xx = array1d(x) } in forall (i in index_set(xx)) (var_dom(xx[i],d)); predicate var_dom(array[$T] of var float: x, float: l, float: u) = let { array[int] of var float: xx = array1d(x) } in forall (i in index_set(xx)) (var_dom(xx[i],l,u)); predicate var_dom(array[$T] of var float: x, set of float: d) = let { array[int] of var float: xx = array1d(x) } in forall (i in index_set(xx)) (var_dom(xx[i],d)); test var_dom(array[$T] of set of int: x, set of int: d) = let { array[int] of set of int: xx = array1d(x) } in forall (i in index_set(xx)) (xx[i] subset d); test var_dom(array[$T] of int: x, set of int: d) = let { array[int] of int: xx = array1d(x) } in forall (i in index_set(xx)) (xx[i] in d); test var_dom(array[$T] of float: x, float: l, float: u) = let { array[int] of float: xx = array1d(x) } in forall (i in index_set(xx)) (var_dom(xx[i],l,u)); test var_dom(array[$T] of float: x, set of float: d) = let { array[int] of float: xx = array1d(x) } in forall (i in index_set(xx)) (var_dom(xx[i],d)); predicate set_in(array[$T] of var int: X, set of int: s) = forall(x in array1d(X)) (x in s); predicate int_eq(array[$T] of var int: X, int: s) = forall(x in array1d(X)) (x = s); predicate float_eq(array[$T] of var int: X, float: s) = forall(x in array1d(X)) (x = s); predicate int_le(array[$T] of var int: X, int: s) = forall(x in array1d(X)) (x <= s); predicate int_le(int:s, array[$T] of var int: X) = forall(x in array1d(X)) (x >= s); predicate float_le(array[$T] of var float: X, float: s) = forall(x in array1d(X)) (x <= s); predicate float_le(float:s, array[$T] of var float: X) = forall(x in array1d(X)) (x >= s); predicate array_var_int_element(var int: x, array[int] of int: y, var int: z) = array_int_element(x,y,z); predicate array_var_bool_element(var int: x, array[int] of bool: y, var bool: z) = array_bool_element(x,y,z); predicate array_var_float_element(var int: x, array[int] of float: y, var float: z) = array_float_element(x,y,z); predicate array_var_set_element(var int: x, array[int] of set of int: y, var set of int: z) = array_set_element(x,y,z); predicate mzn_alias_eq(var bool: x, var bool: y) = bool_eq(x, y); predicate mzn_alias_eq(var opt bool: x, var opt bool: y) = deopt(x)=deopt(y) /\ occurs(x)=occurs(y); /* True iff both \a b0 and \a b1 are absent or both are present and have the same value. */ predicate bool_eq(var opt bool: b0, var opt bool: b1) = (absent(b0) /\ absent(b1)) \/ (occurs(b0) /\ occurs(b1) /\ deopt(b0)=deopt(b1)); /* True iff \a b0 occurs and is equal to \a b1 */ predicate bool_eq(var opt bool: b0, var bool: b1) = occurs(b0) /\ deopt(b0)=b1; /* True iff \a b1 occurs and is equal to \a b0 */ predicate bool_eq(var bool: b0, var opt bool: b1) = occurs(b1) /\ deopt(b1)=b0; predicate bool_xor_reif(var bool: a, var bool: b, var bool: c) = bool_xor(a,b,c); predicate bool_xor(var opt bool: x, var opt bool: y) = absent(x) \/ absent(y) \/ (deopt(x) xor deopt(y)); predicate mzn_alias_eq(var int: x, var int: y) = int_eq(x, y); predicate mzn_alias_eq(var opt int: x, var opt int: y) = deopt(x) = deopt(y) /\ occurs(x) = occurs(y); /* True iff both \a x and \a y are absent or both are present and have the same value. */ predicate int_eq(var opt int: x, var opt int: y) ::promise_commutative = (absent(x) /\ absent(y)) \/ (occurs(x) /\ occurs(y) /\ (deopt(x)=deopt(y))::maybe_partial); /* True iff only one of \a x and \a y is absent or both are present and have different values. */ predicate int_ne(var opt int : x, var opt int : y) ::promise_commutative = (absent(x) != absent(y)) \/ (occurs(x) /\ occurs(y) /\ (deopt(x)!=deopt(y))::maybe_partial); /* Constrains \a x \( \in \) \a S */ predicate set_in(var opt int: x, set of int: S) = if occurs(x) then deopt(x) in S endif; /* Constrains \a x \( \in \) \a S */ predicate set_in(var opt int: x, var set of int: S) = if occurs(x) then deopt(x) in S endif; % :NOTE: does it apply to float? /* predicate var_dom(var opt float:x, set of float: s) = let { var float: dx = deopt(x); set of float: new_dom = dom(dx) intersect s; } in if new_dom = {} then absent(x) else dx in new_dom endif; predicate var_dom(array[$T] of var opt float: x, set of float: d) = let { array[int] of var opt float: xx = array1d(x) } in forall (i in index_set(xx)) (var_dom(xx[i],d)); */ predicate float_dom(var opt float: x, array[int] of float: as) = let { any: xx = opt_internal_float(x); any: b = xx.1; any: dx = xx.2; constraint (x = reverse_map_var_opt(b, dx)) :: is_reverse_map; } in float_dom(dx, as); predicate mzn_alias_eq(var float: x, var float: y) = float_eq(x, y); predicate mzn_alias_eq(var opt float: x, var opt float: y) = deopt(x) = deopt(y) /\ occurs(x) = occurs(y); /* True iff both \a x and \a y are absent or both are present and have the same value. */ predicate float_eq(var opt float: x, var opt float: y) = (absent(x) /\ absent(y)) \/ (occurs(x) /\ occurs(y) /\ (deopt(x)=deopt(y))::maybe_partial); /* True iff only one of \a x and \a y is absent or both are present and have different values. */ predicate float_ne(var opt float : x, var opt float : y) = (absent(x) != absent(y)) \/ (occurs(x) /\ occurs(y) /\ (deopt(x)!=deopt(y))::maybe_partial); predicate xorall_reif(array[$T] of var bool: b, var bool: c) = let { var bool: nc ::is_defined_var; constraint xorall([nc]++array1d(b)) ::defines_var(nc); } in c = not nc; function var int: lin_exp(array[int] of int, array[int] of var int, int) ::mzn_internal_representation; function var float: lin_exp(array[int] of float, array[int] of var float, float) ::mzn_internal_representation; test mzn_in_root_context(var $T) ::mzn_internal_representation; test mzn_in_redundant_constraint(); test mzn_in_symmetry_breaking_constraint(); /* Internal function used to optimize over option type objective */ function var float: objective_deopt_(var opt float: x, bool: direction) = let { float: worst = if direction then lb(x)-1 else ub(x)+1 endif; } in if occurs(x) then deopt(x) else worst endif; predicate mzn_alias_eq(var set of int: x, var set of int: y) = set_eq(x, y); %-----------------------------------------------------------------------------% % % Element constraint implementations % % MiniZinc compiles element constraints using a series of intermediate % functions that test whether the constraint is total and perform array slicing % for multi-dimensional element constraints. % %%%%%%%%%%%%%%%%%%% % Element on ints function var int: element_t(var int: idx, array[int] of var int: x) :: promise_total = if length(x) = 0 then 0 else let { var dom_bounds_array(x): r ::is_defined_var; constraint idx in index_set(x); constraint array_var_int_element_nonshifted(idx,x,r) ::defines_var(r); } in r endif; function var int: element_mt(var int: idx, array[int] of var int: x) :: promise_total = let { var lb_array(x)..ub_array(x): r ::is_defined_var; var index_set(x): idx2; constraint idx in index_set(x) -> idx2=idx; constraint idx in index_set(x) \/ idx2=min(index_set(x)); constraint array_var_int_element_nonshifted(idx2,x,r) ::defines_var(r); } in r; function var int: element_t(var int: idx1, var int: idx2, array[int,int] of var int: x) :: promise_total = if length(x) = 0 then 0 else let { var dom_bounds_array(x): r ::is_defined_var; constraint idx1 in index_set_1of2(x); constraint idx2 in index_set_2of2(x); constraint array_var_int_element2d_nonshifted(idx1,idx2,x,r) ::defines_var(r); } in r endif; function var int: element_mt(var int: idx1, var int: idx2, array[int,int] of var int: x) :: promise_total = let { var lb_array(x)..ub_array(x): r ::is_defined_var; var index_set_1of2(x): idx1_2; var index_set_2of2(x): idx2_2; constraint (idx1 in index_set_1of2(x) /\ idx2 in index_set_2of2(x)) -> (idx1_2=idx1 /\ idx2_2=idx2); constraint (idx1 in index_set_1of2(x) /\ idx2 in index_set_2of2(x)) \/ (idx1_2=min(index_set_1of2(x)) /\ idx2_2=min(index_set_2of2(x))); constraint array_var_int_element2d_nonshifted(idx1_2,idx2_2,x,r) ::defines_var(r); } in r; function var int: element(var int: idx, array[int] of var int: x) = if length(x) = 0 \/ mzn_in_root_context(idx) then let { constraint idx in index_set(x) } in element_t(idx,x) elseif (has_bounds(idx) /\ lb(idx) >= min(index_set(x)) /\ ub(idx) <= max(index_set(x))) then element_t(idx,x) else let { constraint idx in index_set(x) } in element_mt(idx,x) endif; function var int: element(var int: idx1, var int: idx2, array[int,int] of var int: x) = let { int: dim = card(index_set_2of2(x)); } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of2(x); constraint idx2 in index_set_2of2(x); } in element_t(idx1, idx2, x) elseif ((has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of2(x)) /\ ub(idx1) <= max(index_set_1of2(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of2(x)) /\ ub(idx2) <= max(index_set_2of2(x)))) then element_t(idx1,idx2,x) else let { constraint idx1 in index_set_1of2(x); constraint idx2 in index_set_2of2(x); } in element_mt(idx1,idx2,x) endif; function var int: element(var int: idx1, var int: idx2, var int: idx3, array[int,int,int] of var int: x) = let { int: dim2 = card(index_set_2of3(x)); int: dim3 = card(index_set_3of3(x)); int: min = min(index_set_1of3(x))*dim2*dim3+ min(index_set_2of3(x))*dim3+ min(index_set_3of3(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of3(x); constraint idx2 in index_set_2of3(x); constraint idx3 in index_set_3of3(x); } in element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of3(x)) /\ ub(idx1) <= max(index_set_1of3(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of3(x)) /\ ub(idx2) <= max(index_set_2of3(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of3(x)) /\ ub(idx3) <= max(index_set_3of3(x)))) then element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of3(x); constraint idx2 in index_set_2of3(x); constraint idx3 in index_set_3of3(x); } in element_mt( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x)) endif; function var int: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, array[int,int,int,int] of var int: x) = let { int: dim2 = card(index_set_2of4(x)); int: dim3 = card(index_set_3of4(x)); int: dim4 = card(index_set_4of4(x)); int: min = min(index_set_1of4(x))*dim2*dim3*dim4+ min(index_set_2of4(x))*dim3*dim4+ min(index_set_3of4(x))*dim4+ min(index_set_4of4(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of4(x); constraint idx2 in index_set_2of4(x); constraint idx3 in index_set_3of4(x); constraint idx4 in index_set_4of4(x); } in element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of4(x)) /\ ub(idx1) <= max(index_set_1of4(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of4(x)) /\ ub(idx2) <= max(index_set_2of4(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of4(x)) /\ ub(idx3) <= max(index_set_3of4(x))) /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of4(x)) /\ ub(idx4) <= max(index_set_4of4(x))) ) then element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of4(x); constraint idx2 in index_set_2of4(x); constraint idx3 in index_set_3of4(x); constraint idx4 in index_set_4of4(x); } in element_mt( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x)) endif; function var int: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, array[int,int,int,int,int] of var int: x) = let { int: dim2 = card(index_set_2of5(x)); int: dim3 = card(index_set_3of5(x)); int: dim4 = card(index_set_4of5(x)); int: dim5 = card(index_set_5of5(x)); int: min = min(index_set_1of5(x))*dim2*dim3*dim4*dim5+ min(index_set_2of5(x))*dim3*dim4*dim5+ min(index_set_3of5(x))*dim4*dim5+ min(index_set_4of5(x))*dim5+ min(index_set_5of5(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of5(x); constraint idx2 in index_set_2of5(x); constraint idx3 in index_set_3of5(x); constraint idx4 in index_set_4of5(x); constraint idx5 in index_set_5of5(x); } in element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of5(x)) /\ ub(idx1) <= max(index_set_1of5(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of5(x)) /\ ub(idx2) <= max(index_set_2of5(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of5(x)) /\ ub(idx3) <= max(index_set_3of5(x))) /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of5(x)) /\ ub(idx4) <= max(index_set_4of5(x))) /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of5(x)) /\ ub(idx5) <= max(index_set_5of5(x))) ) then element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of5(x); constraint idx2 in index_set_2of5(x); constraint idx3 in index_set_3of5(x); constraint idx4 in index_set_4of5(x); constraint idx5 in index_set_5of5(x); } in element_mt( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x)) endif; function var int: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, var int: idx6, array[int,int,int,int,int,int] of var int: x) = let { int: dim2 = card(index_set_2of6(x)); int: dim3 = card(index_set_3of6(x)); int: dim4 = card(index_set_4of6(x)); int: dim5 = card(index_set_5of6(x)); int: dim6 = card(index_set_6of6(x)); int: min = min(index_set_1of6(x))*dim2*dim3*dim4*dim5*dim6+ min(index_set_2of6(x))*dim3*dim4*dim5*dim6+ min(index_set_3of6(x))*dim4*dim5*dim6+ min(index_set_4of6(x))*dim5*dim6+ min(index_set_5of6(x))*dim6+ min(index_set_6of6(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of6(x); constraint idx2 in index_set_2of6(x); constraint idx3 in index_set_3of6(x); constraint idx4 in index_set_4of6(x); constraint idx5 in index_set_5of6(x); constraint idx6 in index_set_6of6(x); } in element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of6(x)) /\ ub(idx1) <= max(index_set_1of6(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of6(x)) /\ ub(idx2) <= max(index_set_2of6(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of6(x)) /\ ub(idx3) <= max(index_set_3of6(x))) /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of6(x)) /\ ub(idx4) <= max(index_set_4of6(x))) /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of6(x)) /\ ub(idx5) <= max(index_set_5of6(x))) /\ (has_bounds(idx6) /\ lb(idx6) >= min(index_set_6of6(x)) /\ ub(idx6) <= max(index_set_6of6(x))) ) then element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of6(x); constraint idx2 in index_set_2of6(x); constraint idx3 in index_set_3of6(x); constraint idx4 in index_set_4of6(x); constraint idx5 in index_set_5of6(x); constraint idx6 in index_set_6of6(x); } in element_mt( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x)) endif; /* Return absent if \a idx is absent, otherwise return \a x[\a idx] */ function var opt int: element(var opt int: idx, array[int] of var int: x) = if absent(idx) then <> else x[deopt(idx)] endif; /* Return absent if \a idx1 or \a idx2 is absent, otherwise return \a x[\a idx1, \a idx2]. Undefined if any non-absent index is out of bounds. */ function var opt int: element(var opt int: idx1, var opt int: idx2, array[int, int] of var int: x) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2); } in <> else let { any: i1 = idx1 default min(index_set_1of2(x)); any: i2 = idx2 default min(index_set_2of2(x)); any: xx = element(i1, i2, x); } in if absent(idx1) \/ absent(idx2) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2]. Undefined if any non-absent index is out of bounds. */ function var opt int: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, array[int, int, int] of var int: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3); } in <> else let { any: i1 = idx1 default min(index_set_1of3(x)); any: i2 = idx2 default min(index_set_2of3(x)); any: i3 = idx3 default min(index_set_3of3(x)); any: xx = element(i1, i2, i3, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4]. Undefined if any non-absent index is out of bounds. */ function var opt int: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, array[int, int, int, int] of var int: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4); } in <> else let { any: i1 = idx1 default min(index_set_1of4(x)); any: i2 = idx2 default min(index_set_2of4(x)); any: i3 = idx3 default min(index_set_3of4(x)); any: i4 = idx4 default min(index_set_4of4(x)); any: xx = element(i1, i2, i3, i4, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5]. Undefined if any non-absent index is out of bounds. */ function var opt int: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, var opt int: idx5, array[int, int, int, int, int] of var int: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4) /\ absent(idx5); } in <> else let { any: i1 = idx1 default min(index_set_1of5(x)); any: i2 = idx2 default min(index_set_2of5(x)); any: i3 = idx3 default min(index_set_3of5(x)); any: i4 = idx4 default min(index_set_4of5(x)); any: i5 = idx5 default min(index_set_5of5(x)); any: xx = element(i1, i2, i3, i4, i5, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) \/ absent(idx5) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5, \a idx6]. Undefined if any non-absent index is out of bounds. */ function var opt int: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, var opt int: idx5, var opt int: idx6, array[int, int, int, int, int, int] of var int: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4) /\ absent(idx5) /\ absent(idx6); } in <> else let { any: i1 = idx1 default min(index_set_1of6(x)); any: i2 = idx2 default min(index_set_2of6(x)); any: i3 = idx3 default min(index_set_3of6(x)); any: i4 = idx4 default min(index_set_4of6(x)); any: i5 = idx5 default min(index_set_5of6(x)); any: i6 = idx6 default min(index_set_6of6(x)); any: xx = element(i1, i2, i3, i4, i5, i6, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) \/ absent(idx5) \/ absent(idx6) then <> else xx endif endif; /* Return \a x[\a idx] */ function var opt int: element(var int: idx, array[int] of var opt int: x) = let { var bool: occ = element(idx, arrayXd(x, [occurs(x_i) | x_i in x])); var int: d = element(idx, arrayXd(x, [x_i default 0 | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2] */ function var opt int: element(var int: idx1, var int: idx2, array[int,int] of var opt int: x) = let { var bool: occ = element(idx1, idx2, arrayXd(x, [occurs(x_i) | x_i in x])); var int: d = element(idx1, idx2, arrayXd(x, [x_i default 0 | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2, \a idx3] */ function var opt int: element( var int: idx1, var int: idx2, var int: idx3, array[int, int, int] of var opt int: x ) = let { var bool: occ = element(idx1, idx2, idx3, arrayXd(x, [occurs(x_i) | x_i in x])); var int: d = element(idx1, idx2, idx3, arrayXd(x, [x_i default 0 | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2, \a idx3, \a idx4] */ function var opt int: element( var int: idx1, var int: idx2, var int: idx3, var int: idx4, array[int, int, int, int] of var opt int: x ) = let { var bool: occ = element(idx1, idx2, idx3, idx4, arrayXd(x, [occurs(x_i) | x_i in x])); var int: d = element(idx1, idx2, idx3, idx4, arrayXd(x, [x_i default 0 | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5] */ function var opt int: element( var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, array[int, int, int, int, int] of var opt int: x ) = let { var bool: occ = element(idx1, idx2, idx3, idx4, idx5, arrayXd(x, [occurs(x_i) | x_i in x])); var int: d = element(idx1, idx2, idx3, idx4, idx5, arrayXd(x, [x_i default 0 | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5, \a idx6] */ function var opt int: element( var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, var int: idx6, array[int, int, int, int, int, int] of var opt int: x ) = let { var bool: occ = element(idx1, idx2, idx3, idx4, idx5, idx6, arrayXd(x, [occurs(x_i) | x_i in x])); var int: d = element(idx1, idx2, idx3, idx4, idx5, idx6, arrayXd(x, [x_i default 0 | x_i in x])); } in if occ then d else <> endif; /* Return absent if \a idx is absent, otherwise return \a x[\a idx] */ function var opt int: element(var opt int: idx, array[int] of var opt int: x) = if length(x) > 0 /\ not had_zero(idx) /\ min(index_set(x)) = 1 then let { opt int: absent_value = <>; % Workaround since [<>] array literal not allowed } in element(deopt(idx), array1d(0..max(index_set(x)), [absent_value] ++ x)) else if absent(idx) then <> else element(deopt(idx), x) endif endif; /* Return absent if \a idx1 or \a idx2 is absent, otherwise return \a x[\a idx1, \a idx2]. Undefined if any non-absent index is out of bounds. */ function var opt int: element(var opt int: idx1, var opt int: idx2, array[int, int] of var opt int: x) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2); } in <> else let { any: i1 = idx1 default min(index_set_1of2(x)); any: i2 = idx2 default min(index_set_2of2(x)); any: xx = element(i1, i2, x); } in if absent(idx1) \/ absent(idx2) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3]. Undefined if any non-absent index is out of bounds. */ function var opt int: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, array[int, int, int] of var opt int: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3); } in <> else let { any: i1 = idx1 default min(index_set_1of3(x)); any: i2 = idx2 default min(index_set_2of3(x)); any: i3 = idx3 default min(index_set_3of3(x)); any: xx = element(i1, i2, i3, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4]. Undefined if any non-absent index is out of bounds. */ function var opt int: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, array[int, int, int, int] of var opt int: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4); } in <> else let { any: i1 = idx1 default min(index_set_1of4(x)); any: i2 = idx2 default min(index_set_2of4(x)); any: i3 = idx3 default min(index_set_3of4(x)); any: i4 = idx4 default min(index_set_4of4(x)); any: xx = element(i1, i2, i3, i4, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5]. Undefined if any non-absent index is out of bounds. */ function var opt int: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, var opt int: idx5, array[int, int, int, int, int] of var opt int: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4) /\ absent(idx5); } in <> else let { any: i1 = idx1 default min(index_set_1of5(x)); any: i2 = idx2 default min(index_set_2of5(x)); any: i3 = idx3 default min(index_set_3of5(x)); any: i4 = idx4 default min(index_set_4of5(x)); any: i5 = idx5 default min(index_set_5of5(x)); any: xx = element(i1, i2, i3, i4, i5, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) \/ absent(idx5) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5, \a idx6]. Undefined if any non-absent index is out of bounds. */ function var opt int: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, var opt int: idx5, var opt int: idx6, array[int, int, int, int, int, int] of var opt int: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4) /\ absent(idx5) /\ absent(idx6); } in <> else let { any: i1 = idx1 default min(index_set_1of6(x)); any: i2 = idx2 default min(index_set_2of6(x)); any: i3 = idx3 default min(index_set_3of6(x)); any: i4 = idx4 default min(index_set_4of6(x)); any: i5 = idx5 default min(index_set_5of6(x)); any: i6 = idx6 default min(index_set_6of6(x)); any: xx = element(i1, i2, i3, i4, i5, i6, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) \/ absent(idx5) \/ absent(idx6) then <> else xx endif endif; %%%%%%%%%%%%%%%%%%% % Element on floats function var float: element_t(var int: idx, array[int] of var float: x) :: promise_total = if length(x) = 0 then 0.0 else let { var lb_array(x)..ub_array(x): r ::is_defined_var; constraint idx in index_set(x); constraint array_var_float_element_nonshifted(idx,x,r) ::defines_var(r); } in r endif; function var float: element_mt(var int: idx, array[int] of var float: x) :: promise_total = let { var lb_array(x)..ub_array(x): r ::is_defined_var; var index_set(x): idx2; constraint idx in index_set(x) -> idx2=idx; constraint idx in index_set(x) \/ idx2=min(index_set(x)); constraint array_var_float_element_nonshifted(idx2,x,r) ::defines_var(r); } in r; function var float: element_t(var int: idx1, var int: idx2, array[int,int] of var float: x) :: promise_total = if length(x) = 0 then 0.0 else let { var lb_array(x)..ub_array(x): r ::is_defined_var; constraint idx1 in index_set_1of2(x); constraint idx2 in index_set_2of2(x); constraint array_var_float_element2d_nonshifted(idx1,idx2,x,r) ::defines_var(r); } in r endif; function var float: element_mt(var int: idx1, var int: idx2, array[int,int] of var float: x) :: promise_total = let { var lb_array(x)..ub_array(x): r ::is_defined_var; var index_set_1of2(x): idx1_2; var index_set_2of2(x): idx2_2; constraint (idx1 in index_set_1of2(x) /\ idx2 in index_set_2of2(x)) -> (idx1_2=idx1 /\ idx2_2=idx2); constraint (idx1 in index_set_1of2(x) /\ idx2 in index_set_2of2(x)) \/ (idx1_2=min(index_set_1of2(x)) /\ idx2_2=min(index_set_2of2(x))); constraint array_var_float_element2d_nonshifted(idx1_2,idx2_2,x,r) ::defines_var(r); } in r; function var float: element(var int: idx, array[int] of var float: x) = if length(x) = 0 \/ mzn_in_root_context(idx) then let { constraint idx in index_set(x) } in element_t(idx,x) elseif (has_bounds(idx) /\ lb(idx) >= min(index_set(x)) /\ ub(idx) <= max(index_set(x))) then element_t(idx,x) else let { constraint idx in index_set(x) } in element_mt(idx,x) endif; function var float: element(var int: idx1, var int: idx2, array[int,int] of var float: x) = let { int: dim = card(index_set_2of2(x)); } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of2(x); constraint idx2 in index_set_2of2(x); } in element_t(idx1,idx2,x) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of2(x)) /\ ub(idx1) <= max(index_set_1of2(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of2(x)) /\ ub(idx2) <= max(index_set_2of2(x))) ) then element_t(idx1,idx2,x) else let { constraint idx1 in index_set_1of2(x); constraint idx2 in index_set_2of2(x); } in element_mt(idx1,idx2,x) endif; function var float: element(var int: idx1, var int: idx2, var int: idx3, array[int,int,int] of var float: x) = let { int: dim2 = card(index_set_2of3(x)); int: dim3 = card(index_set_3of3(x)); int: min = min(index_set_1of3(x))*dim2*dim3+ min(index_set_2of3(x))*dim3+ min(index_set_3of3(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of3(x); constraint idx2 in index_set_2of3(x); constraint idx3 in index_set_3of3(x); } in element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of3(x)) /\ ub(idx1) <= max(index_set_1of3(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of3(x)) /\ ub(idx2) <= max(index_set_2of3(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of3(x)) /\ ub(idx3) <= max(index_set_3of3(x))) ) then element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of3(x); constraint idx2 in index_set_2of3(x); constraint idx3 in index_set_3of3(x); } in element_mt( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x)) endif; function var float: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, array[int,int,int,int] of var float: x) = let { int: dim2 = card(index_set_2of4(x)); int: dim3 = card(index_set_3of4(x)); int: dim4 = card(index_set_4of4(x)); int: min = min(index_set_1of4(x))*dim2*dim3*dim4+ min(index_set_2of4(x))*dim3*dim4+ min(index_set_3of4(x))*dim4+ min(index_set_4of4(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of4(x); constraint idx2 in index_set_2of4(x); constraint idx3 in index_set_3of4(x); constraint idx4 in index_set_4of4(x); } in element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of4(x)) /\ ub(idx1) <= max(index_set_1of4(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of4(x)) /\ ub(idx2) <= max(index_set_2of4(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of4(x)) /\ ub(idx3) <= max(index_set_3of4(x))) /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of4(x)) /\ ub(idx4) <= max(index_set_4of4(x))) ) then element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of4(x); constraint idx2 in index_set_2of4(x); constraint idx3 in index_set_3of4(x); constraint idx4 in index_set_4of4(x); } in element_mt( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x)) endif; function var float: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, array[int,int,int,int,int] of var float: x) = let { int: dim2 = card(index_set_2of5(x)); int: dim3 = card(index_set_3of5(x)); int: dim4 = card(index_set_4of5(x)); int: dim5 = card(index_set_5of5(x)); int: min = min(index_set_1of5(x))*dim2*dim3*dim4*dim5+ min(index_set_2of5(x))*dim3*dim4*dim5+ min(index_set_3of5(x))*dim4*dim5+ min(index_set_4of5(x))*dim5+ min(index_set_5of5(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of5(x); constraint idx2 in index_set_2of5(x); constraint idx3 in index_set_3of5(x); constraint idx4 in index_set_4of5(x); constraint idx5 in index_set_5of5(x); } in element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of5(x)) /\ ub(idx1) <= max(index_set_1of5(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of5(x)) /\ ub(idx2) <= max(index_set_2of5(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of5(x)) /\ ub(idx3) <= max(index_set_3of5(x))) /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of5(x)) /\ ub(idx4) <= max(index_set_4of5(x))) /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of5(x)) /\ ub(idx5) <= max(index_set_5of5(x))) ) then element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of5(x); constraint idx2 in index_set_2of5(x); constraint idx3 in index_set_3of5(x); constraint idx4 in index_set_4of5(x); constraint idx5 in index_set_5of5(x); } in element_mt( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x)) endif; function var float: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, var int: idx6, array[int,int,int,int,int,int] of var float: x) = let { int: dim2 = card(index_set_2of6(x)); int: dim3 = card(index_set_3of6(x)); int: dim4 = card(index_set_4of6(x)); int: dim5 = card(index_set_5of6(x)); int: dim6 = card(index_set_6of6(x)); int: min = min(index_set_1of6(x))*dim2*dim3*dim4*dim5*dim6+ min(index_set_2of6(x))*dim3*dim4*dim5*dim6+ min(index_set_3of6(x))*dim4*dim5*dim6+ min(index_set_4of6(x))*dim5*dim6+ min(index_set_5of6(x))*dim6+ min(index_set_6of6(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of6(x); constraint idx2 in index_set_2of6(x); constraint idx3 in index_set_3of6(x); constraint idx4 in index_set_4of6(x); constraint idx5 in index_set_5of6(x); constraint idx6 in index_set_6of6(x); } in element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of6(x)) /\ ub(idx1) <= max(index_set_1of6(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of6(x)) /\ ub(idx2) <= max(index_set_2of6(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of6(x)) /\ ub(idx3) <= max(index_set_3of6(x))) /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of6(x)) /\ ub(idx4) <= max(index_set_4of6(x))) /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of6(x)) /\ ub(idx5) <= max(index_set_5of6(x))) /\ (has_bounds(idx6) /\ lb(idx6) >= min(index_set_6of6(x)) /\ ub(idx6) <= max(index_set_6of6(x))) ) then element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of6(x); constraint idx2 in index_set_2of6(x); constraint idx3 in index_set_3of6(x); constraint idx4 in index_set_4of6(x); constraint idx5 in index_set_5of6(x); constraint idx6 in index_set_6of6(x); } in element_mt( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x)) endif; /* Return absent if \a idx is absent, otherwise return \a x[\a idx] */ function var opt float: element(var opt int: idx, array[int] of var float: x) = if absent(idx) then <> else element(deopt(idx),x) endif; /* Return absent if \a idx1 or \a idx2 is absent, otherwise return \a x[\a idx1, \a idx2]. Undefined if any non-absent index is out of bounds. */ function var opt float: element(var opt int: idx1, var opt int: idx2, array[int, int] of var float: x) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2); } in <> else let { any: i1 = idx1 default min(index_set_1of2(x)); any: i2 = idx2 default min(index_set_2of2(x)); any: xx = element(i1, i2, x); } in if absent(idx1) \/ absent(idx2) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2]. Undefined if any non-absent index is out of bounds. */ function var opt float: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, array[int, int, int] of var float: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3); } in <> else let { any: i1 = idx1 default min(index_set_1of3(x)); any: i2 = idx2 default min(index_set_2of3(x)); any: i3 = idx3 default min(index_set_3of3(x)); any: xx = element(i1, i2, i3, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4]. Undefined if any non-absent index is out of bounds. */ function var opt float: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, array[int, int, int, int] of var float: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4); } in <> else let { any: i1 = idx1 default min(index_set_1of4(x)); any: i2 = idx2 default min(index_set_2of4(x)); any: i3 = idx3 default min(index_set_3of4(x)); any: i4 = idx4 default min(index_set_4of4(x)); any: xx = element(i1, i2, i3, i4, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5]. Undefined if any non-absent index is out of bounds. */ function var opt float: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, var opt int: idx5, array[int, int, int, int, int] of var float: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4) /\ absent(idx5); } in <> else let { any: i1 = idx1 default min(index_set_1of5(x)); any: i2 = idx2 default min(index_set_2of5(x)); any: i3 = idx3 default min(index_set_3of5(x)); any: i4 = idx4 default min(index_set_4of5(x)); any: i5 = idx5 default min(index_set_5of5(x)); any: xx = element(i1, i2, i3, i4, i5, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) \/ absent(idx5) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5, \a idx6]. Undefined if any non-absent index is out of bounds. */ function var opt float: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, var opt int: idx5, var opt int: idx6, array[int, int, int, int, int, int] of var float: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4) /\ absent(idx5) /\ absent(idx6); } in <> else let { any: i1 = idx1 default min(index_set_1of6(x)); any: i2 = idx2 default min(index_set_2of6(x)); any: i3 = idx3 default min(index_set_3of6(x)); any: i4 = idx4 default min(index_set_4of6(x)); any: i5 = idx5 default min(index_set_5of6(x)); any: i6 = idx6 default min(index_set_6of6(x)); any: xx = element(i1, i2, i3, i4, i5, i6, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) \/ absent(idx5) \/ absent(idx6) then <> else xx endif endif; /* Return \a x[\a idx] */ function var opt float: element(var int: idx, array[int] of var opt float: x) = let { var bool: occ = element(idx, arrayXd(x, [occurs(x_i) | x_i in x])); var float: d = element(idx, arrayXd(x, [x_i default 0 | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2] */ function var opt float: element(var int: idx1, var int: idx2, array[int,int] of var opt float: x) = let { var bool: occ = element(idx1, idx2, arrayXd(x, [occurs(x_i) | x_i in x])); var float: d = element(idx1, idx2, arrayXd(x, [x_i default 0.0 | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2, \a idx3] */ function var opt float: element( var int: idx1, var int: idx2, var int: idx3, array[int, int, int] of var opt float: x ) = let { var bool: occ = element(idx1, idx2, idx3, arrayXd(x, [occurs(x_i) | x_i in x])); var float: d = element(idx1, idx2, idx3, arrayXd(x, [x_i default 0.0 | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2, \a idx3, \a idx4] */ function var opt float: element( var int: idx1, var int: idx2, var int: idx3, var int: idx4, array[int, int, int, int] of var opt float: x ) = let { var bool: occ = element(idx1, idx2, idx3, idx4, arrayXd(x, [occurs(x_i) | x_i in x])); var float: d = element(idx1, idx2, idx3, idx4, arrayXd(x, [x_i default 0.0 | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5] */ function var opt float: element( var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, array[int, int, int, int, int] of var opt float: x ) = let { var bool: occ = element(idx1, idx2, idx3, idx4, idx5, arrayXd(x, [occurs(x_i) | x_i in x])); var float: d = element(idx1, idx2, idx3, idx4, idx5, arrayXd(x, [x_i default 0.0 | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5, \a idx6] */ function var opt float: element( var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, var int: idx6, array[int, int, int, int, int, int] of var opt float: x ) = let { var bool: occ = element(idx1, idx2, idx3, idx4, idx5, idx6, arrayXd(x, [occurs(x_i) | x_i in x])); var float: d = element(idx1, idx2, idx3, idx4, idx5, idx6, arrayXd(x, [x_i default 0.0 | x_i in x])); } in if occ then d else <> endif; /* Return absent if \a idx is absent, otherwise return \a x[\a idx] */ function var opt float: element(var opt int: idx, array[int] of var opt float: x) = if length(x) > 0 /\ not had_zero(idx) /\ min(index_set(x)) = 1 then let { opt float: absent_value = <>; % Workaround since [<>] array literal not allowed } in element(deopt(idx), array1d(0..max(index_set(x)), [absent_value] ++ x)) else if absent(idx) then <> else element(deopt(idx), x) endif endif; /* Return absent if \a idx1 or \a idx2 is absent, otherwise return \a x[\a idx1, \a idx2]. Undefined if any non-absent index is out of bounds. */ function var opt float: element(var opt int: idx1, var opt int: idx2, array[int, int] of var opt float: x) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2); } in <> else let { any: i1 = idx1 default min(index_set_1of2(x)); any: i2 = idx2 default min(index_set_2of2(x)); any: xx = element(i1, i2, x); } in if absent(idx1) \/ absent(idx2) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3]. Undefined if any non-absent index is out of bounds. */ function var opt float: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, array[int, int, int] of var opt float: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3); } in <> else let { any: i1 = idx1 default min(index_set_1of3(x)); any: i2 = idx2 default min(index_set_2of3(x)); any: i3 = idx3 default min(index_set_3of3(x)); any: xx = element(i1, i2, i3, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4]. Undefined if any non-absent index is out of bounds. */ function var opt float: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, array[int, int, int, int] of var opt float: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4); } in <> else let { any: i1 = idx1 default min(index_set_1of4(x)); any: i2 = idx2 default min(index_set_2of4(x)); any: i3 = idx3 default min(index_set_3of4(x)); any: i4 = idx4 default min(index_set_4of4(x)); any: xx = element(i1, i2, i3, i4, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5]. Undefined if any non-absent index is out of bounds. */ function var opt float: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, var opt int: idx5, array[int, int, int, int, int] of var opt float: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4) /\ absent(idx5); } in <> else let { any: i1 = idx1 default min(index_set_1of5(x)); any: i2 = idx2 default min(index_set_2of5(x)); any: i3 = idx3 default min(index_set_3of5(x)); any: i4 = idx4 default min(index_set_4of5(x)); any: i5 = idx5 default min(index_set_5of5(x)); any: xx = element(i1, i2, i3, i4, i5, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) \/ absent(idx5) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5, \a idx6]. Undefined if any non-absent index is out of bounds. */ function var opt float: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, var opt int: idx5, var opt int: idx6, array[int, int, int, int, int, int] of var opt float: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4) /\ absent(idx5) /\ absent(idx6); } in <> else let { any: i1 = idx1 default min(index_set_1of6(x)); any: i2 = idx2 default min(index_set_2of6(x)); any: i3 = idx3 default min(index_set_3of6(x)); any: i4 = idx4 default min(index_set_4of6(x)); any: i5 = idx5 default min(index_set_5of6(x)); any: i6 = idx6 default min(index_set_6of6(x)); any: xx = element(i1, i2, i3, i4, i5, i6, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) \/ absent(idx5) \/ absent(idx6) then <> else xx endif endif; %%%%%%%%%%%%%%%%% % Element on sets function var set of int: element_t(var int: idx, array[int] of var set of int: x) :: promise_total = if length(x) = 0 then {} else let { var set of set_min_to_max(ub_array(x)): r ::is_defined_var; constraint idx in index_set(x); constraint array_var_set_element_nonshifted(idx,x,r) ::defines_var(r); } in r endif; function var set of int: element_mt(var int: idx, array[int] of var set of int: x) :: promise_total = let { var set of set_min_to_max(ub_array(x)): r ::is_defined_var; var index_set(x): idx2; constraint idx in index_set(x) -> idx2=idx; constraint idx in index_set(x) \/ idx2=min(index_set(x)); constraint array_var_set_element_nonshifted(idx2,x,r) ::defines_var(r); } in r; function var set of int: element_t(var int: idx1, var int: idx2, array[int,int] of var set of int: x) :: promise_total = if length(x) = 0 then {} else let { var set of set_min_to_max(ub_array(x)): r ::is_defined_var; constraint idx1 in index_set_1of2(x); constraint idx2 in index_set_2of2(x); constraint array_var_set_element2d_nonshifted(idx1,idx2,x,r) ::defines_var(r); } in r endif; function var set of int: element_mt(var int: idx1, var int: idx2, array[int,int] of var set of int: x) :: promise_total = let { var set of set_min_to_max(ub_array(x)): r ::is_defined_var; var index_set_1of2(x): idx1_2; var index_set_2of2(x): idx2_2; constraint (idx1 in index_set_1of2(x) /\ idx2 in index_set_2of2(x)) -> (idx1_2=idx1 /\ idx2_2=idx2); constraint (idx1 in index_set_1of2(x) /\ idx2 in index_set_2of2(x)) \/ (idx1_2=min(index_set_1of2(x)) /\ idx2_2=min(index_set_2of2(x))); constraint array_var_set_element2d_nonshifted(idx1_2,idx2_2,x,r) ::defines_var(r); } in r; function var set of int: element(var int: idx, array[int] of var set of int: x) = if length(x) = 0 \/ mzn_in_root_context(idx) then let { constraint idx in index_set(x) } in element_t(idx,x) elseif (has_bounds(idx) /\ lb(idx) >= min(index_set(x)) /\ ub(idx) <= max(index_set(x))) then element_t(idx,x) else let { constraint idx in index_set(x) } in element_mt(idx,x) endif; function var set of int: element(var int: idx1, var int: idx2, array[int,int] of var set of int: x) = let { int: dim = card(index_set_2of2(x)); } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of2(x); constraint idx2 in index_set_2of2(x); } in element_t(idx1,idx2,x) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of2(x)) /\ ub(idx1) <= max(index_set_1of2(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of2(x)) /\ ub(idx2) <= max(index_set_2of2(x))) ) then element_t(idx1,idx2,x) else let { constraint idx1 in index_set_1of2(x); constraint idx2 in index_set_2of2(x); } in element_mt(idx1,idx2,x) endif; function var set of int: element(var int: idx1, var int: idx2, var int: idx3, array[int,int,int] of var set of int: x) = let { int: dim2 = card(index_set_2of3(x)); int: dim3 = card(index_set_3of3(x)); int: min = min(index_set_1of3(x))*dim2*dim3+ min(index_set_2of3(x))*dim3+ min(index_set_3of3(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of3(x); constraint idx2 in index_set_2of3(x); constraint idx3 in index_set_3of3(x); } in element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of3(x)) /\ ub(idx1) <= max(index_set_1of3(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of3(x)) /\ ub(idx2) <= max(index_set_2of3(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of3(x)) /\ ub(idx3) <= max(index_set_3of3(x))) ) then element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of3(x); constraint idx2 in index_set_2of3(x); constraint idx3 in index_set_3of3(x); } in element_mt( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x)) endif; function var set of int: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, array[int,int,int,int] of var set of int: x) = let { int: dim2 = card(index_set_2of4(x)); int: dim3 = card(index_set_3of4(x)); int: dim4 = card(index_set_4of4(x)); int: min = min(index_set_1of4(x))*dim2*dim3*dim4+ min(index_set_2of4(x))*dim3*dim4+ min(index_set_3of4(x))*dim4+ min(index_set_4of4(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of4(x); constraint idx2 in index_set_2of4(x); constraint idx3 in index_set_3of4(x); constraint idx4 in index_set_4of4(x); } in element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of4(x)) /\ ub(idx1) <= max(index_set_1of4(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of4(x)) /\ ub(idx2) <= max(index_set_2of4(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of4(x)) /\ ub(idx3) <= max(index_set_3of4(x))) /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of4(x)) /\ ub(idx4) <= max(index_set_4of4(x))) ) then element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of4(x); constraint idx2 in index_set_2of4(x); constraint idx3 in index_set_3of4(x); constraint idx4 in index_set_4of4(x); } in element_mt( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x)) endif; function var set of int: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, array[int,int,int,int,int] of var set of int: x) = let { int: dim2 = card(index_set_2of5(x)); int: dim3 = card(index_set_3of5(x)); int: dim4 = card(index_set_4of5(x)); int: dim5 = card(index_set_5of5(x)); int: min = min(index_set_1of5(x))*dim2*dim3*dim4*dim5+ min(index_set_2of5(x))*dim3*dim4*dim5+ min(index_set_3of5(x))*dim4*dim5+ min(index_set_4of5(x))*dim5+ min(index_set_5of5(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of5(x); constraint idx2 in index_set_2of5(x); constraint idx3 in index_set_3of5(x); constraint idx4 in index_set_4of5(x); constraint idx5 in index_set_5of5(x); } in element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of5(x)) /\ ub(idx1) <= max(index_set_1of5(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of5(x)) /\ ub(idx2) <= max(index_set_2of5(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of5(x)) /\ ub(idx3) <= max(index_set_3of5(x))) /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of5(x)) /\ ub(idx4) <= max(index_set_4of5(x))) /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of5(x)) /\ ub(idx5) <= max(index_set_5of5(x))) ) then element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of5(x); constraint idx2 in index_set_2of5(x); constraint idx3 in index_set_3of5(x); constraint idx4 in index_set_4of5(x); constraint idx5 in index_set_5of5(x); } in element_mt( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x)) endif; function var set of int: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, var int: idx6, array[int,int,int,int,int,int] of var set of int: x) = let { int: dim2 = card(index_set_2of6(x)); int: dim3 = card(index_set_3of6(x)); int: dim4 = card(index_set_4of6(x)); int: dim5 = card(index_set_5of6(x)); int: dim6 = card(index_set_6of6(x)); int: min = min(index_set_1of6(x))*dim2*dim3*dim4*dim5*dim6+ min(index_set_2of6(x))*dim3*dim4*dim5*dim6+ min(index_set_3of6(x))*dim4*dim5*dim6+ min(index_set_4of6(x))*dim5*dim6+ min(index_set_5of6(x))*dim6+ min(index_set_6of6(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of6(x); constraint idx2 in index_set_2of6(x); constraint idx3 in index_set_3of6(x); constraint idx4 in index_set_4of6(x); constraint idx5 in index_set_5of6(x); constraint idx6 in index_set_6of6(x); } in element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of6(x)) /\ ub(idx1) <= max(index_set_1of6(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of6(x)) /\ ub(idx2) <= max(index_set_2of6(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of6(x)) /\ ub(idx3) <= max(index_set_3of6(x))) /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of6(x)) /\ ub(idx4) <= max(index_set_4of6(x))) /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of6(x)) /\ ub(idx5) <= max(index_set_5of6(x))) /\ (has_bounds(idx6) /\ lb(idx6) >= min(index_set_6of6(x)) /\ ub(idx6) <= max(index_set_6of6(x))) ) then element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of6(x); constraint idx2 in index_set_2of6(x); constraint idx3 in index_set_3of6(x); constraint idx4 in index_set_4of6(x); constraint idx5 in index_set_5of6(x); constraint idx6 in index_set_6of6(x); } in element_mt( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x)) endif; %%%%%%%%%%%%%%%%%% % Element on bools function var bool: element_t(var int: idx, array[int] of var bool: x) :: promise_total = let { var bool: r ::is_defined_var; constraint idx in index_set(x); constraint array_var_bool_element_nonshifted(idx,x,r) ::defines_var(r); } in r; function var bool: element_mt(var int: idx, array[int] of var bool: x) :: promise_total = let { var bool: r ::is_defined_var; var index_set(x): idx2; constraint idx in index_set(x) -> idx2=idx; constraint idx in index_set(x) \/ idx2=min(index_set(x)); constraint array_var_bool_element_nonshifted(idx2,x,r) ::defines_var(r); } in r; function var bool: element_t(var int: idx1, var int: idx2, array[int,int] of var bool: x) :: promise_total = let { var bool: r ::is_defined_var; constraint idx1 in index_set_1of2(x); constraint idx2 in index_set_2of2(x); constraint array_var_bool_element2d_nonshifted(idx1,idx2,x,r) ::defines_var(r); } in r; function var bool: element_mt(var int: idx1, var int: idx2, array[int,int] of var bool: x) :: promise_total = let { var bool: r ::is_defined_var; var index_set_1of2(x): idx1_2; var index_set_2of2(x): idx2_2; constraint (idx1 in index_set_1of2(x) /\ idx2 in index_set_2of2(x)) -> (idx1_2=idx1 /\ idx2_2=idx2); constraint (idx1 in index_set_1of2(x) /\ idx2 in index_set_2of2(x)) \/ (idx1_2=min(index_set_1of2(x)) /\ idx2_2=min(index_set_2of2(x))); constraint array_var_bool_element2d_nonshifted(idx1_2,idx2_2,x,r) ::defines_var(r); } in r; function var bool: element(var int: idx, array[int] of var bool: x) = length(x) > 0 /\ if mzn_in_root_context(idx) then idx in index_set(x) /\ element_t(idx,x) elseif (has_bounds(idx) /\ lb(idx) >= min(index_set(x)) /\ ub(idx) <= max(index_set(x))) then element_t(idx,x) else idx in index_set(x) /\ element_mt(idx,x) endif; function var bool: element(var int: idx1, var int: idx2, array[int,int] of var bool: x) = let { int: dim = card(index_set_2of2(x)); } in length(x) > 0 /\ if mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of2(x); constraint idx2 in index_set_2of2(x); } in element_t(idx1, idx2, x) elseif ((has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of2(x)) /\ ub(idx1) <= max(index_set_1of2(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of2(x)) /\ ub(idx2) <= max(index_set_2of2(x)))) then element_t(idx1,idx2,x) else let { constraint idx1 in index_set_1of2(x); constraint idx2 in index_set_2of2(x); } in element_mt(idx1,idx2,x) endif; function var bool: element(var int: idx1, var int: idx2, var int: idx3, array[int,int,int] of var bool: x) = length(x) > 0 /\ let { int: dim2 = card(index_set_2of3(x)); int: dim3 = card(index_set_3of3(x)); int: min = min(index_set_1of3(x))*dim2*dim3+ min(index_set_2of3(x))*dim3+ min(index_set_3of3(x))-1; } in if mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of3(x); constraint idx2 in index_set_2of3(x); constraint idx3 in index_set_3of3(x); } in element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of3(x)) /\ ub(idx1) <= max(index_set_1of3(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of3(x)) /\ ub(idx2) <= max(index_set_2of3(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of3(x)) /\ ub(idx3) <= max(index_set_3of3(x))) ) then element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of3(x); constraint idx2 in index_set_2of3(x); constraint idx3 in index_set_3of3(x); } in element_mt( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x)) endif; function var bool: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, array[int,int,int,int] of var bool: x) = length(x) > 0 /\ let { int: dim2 = card(index_set_2of4(x)); int: dim3 = card(index_set_3of4(x)); int: dim4 = card(index_set_4of4(x)); int: min = min(index_set_1of4(x))*dim2*dim3*dim4+ min(index_set_2of4(x))*dim3*dim4+ min(index_set_3of4(x))*dim4+ min(index_set_4of4(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of4(x); constraint idx2 in index_set_2of4(x); constraint idx3 in index_set_3of4(x); constraint idx4 in index_set_4of4(x); } in element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of4(x)) /\ ub(idx1) <= max(index_set_1of4(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of4(x)) /\ ub(idx2) <= max(index_set_2of4(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of4(x)) /\ ub(idx3) <= max(index_set_3of4(x))) /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of4(x)) /\ ub(idx4) <= max(index_set_4of4(x))) ) then element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of4(x); constraint idx2 in index_set_2of4(x); constraint idx3 in index_set_3of4(x); constraint idx4 in index_set_4of4(x); } in element_mt( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x)) endif; function var bool: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, array[int,int,int,int,int] of var bool: x) = length(x) > 0 /\ let { int: dim2 = card(index_set_2of5(x)); int: dim3 = card(index_set_3of5(x)); int: dim4 = card(index_set_4of5(x)); int: dim5 = card(index_set_5of5(x)); int: min = min(index_set_1of5(x))*dim2*dim3*dim4*dim5+ min(index_set_2of5(x))*dim3*dim4*dim5+ min(index_set_3of5(x))*dim4*dim5+ min(index_set_4of5(x))*dim5+ min(index_set_5of5(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of5(x); constraint idx2 in index_set_2of5(x); constraint idx3 in index_set_3of5(x); constraint idx4 in index_set_4of5(x); constraint idx5 in index_set_5of5(x); } in element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of5(x)) /\ ub(idx1) <= max(index_set_1of5(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of5(x)) /\ ub(idx2) <= max(index_set_2of5(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of5(x)) /\ ub(idx3) <= max(index_set_3of5(x))) /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of5(x)) /\ ub(idx4) <= max(index_set_4of5(x))) /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of5(x)) /\ ub(idx5) <= max(index_set_5of5(x))) ) then element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of5(x); constraint idx2 in index_set_2of5(x); constraint idx3 in index_set_3of5(x); constraint idx4 in index_set_4of5(x); constraint idx5 in index_set_5of5(x); } in element_mt( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x)) endif; function var bool: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, var int: idx6, array[int,int,int,int,int,int] of var bool: x) = length(x) > 0 /\ let { int: dim2 = card(index_set_2of6(x)); int: dim3 = card(index_set_3of6(x)); int: dim4 = card(index_set_4of6(x)); int: dim5 = card(index_set_5of6(x)); int: dim6 = card(index_set_6of6(x)); int: min = min(index_set_1of6(x))*dim2*dim3*dim4*dim5*dim6+ min(index_set_2of6(x))*dim3*dim4*dim5*dim6+ min(index_set_3of6(x))*dim4*dim5*dim6+ min(index_set_4of6(x))*dim5*dim6+ min(index_set_5of6(x))*dim6+ min(index_set_6of6(x))-1; } in if length(x) = 0 \/ mzn_in_root_context(idx1) then let { constraint idx1 in index_set_1of6(x); constraint idx2 in index_set_2of6(x); constraint idx3 in index_set_3of6(x); constraint idx4 in index_set_4of6(x); constraint idx5 in index_set_5of6(x); constraint idx6 in index_set_6of6(x); } in element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x)) elseif ( (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of6(x)) /\ ub(idx1) <= max(index_set_1of6(x))) /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of6(x)) /\ ub(idx2) <= max(index_set_2of6(x))) /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of6(x)) /\ ub(idx3) <= max(index_set_3of6(x))) /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of6(x)) /\ ub(idx4) <= max(index_set_4of6(x))) /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of6(x)) /\ ub(idx5) <= max(index_set_5of6(x))) /\ (has_bounds(idx6) /\ lb(idx6) >= min(index_set_6of6(x)) /\ ub(idx6) <= max(index_set_6of6(x))) ) then element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x)) else let { constraint idx1 in index_set_1of6(x); constraint idx2 in index_set_2of6(x); constraint idx3 in index_set_3of6(x); constraint idx4 in index_set_4of6(x); constraint idx5 in index_set_5of6(x); constraint idx6 in index_set_6of6(x); } in element_mt( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x)) endif; /* Return absent if \a idx is absent, otherwise return \a x[\a idx] */ function var opt bool: element(var opt int: idx, array[int] of var bool: x) = if absent(idx) then <> else element(deopt(idx),x) endif; /* Return absent if \a idx1 or \a idx2 is absent, otherwise return \a x[\a idx1, \a idx2]. Undefined if any non-absent index is out of bounds. */ function var opt bool: element(var opt int: idx1, var opt int: idx2, array[int, int] of var bool: x) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2); } in <> else let { any: i1 = idx1 default min(index_set_1of2(x)); any: i2 = idx2 default min(index_set_2of2(x)); any: xx = element(i1, i2, x); } in if absent(idx1) \/ absent(idx2) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2]. Undefined if any non-absent index is out of bounds. */ function var opt bool: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, array[int, int, int] of var bool: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3); } in <> else let { any: i1 = idx1 default min(index_set_1of3(x)); any: i2 = idx2 default min(index_set_2of3(x)); any: i3 = idx3 default min(index_set_3of3(x)); any: xx = element(i1, i2, i3, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4]. Undefined if any non-absent index is out of bounds. */ function var opt bool: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, array[int, int, int, int] of var bool: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4); } in <> else let { any: i1 = idx1 default min(index_set_1of4(x)); any: i2 = idx2 default min(index_set_2of4(x)); any: i3 = idx3 default min(index_set_3of4(x)); any: i4 = idx4 default min(index_set_4of4(x)); any: xx = element(i1, i2, i3, i4, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5]. Undefined if any non-absent index is out of bounds. */ function var opt bool: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, var opt int: idx5, array[int, int, int, int, int] of var bool: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4) /\ absent(idx5); } in <> else let { any: i1 = idx1 default min(index_set_1of5(x)); any: i2 = idx2 default min(index_set_2of5(x)); any: i3 = idx3 default min(index_set_3of5(x)); any: i4 = idx4 default min(index_set_4of5(x)); any: i5 = idx5 default min(index_set_5of5(x)); any: xx = element(i1, i2, i3, i4, i5, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) \/ absent(idx5) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5, \a idx6]. Undefined if any non-absent index is out of bounds. */ function var opt bool: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, var opt int: idx5, var opt int: idx6, array[int, int, int, int, int, int] of var bool: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4) /\ absent(idx5) /\ absent(idx6); } in <> else let { any: i1 = idx1 default min(index_set_1of6(x)); any: i2 = idx2 default min(index_set_2of6(x)); any: i3 = idx3 default min(index_set_3of6(x)); any: i4 = idx4 default min(index_set_4of6(x)); any: i5 = idx5 default min(index_set_5of6(x)); any: i6 = idx6 default min(index_set_6of6(x)); any: xx = element(i1, i2, i3, i4, i5, i6, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) \/ absent(idx5) \/ absent(idx6) then <> else xx endif endif; /* Return \a x[\a idx] */ function var opt bool: element(var int: idx, array[int] of var opt bool: x) = let { var bool: occ = element(idx, arrayXd(x, [occurs(x_i) | x_i in x])); var bool: d = element(idx, arrayXd(x, [x_i default false | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2] */ function var opt bool: element(var int: idx1, var int: idx2, array[int,int] of var opt bool: x) = let { var bool: occ = element(idx1, idx2, arrayXd(x, [occurs(x_i) | x_i in x])); var bool: d = element(idx1, idx2, arrayXd(x, [x_i default false | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2, \a idx3] */ function var opt bool: element( var int: idx1, var int: idx2, var int: idx3, array[int, int, int] of var opt bool: x ) = let { var bool: occ = element(idx1, idx2, idx3, arrayXd(x, [occurs(x_i) | x_i in x])); var bool: d = element(idx1, idx2, idx3, arrayXd(x, [x_i default false | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2, \a idx3, \a idx4] */ function var opt bool: element( var int: idx1, var int: idx2, var int: idx3, var int: idx4, array[int, int, int, int] of var opt bool: x ) = let { var bool: occ = element(idx1, idx2, idx3, idx4, arrayXd(x, [occurs(x_i) | x_i in x])); var bool: d = element(idx1, idx2, idx3, idx4, arrayXd(x, [x_i default false | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5] */ function var opt bool: element( var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, array[int, int, int, int, int] of var opt bool: x ) = let { var bool: occ = element(idx1, idx2, idx3, idx4, idx5, arrayXd(x, [occurs(x_i) | x_i in x])); var bool: d = element(idx1, idx2, idx3, idx4, idx5, arrayXd(x, [x_i default false | x_i in x])); } in if occ then d else <> endif; /* Return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5, \a idx6] */ function var opt bool: element( var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, var int: idx6, array[int, int, int, int, int, int] of var opt bool: x ) = let { var bool: occ = element(idx1, idx2, idx3, idx4, idx5, idx6, arrayXd(x, [occurs(x_i) | x_i in x])); var bool: d = element(idx1, idx2, idx3, idx4, idx5, idx6, arrayXd(x, [x_i default false | x_i in x])); } in if occ then d else <> endif; /* Return absent if \a idx is absent, otherwise return \a x[\a idx] */ function var opt bool: element(var opt int: idx, array[int] of var opt bool: x) = if length(x) > 0 /\ not had_zero(idx) /\ min(index_set(x)) = 1 then let { opt bool: absent_value = <>; % Workaround since [<>] array literal not allowed } in element(deopt(idx), array1d(0..max(index_set(x)), [absent_value] ++ x)) else if absent(idx) then <> else element(deopt(idx), x) endif endif; /* Return absent if \a idx1 or \a idx2 is absent, otherwise return \a x[\a idx1, \a idx2]. Undefined if any non-absent index is out of bounds. */ function var opt bool: element(var opt int: idx1, var opt int: idx2, array[int, int] of var opt bool: x) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2); } in <> else let { any: i1 = idx1 default min(index_set_1of2(x)); any: i2 = idx2 default min(index_set_2of2(x)); any: xx = element(i1, i2, x); } in if absent(idx1) \/ absent(idx2) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3]. Undefined if any non-absent index is out of bounds. */ function var opt bool: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, array[int, int, int] of var opt bool: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3); } in <> else let { any: i1 = idx1 default min(index_set_1of3(x)); any: i2 = idx2 default min(index_set_2of3(x)); any: i3 = idx3 default min(index_set_3of3(x)); any: xx = element(i1, i2, i3, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4]. Undefined if any non-absent index is out of bounds. */ function var opt bool: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, array[int, int, int, int] of var opt bool: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4); } in <> else let { any: i1 = idx1 default min(index_set_1of4(x)); any: i2 = idx2 default min(index_set_2of4(x)); any: i3 = idx3 default min(index_set_3of4(x)); any: i4 = idx4 default min(index_set_4of4(x)); any: xx = element(i1, i2, i3, i4, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5]. Undefined if any non-absent index is out of bounds. */ function var opt bool: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, var opt int: idx5, array[int, int, int, int, int] of var opt bool: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4) /\ absent(idx5); } in <> else let { any: i1 = idx1 default min(index_set_1of5(x)); any: i2 = idx2 default min(index_set_2of5(x)); any: i3 = idx3 default min(index_set_3of5(x)); any: i4 = idx4 default min(index_set_4of5(x)); any: i5 = idx5 default min(index_set_5of5(x)); any: xx = element(i1, i2, i3, i4, i5, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) \/ absent(idx5) then <> else xx endif endif; /* Return absent if any index is absent, otherwise return \a x[\a idx1, \a idx2, \a idx3, \a idx4, \a idx5, \a idx6]. Undefined if any non-absent index is out of bounds. */ function var opt bool: element( var opt int: idx1, var opt int: idx2, var opt int: idx3, var opt int: idx4, var opt int: idx5, var opt int: idx6, array[int, int, int, int, int, int] of var opt bool: x ) = if length(x) = 0 then let { constraint absent(idx1) /\ absent(idx2) /\ absent(idx3) /\ absent(idx4) /\ absent(idx5) /\ absent(idx6); } in <> else let { any: i1 = idx1 default min(index_set_1of6(x)); any: i2 = idx2 default min(index_set_2of6(x)); any: i3 = idx3 default min(index_set_3of6(x)); any: i4 = idx4 default min(index_set_4of6(x)); any: i5 = idx5 default min(index_set_5of6(x)); any: i6 = idx6 default min(index_set_6of6(x)); any: xx = element(i1, i2, i3, i4, i5, i6, x); } in if absent(idx1) \/ absent(idx2) \/ absent(idx3) \/ absent(idx4) \/ absent(idx5) \/ absent(idx6) then <> else xx endif endif; %-----------------------------------------------------------------------------% % % Internal functions for implementing div, mod etc function set of int: compute_div_bounds(var int: x, var int: y); function set of int: compute_mod_bounds(var int: x, var int: y); function set of float: compute_float_div_bounds(var float: x, var float: y); function set of int: compute_pow_bounds(var int: x, var int: y); function var int: div_t(var int: x, var int: y) :: promise_total = let { var (compute_div_bounds(x,y)): z ::is_defined_var; constraint y != 0; constraint int_div(x,y,z) ::defines_var(z); } in z; function var int: div_mt(var int: x, var int: y) :: promise_total = let { var ((dom(y) diff {0}) union {1}): yy = if y=0 then 1 else y endif; } in div_t(x,yy); function var float: fldiv_t(var float: x, float: y) :: promise_total = x*(1.0/y); function var float: fldiv_t(var float: x, var float: y) :: promise_total = let { var (compute_float_div_bounds(x,y)): z ::is_defined_var; constraint if lb(y) <= 0 /\ ub(y) >= 0 then y != 0.0 endif; constraint float_div(x, y, z) ::defines_var(z); } in z; function var float: fldiv_mt(var float: x, var float: y) :: promise_total = let { var (lb(y)..ub(y) diff {0.0}) union {1.0}: yy = if (y = 0.0) then 1.0 else y endif; } in fldiv_t(x, yy); function var int: mod_t(var int: x, var int: y) :: promise_total = let { var (compute_mod_bounds(x,y)): z; constraint y != 0; constraint int_mod(x,y,z); } in z; function var int: mod_mt(var int: x, var int: y) :: promise_total = let { var {1} union dom(y): yy = if y=0 then 1 else y endif; } in mod_t(x,yy); function var float: sqrt_t(var float: x) ::promise_total = let { float: sqrt_lb = if lb(x) < 0.0 then 0.0 else sqrt(lb(x)) endif; float: sqrt_ub = if ub(x) < 0.0 then 1.0 elseif ub(x) = infinity then infinity else sqrt(ub(x)) endif; var sqrt_lb..sqrt_ub: r; constraint float_sqrt(x,r); } in r; function var float: sqrt_mt(var float: x) ::promise_total = let { float: sqrt_lb = if lb(x) < 0.0 then 0.0 else sqrt(lb(x)) endif; float: sqrt_ub = if ub(x) < 0.0 then 1.0 elseif ub(x) = infinity then infinity else sqrt(ub(x)) endif; var sqrt_lb..sqrt_ub: r; var float: xx; constraint x < 0.0 -> xx = 1.0; constraint x < 0.0 \/ xx = x; constraint float_sqrt(xx,r); } in r; function var int: product_rec(array[int] of var int: x) = if length(x)=0 then 1 elseif length(x)=1 then x[min(index_set(x))] else let { array[int] of var int: xx = array1d(x); array[index_set(xx)] of var int: y; constraint y[1] = xx[1]; constraint forall (i in 2..length(y)) (y[i]=y[i-1]*xx[i]); } in y[length(y)] endif; function var float: product_rec(array[int] of var float: x) = if length(x)=0 then 1.0 elseif length(x)=1 then x[min(index_set(x))] else let { array[int] of var float: xx = array1d(x); array[index_set(xx)] of var float: y; constraint y[1] = xx[1]; constraint forall (i in 2..length(y)) (y[i]=y[i-1]*xx[i]); } in y[length(y)] endif; function var int: max_t(array[int] of var int: x) :: promise_total = if length(x)=0 then 0 elseif length(x)=1 then x[min(index_set(x))] elseif length(x)=2 then max(x[1],x[2]) else let { var lb_array(x)..ub_array(x): m ::is_defined_var; constraint array_int_maximum(m,x) ::defines_var(m); } in m endif; function var int: min_t(array[int] of var int: x) :: promise_total = if length(x)=0 then 0 elseif length(x)=1 then x[1] elseif length(x)=2 then min(x[1],x[2]) else let { var lb_array(x)..ub_array(x): m ::is_defined_var; constraint array_int_minimum(m,x) ::defines_var(m); } in m endif; function var float: max_t(array[int] of var float: x) :: promise_total = if length(x)=0 then 0.0 elseif length(x)=1 then x[min(index_set(x))] elseif length(x)=2 then max(x[1],x[2]) else let { var lb_array(x)..ub_array(x): m ::is_defined_var; constraint array_float_maximum(m,x) ::defines_var(m); } in m endif; function var float: min_t(array[int] of var float: x) :: promise_total = if length(x)=0 then 0.0 elseif length(x)=1 then x[1] elseif length(x)=2 then min(x[1],x[2]) else let { var lb_array(x)..ub_array(x): m ::is_defined_var; constraint array_float_minimum(m,x) ::defines_var(m); } in m endif; function var int: pow_fixed_t(var int: x, int: y) ::promise_total = let { constraint y < 0 -> x != 0; var compute_pow_bounds(x, y): r ::is_defined_var; constraint int_pow_fixed(x, y, r) ::defines_var(r); } in r; function var int: pow_fixed_mt(var int: x, int: y) ::promise_total = let { constraint assert(y < 0 /\ 0 in dom(x), "pow_fixed_mt called on variant guaranteed to be total"); var dom(x) diff {0} union {1}: nx = if x = 0 then 1 else x endif; } in pow_fixed_t(nx, y); function var int: pow_t(var int: x, var int: y) ::promise_total = let { constraint y < 0 -> x != 0; var compute_pow_bounds(x, y): r ::is_defined_var; constraint int_pow(x, y, r) ::defines_var(r); } in r; function var int: pow_mt(var int: x, var int: y) ::promise_total = let { constraint assert(lb(y) < 0 /\ 0 in dom(x), "pow_mt called on variant guaranteed to be total"); var dom(x) union {1}: nx = if x = 0 /\ y < 0 then 1 else x endif; } in pow_t(nx, y); /* These predicates are used to intercept symmetry_breaking_constraint and * redundant_constraint calls in user models, so that they can be ignored * if the corresponding options have been set. */ predicate mzn_symmetry_breaking_constraint(var bool: b); predicate mzn_redundant_constraint(var bool: b); /* Annotations used for bookkeeping by the compiler */ annotation mzn_was_undefined; /* Predicate used in the compiler for translating infinite domains into constraints */ predicate mzn_set_in_internal(var int: x, set of int: s) = if card(s) = 0 \/ (min(s) != -infinity /\ max(s) != infinity) then set_in(x,s) else let { array[int] of int: ranges_ = set_to_ranges(s); array[int,1..2] of int: ranges = array2d(1..length(ranges_) div 2,1..2,ranges_); } in exists(i in index_set_1of2(ranges)) ( if ranges[i,1] = -infinity then x <= ranges[i,2] elseif ranges[i,2] = infinity then x >= ranges[i,1] elseif ranges[i,1] = ranges[i,2] then x = ranges[i,1] else x in ranges[i,1]..ranges[i,2] endif ) endif; /* Predicate used in the compiler for translating infinite domains into constraints */ predicate mzn_set_in_internal(var opt float: x, set of float: s) = let { array[int] of float: ranges = set_to_ranges(s); int: len = length(ranges); int: from = if ranges[1] = -infinity then 3 else 1 endif; int: to = if ranges[len] = infinity then len-2 else len endif; } in if ranges[1] = -infinity then x <= ranges[2] else false endif \/ if from..to subset index_set(ranges) then float_dom(x, array1d(ranges[from..to])) else false endif \/ if ranges[len] = infinity then x >= ranges[len-1] else false endif; /* Functions used for the type erasure of enumerated types */ test mzn_set_is_contiguous(set of int: X) = card(X) = 0 \/ card(X)=(max(X)-min(X)+1); function int: mzn_min_or_0(set of int: X) = if card(X)=0 then 0 elseif mzn_set_is_contiguous(X) then min(X) else 1 endif; predicate lex_less_std_decomposition( array[int] of var $T: x ::promise_ctx_antitone, array[int] of var $T: y ::promise_ctx_monotone, ) ::promise_total = if length(y) = 0 then false elseif length(x) = 0 then true else let { int: lx = min(index_set(x)); int: ux = max(index_set(x)); int: ly = min(index_set(y)); int: uy = max(index_set(y)); int: size = min(ux - lx, uy - ly); array[0..size+1] of var bool: b; constraint b[size + 1] = (ux - lx < uy - ly); constraint forall(i in 0..size) ( b[i] = ( x[lx + i] <= y[ly + i] /\ (x[lx + i] < y[ly + i] \/ b[i+1]) ) ); } in b[0] endif; predicate lex_lesseq_std_decomposition( array[int] of var $T: x ::promise_ctx_antitone, array[int] of var $T: y ::promise_ctx_monotone, ) ::promise_total = if length(x) = 0 then true elseif length(y) = 0 then length(x) = 0 else let { int: lx = min(index_set(x)); int: ux = max(index_set(x)); int: ly = min(index_set(y)); int: uy = max(index_set(y)); int: size = min(ux - lx, uy - ly); % b[i] is true if the lexicographical order holds from position i on. array[0..size+1] of var bool: b; constraint b[size + 1] = (ux - lx <= uy - ly); constraint forall(i in 0..size) ( b[i] = ( x[lx + i] <= y[ly + i] /\ (x[lx + i] < y[ly + i] \/ b[i+1]) ) ); } in b[0] endif; set of int: set_min_to_max(set of int: x) = if x = {} then {1 | _ in 1..0} else min(x)..max(x) endif; /* Used to generate fresh values */ function int: mzn_increment_counter(string: key); libminizinc-2.8.2/share/minizinc/std/inverse_in_range.mzn0000644000175000017500000000112414536677021022260 0ustar kaolkaolinclude "fzn_inverse_in_range.mzn"; include "fzn_inverse_in_range_reif.mzn"; /** @group globals.channeling If the \a i th variable of the collection \a X is assigned to \a j and if \a j is in the index set of \a Y then the \a j th variable of the collection \a Y is assigned to \a i. Conversely, if the \a j th variable of the collection \a Y is assigned to \a i and if \a i is in the index set of \a X then the \a i th variable of the collection \a X is assigned to \a j. */ predicate inverse_in_range( array[$$A] of var $$B: X, array[$$B] of var $$A: Y, ) = fzn_inverse_in_range(X, Y); libminizinc-2.8.2/share/minizinc/std/fzn_var_sqr_sym.mzn0000644000175000017500000000151214536677021022166 0ustar kaolkaolinclude "fzn_var_perm_sym.mzn"; predicate fzn_var_sqr_sym(array[$$X, $$X] of var $$Y: x) = let { int: n = card(index_set_1of2(x)); int: l = n * n; array[1..l] of var int: y = [ x[i,j] | i in index_set_1of2(x), j in index_set_2of2(x) ]; array[1..8, 1..l] of 1..l: p = array2d(1..8, 1..l, [ if k == 1 then i*n + j - n elseif k == 2 then (n - j)*n + i % r270 elseif k == 3 then (n - i)*n + (n - j)+1 % r180 elseif k == 4 then (j*n - n) + (n - i + 1) % r90 elseif k == 5 then (n - i)*n + j % x flip elseif k == 6 then (i*n - n) + (n - j + 1) % y flip elseif k == 7 then (n - j)*n + (n - i + 1) % d2 flip else (j*n - n) + i % d1 flip endif | k in 1..8, i, j in 1..n] ); } in fzn_var_perm_sym(y, p); libminizinc-2.8.2/share/minizinc/std/at_most1.mzn0000644000175000017500000000052614536677021020477 0ustar kaolkaolinclude "fzn_at_most1.mzn"; include "fzn_at_most1_reif.mzn"; /** @group globals.counting Requires that each pair of sets in \a s overlap in at most one element. */ predicate at_most1(array[$X] of var set of int: s) = fzn_at_most1(array1d(s)); % Synonym for the above. predicate atmost1(array[$X] of var set of int: s) = at_most1(s); libminizinc-2.8.2/share/minizinc/std/fzn_dtree_enum_reif.mzn0000644000175000017500000000052514536677021022760 0ustar kaolkaolpredicate fzn_dtree_reif(array[int] of $$N: from, array[int] of $$N: to, var $$N: r, array[$$N] of var bool: ns, array[int] of var bool: es, var bool: b) = abort("Reified dtree constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_count_leq_par_reif.mzn0000644000175000017500000000035514536677021023465 0ustar kaolkaolinclude "fzn_count_leq_reif.mzn"; predicate fzn_count_leq_par_reif(array[int] of var int: x, int: y, int: c, var bool: b) = fzn_count_leq_reif(x,y,c,b); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/lex_lesseq_set.mzn0000644000175000017500000000136214536677021021766 0ustar kaolkaolinclude "fzn_lex_lesseq_set.mzn"; include "fzn_lex_lesseq_set_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that the array 'x' is lexicographically less than or equal to % array 'y'. Compares them from first to last element, regardless of indices %-----------------------------------------------------------------------------% predicate lex_lesseq_set(array[int] of var set of int: x, array[int] of var set of int: y) = fzn_lex_lesseq_set(x, y); predicate lex_leq_set(array[int] of var set of int: x, array[int] of var set of int: y) = lex_lesseq_set(x, y); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/fzn_arg_max_int.mzn0000644000175000017500000000073514536677021022117 0ustar kaolkaolpredicate fzn_maximum_arg_int(array[int] of var int: x, var int: z) = % general case: min could be 0 or 1 let { int: l = min(index_set(x)) ; int: u = max(index_set(x)) ; int: n = u-l+1; array[int] of var int: xs = array1d(l..u,[ n*x[j]+(u-j) | j in l..u ]); var int: Mx = max(xs) ; } in forall (j in l..u) ( (z != j) = (Mx > xs[j]) ); %%% only the new decomposition from argmax paper CP2020 submission libminizinc-2.8.2/share/minizinc/std/fzn_lex_chain_less_bool_reif.mzn0000644000175000017500000000045214536677021024623 0ustar kaolkaolinclude "lex_less.mzn"; predicate fzn_lex_chain_less_bool_reif( array[int, int] of var bool: a, var bool: b) = let { set of int: is2 = index_set_2of2(a); } in b <-> ( forall(j in is2 where j+1 in is2) ( lex_less(col(a, j), col(a, j+1)) ) ); libminizinc-2.8.2/share/minizinc/std/fzn_sum_set_reif.mzn0000644000175000017500000000031714536677021022307 0ustar kaolkaolpredicate fzn_sum_set_reif(array[int] of int: vs, array[int] of int: ws, var set of int: x, var int: s, var bool: b) = b <-> s == sum(j in index_set(vs)) ( (j in x) * ws[j] ); libminizinc-2.8.2/share/minizinc/std/fzn_lex2.mzn0000644000175000017500000000046714536677021020503 0ustar kaolkaolinclude "lex_chain_lesseq.mzn"; predicate fzn_lex2(array[int, int] of var int: x) = lex_chain_lesseq(x) /\ lex_chain_lesseq( %% transpose array2d(index_set_2of2(x), index_set_1of2(x), [x[i, j] | j in index_set_2of2(x), i in index_set_1of2(x)] ) ); libminizinc-2.8.2/share/minizinc/std/fzn_global_cardinality_low_up_reif.mzn0000644000175000017500000000071614536677021026043 0ustar kaolkaolinclude "count_fn.mzn"; predicate fzn_global_cardinality_low_up_reif(array[int] of var int: x, array[int] of int: cover, array[int] of int: lbound, array[int] of int: ubound, var bool: b) = b <-> forall(i in index_set(cover))( count(x, cover[i]) in lbound[i]..ubound[i] ); libminizinc-2.8.2/share/minizinc/std/fzn_dpath_enum_reif.mzn0000644000175000017500000000051214536677021022751 0ustar kaolkaolpredicate fzn_dpath_reif(array[int] of $$N: from, array[int] of $$N: to, var $$N: s, var $$N: t, array[$$N] of var bool: ns, array[int] of var bool: es, var bool: b) = abort("Reified dpath constraint is not supported"); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/distribute_fn.mzn0000644000175000017500000000112014536677021021600 0ustar kaolkaolinclude "distribute.mzn"; /** @group globals.counting Returns an array of the number of occurrences of \a value[\p i] in \a base. The values in \a value need not be distinct. */ function array[$X] of var int: distribute(array[$X] of var int: value, array[$Y] of var int: base) :: promise_total = let { array[int] of var int: value1d = array1d(value); array[index_set(value1d)] of var 0..length(base): card ::is_defined_var; constraint distribute(card, value1d, array1d(base)) ::defines_var(card); } in arrayXd(value,card); libminizinc-2.8.2/share/minizinc/std/fzn_if_then_else_float.mzn0000644000175000017500000000056214536677021023436 0ustar kaolkaolpredicate fzn_if_then_else_float(array[int] of var bool: c, array[int] of float: x, var float: y) = let { array[index_set(c)] of var bool: d; } in forall(i in index_set(c)) (if i > min(index_set(c)) then d[i] = (not c[i-1] /\ d[i-1]) else d[i] = true endif) /\ forall (i in index_set(c)) (c[i] /\ d[i] -> y=x[i]); libminizinc-2.8.2/share/minizinc/std/exactly_int.mzn0000644000175000017500000000061114536677021021266 0ustar kaolkaolinclude "fzn_exactly_int.mzn"; include "fzn_exactly_int_reif.mzn"; %-----------------------------------------------------------------------------% % Requires exactly 'n' variables in 'x' to take the value 'v'. %-----------------------------------------------------------------------------% predicate exactly_int(int: n, array[$X] of var $$E: x, $$E: v) = fzn_exactly_int(n, array1d(x), v); libminizinc-2.8.2/share/minizinc/std/fzn_array_opt_int_union.mzn0000644000175000017500000000107614536677021023710 0ustar kaolkaol/* Constrain y to be the set of the non-absent elements in x */ predicate fzn_array_opt_int_union(array[int] of var opt int: x, var set of int: y) = if length(x) = 0 then y = {} elseif length(x) = 1 then (card(y) = occurs(x[min(index_set(x))])) /\ (occurs(x[min(index_set(x))]) -> (deopt(x[min(index_set(x))]) in y)) else y = array_union([let { var set of dom(x[i]): s; constraint if occurs(x[i]) then deopt(x[i]) in s /\ card(s)=1 else card(s)=0 endif; } in s | i in index_set(x)]) endif; libminizinc-2.8.2/share/minizinc/std/fzn_count_leq_par.mzn0000644000175000017500000000031714536677021022456 0ustar kaolkaolinclude "fzn_count_leq.mzn"; predicate fzn_count_leq_par(array[int] of var int: x, int: y, int: c) = fzn_count_leq(x,y,c); %-----------------------------------------------------------------------------% libminizinc-2.8.2/share/minizinc/std/set_member.mzn0000644000175000017500000000054714536677021021075 0ustar kaolkaolinclude "fzn_set_member.mzn"; include "fzn_set_member_reif.mzn"; %-----------------------------------------------------------------------------% % Requires that 'y' occurs in the array or set 'x'. %-----------------------------------------------------------------------------% predicate set_member(var set of $$E: x, var $$E: y) = fzn_set_member(x, y); libminizinc-2.8.2/share/minizinc/std/fzn_strictly_increasing_int_reif.mzn0000644000175000017500000000060114536677021025555 0ustar kaolkaol%-----------------------------------------------------------------------------% % Requires that the array 'x' is in strict increasing order %-----------------------------------------------------------------------------% predicate fzn_strictly_increasing_int_reif(array[int] of var int: x, var bool: b) = b <-> forall(i in index_set(x) diff { min(index_set(x)) }) (x[i-1] < x[i]); libminizinc-2.8.2/share/minizinc/std/fzn_table_int_opt.mzn0000644000175000017500000000123114536677021022442 0ustar kaolkaolpredicate fzn_table_int_opt(array[int] of var opt int: x, array[int, int] of opt int: t) = let { int: l = min(index_set(x)), int: u = max(index_set(x)), int: lt = min(index_set_1of2(t)), int: ut = max(index_set_1of2(t)), var lt..ut: i, array[l..u, lt..ut] of opt int: t_transposed = array2d(l..u, lt..ut, [ t[k,j] | j in l..u, k in lt..ut ]) } in forall(j in l..u) ( % Having the variable index component at the left position % means that the nD-to-1D array translation during Mzn-to-Fzn % will generate at most an offset constraint, instead of a % scaling + offset constraint. t_transposed[j,i] ~= x[j] ); libminizinc-2.8.2/share/minizinc/std/fzn_all_equal_set.mzn0000644000175000017500000000052214536677021022433 0ustar kaolkaol%-----------------------------------------------------------------------------% % Constrains the array of objects 'x' to be all equal. %-----------------------------------------------------------------------------% predicate fzn_all_equal_set(array[int] of var set of int: x) = forall(i, j in index_set(x) where i < j) ( x[i] = x[j] ); libminizinc-2.8.2/share/minizinc/std/member_bool.mzn.deprecated.mzn0000644000175000017500000000023514536677021024131 0ustar kaolkaolpredicate member_bool(array[int] of var bool: x, var bool: y) ::mzn_deprecated("2.6.0","https://www.minizinc.org/doc-2.6.0/en/lib-globals.html#deprecated"); libminizinc-2.8.2/share/minizinc/std/maximum.mzn0000644000175000017500000000062514536677021020425 0ustar kaolkaol/** @group globals.math Constrains \a m to be the maximum of the values in \a x. Assumptions: |\a x| > 0. */ predicate maximum(var $$E: m, array[int] of var $$E: x) = array_int_maximum(m, x); /** @group globals.math Constrains \a m to be the maximum of the values in \a x. Assumptions: |\a x| > 0. */ predicate maximum(var float: m, array[int] of var float: x) = array_float_maximum(m, x); libminizinc-2.8.2/share/minizinc/Preferences.json0000644000175000017500000000105414536677021020561 0ustar kaolkaol{ "tagDefaults": [ ["", "org.gecode.gecode"] ], "solverDefaults" : [ ["org.minizinc.mip.gurobi", "-DQuadrIntSolverConfig=true", ""], ["org.minizinc.mip.gurobi", "-DQuadrFloatSolverConfig=true", ""], ["org.minizinc.mip.scip", "-DQuadrIntSolverConfig=true", ""], ["org.minizinc.mip.scip", "-DQuadrFloatSolverConfig=true", ""], ["org.minizinc.mip.scip", "-DCumulativeSolverConfig=true", ""], ["org.minizinc.mip.scip", "-DOrbisackSolverConfig=true", ""], ["org.minizinc.mip.scip", "-DOrbitopeSolverConfig=true", ""] ] } libminizinc-2.8.2/share/minizinc/gecode_presolver/0000755000175000017500000000000014536677021020754 5ustar kaolkaollibminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_global_cardinality_low_up_closed.mzn0000644000175000017500000000325114536677021031121 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2011-05-19 04:08:39 +1000 (Thu, 19 May 2011) $ by $Author: tack $ % $Revision: 12007 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_global_cardinality_low_up_closed(array[int] of var int: x, array[int] of int: cover, array[int] of int: lbound, array[int] of int: ubound); libminizinc-2.8.2/share/minizinc/gecode_presolver/gecode.mzn0000644000175000017500000001712214536677021022733 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2015-01-05 17:33:06 +1100 (Mon, 05 Jan 2015) $ by $Author: tack $ % $Revision: 14337 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % /*** @groupdef gecode Additional declarations for Gecode These annotations and predicates are available for the Gecode solver. In order to use them in a model, include the file "gecode.mzn". */ /*** @groupdef gecode.annotations Additional Gecode search annotations */ /** @group gecode.annotations Select variable with smallest accumulated failure count */ annotation afc_min; /** @group gecode.annotations Select variable with smallest accumulated failure count divided by domain size */ annotation afc_size_min; /** @group gecode.annotations Select variable with largest accumulated failure count */ annotation afc_max; /** @group gecode.annotations Select variable with largest accumulated failure count divided by domain size */ annotation afc_size_max; /** @group gecode.annotations Select variable with smallest activity count */ annotation activity_min; /** @group gecode.annotations Select variable with smallest activity count divided by domain size */ annotation activity_size_min; /** @group gecode.annotations Select variable with largest activity count */ annotation activity_max; /** @group gecode.annotations Select variable with largest activity count divided by domain size */ annotation activity_size_max; /** @group gecode.annotations Select random variable */ annotation random; /** @group gecode.annotations Specify default search strategy for integer variables to use variable selection strategy \a varsel, and value choice strategy \a valsel. */ annotation int_default_search(ann: varsel, ann: valsel); /** @group gecode.annotations Specify default search strategy for Boolean variables to use variable selection strategy \a varsel, and value choice strategy \a valsel. */ annotation bool_default_search(ann: varsel, ann: valsel); /** @group gecode.annotations Specify default search strategy for set variables to use variable selection strategy \a varsel, and value choice strategy \a valsel. */ annotation set_default_search(ann: varsel, ann: valsel); /** @group gecode.annotations Specify default search strategy for float variables to use variable selection strategy \a varsel, and value choice strategy \a valsel. */ annotation float_default_search(ann: varsel, ann: valsel); /** @group gecode.annotations Simple large neighbourhood search strategy: upon restart, for each variable in \a x, the probability of it being fixed to the previous solution is \a percentage (out of 100). */ annotation relax_and_reconstruct(array[int] of var int: x, int: percentage); /** @group gecode.annotations Simple large neighbourhood search strategy: upon restart, for each variable in \a x, the probability of it being fixed to the previous solution is \a percentage (out of 100). Start from an initial solution \a y. */ annotation relax_and_reconstruct(array[int] of var int: x, int: percentage, array[int] of int: y); /*** @groupdef gecode.constraints Additional Gecode constraints */ /** @group gecode.constraints Constrain \a z to be the intersection of all sets in \a y that are selected by \a x: \(i \in \a z \leftrightarrow \forall j \in \a x: (i \in \a y[j]) \) */ predicate gecode_array_set_element_intersect(var set of int: x, array[int] of var set of int: y, var set of int: z); /** @group gecode.constraints Constrain \a z to be the disjoint union of all sets in \a y that are selected by \a x: \(i \in \a z \leftrightarrow \exists j \in \a x: (i \in \a y[j]) \) and \( i \in \a x \land j \in \a x \land i\neq j \rightarrow \a y[i] \cap \a y[j]=\emptyset \) */ predicate gecode_array_set_element_partition(var set of int: x, array[int] of var set of int: y, var set of int: z); /** @group gecode.constraints Constrain \a z to be a subset of \a u, and \a z to be the intersection of all sets in \a y that are selected by \a x: \(i \in \a z \leftrightarrow \forall j \in \a x: (i \in \a y[j]) \) */ predicate gecode_array_set_element_intersect_in(var set of int: x, array[int] of var set of int: y, var set of int: z, set of int: u); predicate gecode_among_seq_int(array[int] of var int: x, set of int: S, int: l, int: m, int: n); predicate gecode_among_seq_bool(array[int] of var bool: x, bool: b, int: l, int: m, int: n); /** @group gecode.constraints Every subsequence of \a x of length \a l has at least \a m and at most \a n occurrences of the values in \a S */ predicate among_seq(array[int] of var int: x, set of int: S, int: l, int: m, int: n) = gecode_among_seq_int(x,S,l,m,n); /** @group gecode.constraints Every subsequence of \a x of length \a l has at least \a m and at most \a n occurrences of the value \a b */ predicate among_seq(array[int] of var bool: x, bool: b, int: l, int: m, int: n) = gecode_among_seq_bool(x,b,l,m,n); predicate gecode_circuit_cost_array(array[int] of int: c, array[int] of var int: x, array[int] of var int: y, var int: z); predicate gecode_circuit_cost(array[int] of int: c, array[int] of var int: x, var int: z); /** @group gecode.constraints Constrains the elements of \a x to define a circuit where \a x[\p i] = \p j means that \p j is the successor of \p i. Additionally, constrain \a z to be the cost of the circuit. Each edge cost is defined by array \a c. The variables \a y[i] are constrained to be the edge cost of the node \a x[i]. */ predicate circuit_cost_array(array[int] of int: c, array[int] of var int: x, array[int] of var int: y, var int: z) = gecode_circuit_cost_array(c,[x[i]-min(index_set(x)) | i in index_set(x)], y,z); /** @group gecode.constraints Constrains the elements of \a x to define a circuit where \a x[\p i] = \p j means that \p j is the successor of \p i. Additionally, constrain \a z to be the cost of the circuit. Each edge cost is defined by array \a c. */ predicate circuit_cost(array[int] of int: c, array[int] of var int: x, var int: z) = gecode_circuit_cost(c, [x[i]-min(index_set(x)) | i in index_set(x)], z); predicate gecode_schedule_unary(array[int] of var int: x, array[int] of int: p); predicate gecode_schedule_unary_optional(array[int] of var int: x, array[int] of int: p, array[int] of var bool: m); predicate gecode_schedule_cumulative_optional(array[int] of var int: start, array[int] of int: duration, array[int] of int: usage, array[int] of var bool: m, int: capacity); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_decreasing_int.mzn0000644000175000017500000000267214536677021025344 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2010-03-31 19:18:34 +1100 (Wed, 31 Mar 2010) $ by $Author: tack $ % $Revision: 10618 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_decreasing_int(array[int] of var int: x); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_at_least_int.mzn0000644000175000017500000000271214536677021025027 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_at_least_int(int: n, array[int] of var int: x, int: v); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_member_bool.mzn0000644000175000017500000000270514536677021024645 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-03-19 11:56:37 +1100 (Mon, 19 Mar 2012) $ by $Author: tack $ % $Revision: 12583 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_member_bool(array[int] of var bool: x, var bool: y); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_lex_lesseq_bool.mzn0000644000175000017500000000321314536677021025535 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-04-11 14:59:27 +1000 (Wed, 11 Apr 2012) $ by $Author: tack $ % $Revision: 12730 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_array_bool_lq(array[int] of var bool: x, array[int] of var bool: y); predicate fzn_lex_lesseq_bool(array[int] of var bool: x, array[int] of var bool: y) = gecode_array_bool_lq(x,y); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_distribute.mzn0000644000175000017500000000350314536677021024536 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2011-05-19 04:08:39 +1000 (Thu, 19 May 2011) $ by $Author: tack $ % $Revision: 12007 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_distribute(array[int] of var int: card, array[int] of var int: value, array[int] of var int: base) = assert(index_set(card) == index_set(value), "distribute: card and value arrays must have identical index sets", forall (i in index_set(card)) ( bool_sum_eq([value[i] == base[j] | j in index_set(base)], card[i]) ) ); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_disjoint.mzn0000644000175000017500000000270414536677021024205 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_disjoint(var set of int: s1, var set of int: s2); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_cumulatives.mzn0000644000175000017500000000156414536677021024726 0ustar kaolkaolinclude "fzn_cumulatives_decomp.mzn"; predicate fzn_cumulatives(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, array[int] of var int: m, array[int] of var int: b, bool: upper, int: min_m) = if is_fixed(b) then % Propagator only supports fixed bounds gecode_cumulatives(s, d, r, [m_i - min_m | m_i in m], fix(b), upper) else fzn_cumulatives_decomp(s, d, r, m, b, upper) endif; predicate gecode_cumulatives(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, array[int] of var int: m, array[int] of int: b, bool: upper); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_link_set_to_booleans.mzn0000644000175000017500000000331514536677021026555 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-03-19 11:56:37 +1100 (Mon, 19 Mar 2012) $ by $Author: tack $ % $Revision: 12583 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_link_set_to_booleans(var set of int: s, array[int] of var bool: b, int: idx); predicate fzn_link_set_to_booleans(var set of int: s, array[int] of var bool: b) = if min(index_set(b)) < 0 then forall(i in index_set(b)) ( b[i] <-> i in s ) else gecode_link_set_to_booleans(s,b,min(index_set(b))) endif libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_increasing_bool.mzn0000644000175000017500000000267614536677021025527 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_increasing_bool(array[int] of var bool: x); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_global_cardinality_closed.mzn0000644000175000017500000000311614536677021027534 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2011-01-14 08:42:12 +1100 (Fri, 14 Jan 2011) $ by $Author: tack $ % $Revision: 11531 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_global_cardinality_closed(array[int] of var int: x, array[int] of int: cover, array[int] of var int: counts); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_value_precede_set.mzn0000644000175000017500000000310514536677021026034 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2013-07-19 22:10:52 +1000 (Fri, 19 Jul 2013) $ by $Author: schulte $ % $Revision: 13911 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_precede_set(array[int] of var set of int: x, int: s, int: t); predicate fzn_value_precede_set(int: s, int: t, array[int] of var set of int: x) = gecode_precede_set(x,s,t); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_table_int.mzn0000644000175000017500000000307414536677021024324 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_table_int(array[int] of var int: x, array[int, int] of int: t) = fzn_table_int(x, array1d(t)); predicate fzn_table_int(array[int] of var int: x, array[int] of int: t); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_count_eq_reif.mzn0000644000175000017500000000322514536677021025203 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-08-14 10:15:14 +1000 (Tue, 14 Aug 2012) $ by $Author: tack $ % $Revision: 12979 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_count_reif(array[int] of var int: x, var int: y, var int: c, var bool: b); predicate fzn_count_eq_reif(array[int] of var int: x, var int: y, var int: c, var bool: b) = gecode_count_reif(x, y, c, b); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_exactly_set.mzn0000644000175000017500000000301514536677021024702 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_exactly_set(int: n, array[int] of var set of int: x, set of int: v) = bool_sum_eq([x[i] == v | i in index_set(x)], n); libminizinc-2.8.2/share/minizinc/gecode_presolver/redefinitions.mzn0000644000175000017500000000604614536677021024352 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-04-06 16:43:44 +1000 (Fri, 06 Apr 2012) $ by $Author: tack $ % $Revision: 12706 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % % Sums over Boolean variables predicate bool_lin_eq(array[int] of int: a, array[int] of var bool: x, var int: c); predicate bool_lin_ne(array[int] of int: a, array[int] of var bool: x, var int: c); predicate bool_lin_le(array[int] of int: a, array[int] of var bool: x, var int: c); predicate bool_lin_lt(array[int] of int: a, array[int] of var bool: x, var int: c); predicate bool_lin_ge(array[int] of int: a, array[int] of var bool: x, var int: c); predicate bool_lin_gt(array[int] of int: a, array[int] of var bool: x, var int: c); predicate bool_sum_eq(array[int] of var bool: x, var int: c) = bool_lin_eq([1 | i in index_set(x)],x,c); predicate bool_sum_ne(array[int] of var bool: x, var int: c) = bool_lin_ne([1 | i in index_set(x)],x,c); predicate bool_sum_le(array[int] of var bool: x, var int: c) = bool_lin_le([1 | i in index_set(x)],x,c); predicate bool_sum_lt(array[int] of var bool: x, var int: c) = bool_lin_lt([1 | i in index_set(x)],x,c); predicate bool_sum_ge(array[int] of var bool: x, var int: c) = bool_lin_ge([1 | i in index_set(x)],x,c); predicate bool_sum_gt(array[int] of var bool: x, var int: c) = bool_lin_gt([1 | i in index_set(x)],x,c); predicate float_sinh(var float: a, var float: b) = b == (exp(a)-exp(-a))/2.0; predicate float_cosh(var float: a, var float: b) = b == (exp(a)+exp(-a))/2.0; predicate float_tanh(var float: a, var float: b) = let { var float: e2a = exp(2.0*a) } in b == (e2a-1.0)/(e2a+1.0); predicate float_ne_reif(var float: a, var float: b, var bool: c) = not c <-> a==b; libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_int_set_channel.mzn0000644000175000017500000000377114536677021025524 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-03-19 11:56:37 +1100 (Mon, 19 Mar 2012) $ by $Author: tack $ % $Revision: 12583 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_int_set_channel(array[int] of var int: x, int: xoff, array[int] of var set of int: y, int: yoff); predicate fzn_int_set_channel(array[int] of var int: x, array[int] of var set of int: y) = if (min(index_set(x)) < 0 \/ min(index_set(y)) < 0) then forall(i in index_set(x)) (x[i] in index_set(y)) /\ forall(j in index_set(y)) (y[j] subset index_set(x)) /\ forall(i in index_set(x), j in index_set(y)) (x[i]=j <-> i in y[j]) else gecode_int_set_channel(x,min(index_set(x)),y,min(index_set(y))) endif; libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_all_equal_int.mzn0000644000175000017500000000267114536677021025176 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2010-03-31 19:18:34 +1100 (Wed, 31 Mar 2010) $ by $Author: tack $ % $Revision: 10618 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_all_equal_int(array[int] of var int: x); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_among.mzn0000644000175000017500000000271414536677021023464 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2011-08-22 05:22:06 +1000 (Mon, 22 Aug 2011) $ by $Author: tack $ % $Revision: 12325 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_among(var int: n, array[int] of var int: x, set of int: v); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_lex_lesseq_int.mzn0000644000175000017500000000320414536677021025374 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_array_int_lq(array[int] of var int: x, array[int] of var int: y); predicate fzn_lex_lesseq_int(array[int] of var int: x, array[int] of var int: y) = gecode_array_int_lq(x,y); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_bin_packing.mzn0000644000175000017500000000331714536677021024627 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2010 % % Last modified: % $Date: 2013-07-19 10:50:31 +1000 (Fri, 19 Jul 2013) $ by $Author: tack $ % $Revision: 13902 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % include "bin_packing_capa.mzn"; predicate fzn_bin_packing(int: c, array[int] of var int: bin, array[int] of int: w) = let { set of int: idx = lb_array(bin)..ub_array(bin), array[idx] of int: capa = array1d(idx, [c|i in idx]) } in bin_packing_capa(capa,bin,w); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_sum_pred.mzn0000644000175000017500000000325214536677021024177 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-03-19 11:56:37 +1100 (Mon, 19 Mar 2012) $ by $Author: tack $ % $Revision: 12583 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_set_weights(array[int] of int: csi,array[int] of int: cs, var set of int: x, var int: y); predicate fzn_sum_pred(var int: i, array[int] of set of int: sets, array[int] of int: cs, var int: s) = gecode_set_weights([j|j in index_set(cs)],cs,sets[i],s); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_count_eq.mzn0000644000175000017500000000306114536677021024174 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-08-14 10:15:14 +1000 (Tue, 14 Aug 2012) $ by $Author: tack $ % $Revision: 12979 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_count(array[int] of var int: x, var int: y, var int: c); predicate fzn_count_eq(array[int] of var int: x, var int: y, var int: c) = gecode_count(x, y, c); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_bin_packing_capa.mzn0000644000175000017500000000340214536677021025606 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2010 % % Last modified: % $Date: 2013-07-19 10:50:31 +1000 (Fri, 19 Jul 2013) $ by $Author: tack $ % $Revision: 13902 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % include "bin_packing_load.mzn"; predicate fzn_bin_packing_capa(array[int] of int: c, array[int] of var int: bin, array[int] of int: w) = let { array[min(index_set(c))..max(index_set(c))] of var 0..ub_array(c): l } in ( forall( i in index_set(l) ) ( l[i] <= c[i] ) /\ bin_packing_load(l,bin,w) ); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_lex_less_int.mzn0000644000175000017500000000320014536677021025042 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_array_int_lt(array[int] of var int: x, array[int] of var int: y); predicate fzn_lex_less_int(array[int] of var int: x, array[int] of var int: y) = gecode_array_int_lt(x,y); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_partition_set.mzn0000644000175000017500000000324514536677021025247 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_array_set_partition(array[int] of var set of int: S, set of int: universe); predicate fzn_partition_set(array[int] of var set of int: S, set of int: universe) = gecode_array_set_partition(S, universe); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_member_bool_reif.mzn0000644000175000017500000000321514536677021025647 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-03-19 11:56:37 +1100 (Mon, 19 Mar 2012) $ by $Author: tack $ % $Revision: 12583 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_member_bool_reif(array[int] of var bool: x, var bool: y, var bool: b); predicate fzn_member_bool_reif(array[int] of var bool: x, var bool: y, var bool: b) = gecode_member_bool_reif(x,y,b); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_all_different_int.mzn0000644000175000017500000000363014536677021026031 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_all_different_int(array[int] of var int: x); %predicate all_different_int(array[int] of var int: x) = gecode_all_different_int(x); predicate fzn_all_different_int(array[int] of var int: xs) = let { set of int: cs = {fix(x) | x in xs where is_fixed(x)}; array[int] of var int: ys = [x | x in xs where not is_fixed(x)]; constraint forall(y in ys, c in cs) (y != c); } in if length(ys) <= 1 then true elseif length(ys) == 2 then ys[1] != ys[2] else gecode_all_different_int(ys) endif; libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_lex_less_bool.mzn0000644000175000017500000000317414536677021025215 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-04-11 14:59:27 +1000 (Wed, 11 Apr 2012) $ by $Author: tack $ % $Revision: 12730 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_array_bool_lt(array[int] of var bool: x, array[int] of var bool: y); predicate fzn_lex_less_bool(array[int] of var bool: x, array[int] of var bool: y) = gecode_array_bool_lt(x,y); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_at_most_int.mzn0000644000175000017500000000271114536677021024700 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_at_most_int(int: n, array[int] of var int: x, int: v); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_decreasing_bool.mzn0000644000175000017500000000267414536677021025507 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2011-05-19 04:08:39 +1000 (Thu, 19 May 2011) $ by $Author: tack $ % $Revision: 12007 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_decreasing_bool(array[int] of var bool: x); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_member_int_reif.mzn0000644000175000017500000000321014536677021025501 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-03-19 11:56:37 +1100 (Mon, 19 Mar 2012) $ by $Author: tack $ % $Revision: 12583 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_member_int_reif(array[int] of var int: x, var int: y, var bool: b); predicate fzn_member_int_reif(array[int] of var int: x, var int: y, var bool: b) = gecode_member_int_reif(x,y,b); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_inverse.mzn0000644000175000017500000000330014536677021024026 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_inverse_offsets(array[int] of var int: f, int: foff, array[int] of var int: invf, int: invfoff); predicate fzn_inverse(array[int] of var int: f, array[int] of var int: invf) = gecode_inverse_offsets(f, min(index_set(invf)), invf, min(index_set(f))); libminizinc-2.8.2/share/minizinc/gecode_presolver/redefinitions-2.0.mzn0000644000175000017500000000227214536677021024644 0ustar kaolkaol% This file contains redefinitions of standard builtins that can be overridden % by solvers. predicate bool_clause_reif(array[int] of var bool: as, array[int] of var bool: bs, var bool: b) = clause(as,bs++[b]) /\ forall (i in index_set(as)) (as[i] -> b) /\ forall (i in index_set(bs)) (bs[i] \/ b); predicate array_int_maximum(var int: m, array[int] of var int: x); predicate array_float_maximum(var float: m, array[int] of var float: x) = let { int: l = min(index_set(x)), int: u = max(index_set(x)), float: ly = lb_array(x), float: uy = ub_array(x), array[l..u] of var ly..uy: y } in y[l] = x[l] /\ m = y[u] /\ forall (i in l+1 .. u) ( y[i] == max(x[i],y[i-1]) ); predicate array_int_minimum(var int: m, array[int] of var int: x); predicate array_float_minimum(var float: m, array[int] of var float: x) = let { int: l = min(index_set(x)), int: u = max(index_set(x)), float: ly = lb_array(x), float: uy = ub_array(x), array[l..u] of var ly..uy: y } in y[l] = x[l] /\ m = y[u] /\ forall (i in l+1 .. u) ( y[i] == min(x[i],y[i-1]) ); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_bin_packing_load.mzn0000644000175000017500000000350214536677021025622 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2010 % % Last modified: % $Date: 2012-03-19 11:56:37 +1100 (Mon, 19 Mar 2012) $ by $Author: tack $ % $Revision: 12583 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_bin_packing_load(array[int] of var int: l, array[int] of var int: bin, array[int] of int: w, int: minIndex); predicate fzn_bin_packing_load(array[int] of var int: l, array[int] of var int: bin, array[int] of int: w) = gecode_bin_packing_load(l,bin,w,min(index_set(l))); libminizinc-2.8.2/share/minizinc/gecode_presolver/precedence.mzn0000644000175000017500000000314214536677021023577 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2011-07-12 21:52:11 +1000 (Tue, 12 Jul 2011) $ by $Author: tack $ % $Revision: 12175 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_precede(array[int] of var int: x, array[int] of int: c); predicate precedence(array[int] of var int: x) = forall (i in index_set(x)) (x[i] <= length(x)) /\ gecode_precede(x, [i|i in 1..length(x)]); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_roots.mzn0000644000175000017500000000463614536677021023536 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-03-19 11:56:37 +1100 (Mon, 19 Mar 2012) $ by $Author: tack $ % $Revision: 12583 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % include "int_set_channel.mzn"; % i in z <-> exists (j in x) (i in y[j]) predicate gecode_array_set_element_union(var set of int: x, array[int] of var set of int: y, var set of int: z); predicate fzn_roots(array[int] of var int: x, var set of int: s, var set of int: t) = assert(ub(s) subset index_set(x), "roots: upper bound of 's' must be a subset of the index set of 'x'", if (min(index_set(x)) < 0 \/ min(ub(t)) < 1) then % All values in 's' must map to a value in 't'. forall(i in ub(s)) ( i in s -> x[i] in t ) /\ % All values in 't' must be mapped from a value in 's'. forall(i in ub(t)) ( i in t -> forall(j in index_set(x)) (x[j] == i -> j in s) ) else let { array[1..max(ub(t))] of var set of 0..max(index_set(x)): y, } in int_set_channel(x,y) /\ gecode_array_set_element_union(t,y,s) endif ); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_exactly_int.mzn0000644000175000017500000000276414536677021024713 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % include "count.mzn"; predicate fzn_exactly_int(int: n, array[int] of var int: x, int: v) = count(x, v, n); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_global_cardinality.mzn0000644000175000017500000000334614536677021026210 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2013-03-07 12:18:29 +1100 (Thu, 07 Mar 2013) $ by $Author: mears $ % $Revision: 13455 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_global_cardinality(array[int] of var int: x, array[int] of int: cover, array[int] of var int: counts); predicate global_cardinality_old(array[int] of var int: x, array[int] of var int: c) = global_cardinality(x,[i|i in index_set(c)],c); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_at_least_set.mzn0000644000175000017500000000301614536677021025026 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_at_least_set(int: n, array[int] of var set of int: x, set of int: v) = bool_sum_ge([x[i] == v | i in index_set(x)], n); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_diffn.mzn0000644000175000017500000000335014536677021023446 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2011-06-04 01:27:50 +1000 (Sat, 04 Jun 2011) $ by $Author: tack $ % $Revision: 12041 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_nooverlap(array[int] of var int: x, array[int] of var int: w, array[int] of var int: y, array[int] of var int: h); predicate fzn_diffn(array[int] of var int: x, array[int] of var int: y, array[int] of var int: dx, array[int] of var int: dy) = gecode_nooverlap(x,dx,y,dy); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_regular.mzn0000644000175000017500000000330314536677021024017 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_regular(array[int] of var int: x, int: Q, int: S, array[int] of int: d, int: q0, set of int: F); predicate fzn_regular(array[int] of var int: x, int: Q, int: S, array[int,int] of int: d, int: q0, set of int: F) = gecode_regular(x,Q,S,array1d(d),q0,F); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_at_most_set.mzn0000644000175000017500000000301514536677021024677 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_at_most_set(int: n, array[int] of var set of int: x, set of int: v) = bool_sum_le([x[i] == v | i in index_set(x)], n); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_sort.mzn0000644000175000017500000000271414536677021023352 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_sort(array[int] of var int: x, array[int] of var int: y); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_value_precede_int.mzn0000644000175000017500000000305714536677021026041 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2013-07-19 22:10:52 +1000 (Fri, 19 Jul 2013) $ by $Author: schulte $ % $Revision: 13911 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_precede(array[int] of var int: x, int: s, int: t); predicate fzn_value_precede_int(int: s, int: t, array[int] of var int: x) = gecode_precede(x,s,t); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_table_bool.mzn0000644000175000017500000000314614536677021024465 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_table_bool(array[int] of var bool: x, array[int] of bool: t); predicate fzn_table_bool(array[int] of var bool: x, array[int, int] of bool: t) = gecode_table_bool(x,array1d(t)); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_nvalue.mzn0000644000175000017500000000267614536677021023664 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2011-08-18 17:42:10 +1000 (Thu, 18 Aug 2011) $ by $Author: tack $ % $Revision: 12312 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_nvalue(var int: n, array[int] of var int: x); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_arg_min_int.mzn0000644000175000017500000000031214536677021024641 0ustar kaolkaolpredicate gecode_minimum_arg_int(array[int] of var int: x, var int: i); predicate fzn_minimum_arg_int(array[int] of var int: x, var int: i) = gecode_minimum_arg_int(x,(i-min(index_set(x)))::domain); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_circuit.mzn0000644000175000017500000000322214536677021024020 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-10-22 09:04:10 +1100 (Mon, 22 Oct 2012) $ by $Author: tack $ % $Revision: 13159 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_circuit(int: offset, array[int] of var int: x); predicate fzn_circuit(array[int] of var int: x) = if min(index_set(x)) >= 0 then gecode_circuit(min(index_set(x)),x) else gecode_circuit(0,[x[i]-min(index_set(x)) | i in index_set(x)]) endif; libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_cumulative.mzn0000644000175000017500000000362014536677021024536 0ustar kaolkaol% % Main authors: % Guido Tack % Mikael lagerkvist % % Copyright: % Guido Tack, 2007 % Mikael Lagerkvist, 2009 % % Last modified: % $Date: 2011-03-08 19:54:48 +1100 (Tue, 08 Mar 2011) $ by $Author: tack $ % $Revision: 11787 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_cumulative(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b) = gecode_cumulatives(s, d, r, b); % Specialized cumulatives propagator is only for fixed bounds predicate gecode_cumulatives(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, var int: b); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_inverse_set.mzn0000644000175000017500000000404714536677021024712 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-03-19 11:56:37 +1100 (Mon, 19 Mar 2012) $ by $Author: tack $ % $Revision: 12583 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_inverse_set(array[int] of var set of int: f, array[int] of var set of int: invf, int: xoff, int: yoff); predicate fzn_inverse_set(array[int] of var set of int: f, array[int] of var set of int: invf) = forall(i in index_set(f)) ( f[i] subset index_set(invf) ) /\ forall(j in index_set(invf)) ( invf[j] subset index_set(f) ) /\ if (min(index_set(f)) >= 0 /\ min(index_set(invf)) >= 0) then gecode_inverse_set(f,invf,min(index_set(f)),min(index_set(invf))) else forall(i in index_set(f), j in index_set(invf)) ( (j in f[i] <-> i in invf[j]) ) endif; libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_range.mzn0000644000175000017500000000403514536677021023455 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-03-19 11:56:37 +1100 (Mon, 19 Mar 2012) $ by $Author: tack $ % $Revision: 12583 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate gecode_range(array[int] of var int: x, int: xoff, var set of int: s, var set of int: t); predicate fzn_range(array[int] of var int: x, var set of int: s, var set of int: t) = assert(ub(s) subset index_set(x), "range: upper bound of 's' must be a subset of the index set of 'x'", if (min(index_set(x)) >= 0) then gecode_range(x,min(index_set(x)),s,t) else forall(i in ub(s)) (i in s -> x[i] in t) /\ forall(i in ub(t)) ( i in t -> exists(j in ub(s)) ( j in s /\ x[j] == i ) ) endif ); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_member_int.mzn0000644000175000017500000000270214536677021024501 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2012-03-19 11:56:37 +1100 (Mon, 19 Mar 2012) $ by $Author: tack $ % $Revision: 12583 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_member_int(array[int] of var int: x, var int: y); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_increasing_int.mzn0000644000175000017500000000267414536677021025364 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2009-09-09 01:42:03 +1000 (Wed, 09 Sep 2009) $ by $Author: schulte $ % $Revision: 9689 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_increasing_int(array[int] of var int: x); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_global_cardinality_low_up.mzn0000644000175000017500000000322014536677021027564 0ustar kaolkaol% % Main authors: % Guido Tack % % Copyright: % Guido Tack, 2007 % % Last modified: % $Date: 2010-10-07 08:10:08 +1100 (Thu, 07 Oct 2010) $ by $Author: schulte $ % $Revision: 11466 $ % % This file is part of Gecode, the generic constraint % development environment: % http://www.gecode.org % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % predicate fzn_global_cardinality_low_up(array[int] of var int: x, array[int] of int: cover, array[int] of int: lbound, array[int] of int: ubound); libminizinc-2.8.2/share/minizinc/gecode_presolver/fzn_arg_max_int.mzn0000644000175000017500000000031214536677021024643 0ustar kaolkaolpredicate gecode_maximum_arg_int(array[int] of var int: x, var int: i); predicate fzn_maximum_arg_int(array[int] of var int: x, var int: i) = gecode_maximum_arg_int(x,(i-min(index_set(x)))::domain); libminizinc-2.8.2/changes.rst0000644000175000017500000043062414536677021014656 0ustar kaolkaolMiniZinc Change Log ------------------- For detailed bug reports consult the issue tracker at https://github.com/MiniZinc/libminizinc/issues. .. _v2.8.1: `Version 2.8.2 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 15 December 2023) Bug fixes: ^^^^^^^^^^ - Fix incorrect FlatZinc definition in the ``gecode_presolver`` solver library (:bugref:`755`). - Fix type specialisation for function with an polymorphic array argument and a non-array return type with the same type-inst identifier (related to :bugref:`671`). - Fix crash during typechecking of overloaded functions differing only by inst returning structured types. - Fix incorrect type checking of polymorphic functions with type-inst IDs inside structured types. - Fix evaluation error when boolean variables are fixed during flattening (:bugref:`758`). - Fix incorrect call names output when generating ``.ozn`` files (:bugref:`759`). - Fix incorrect output of record access as tuple access in ``.ozn`` files (:bugref:`759`). - Fix definition of ``array_intersect`` so that it can be used in non-positive contexts. - Fix standards definitions of ``increasing`` variants to correct be ignored when the argument array is empty (:bugref:`762`). - Fix a problem where exceptions thrown for undefined expressions were not caught during the aggregation of linear expressions, breaking relational semantics (:bugref:`760`). - Fix crash when calculating computed domain of a declaration (:bugref:`765`). - Fix x-y line/scatter visualisations. Changes: ^^^^^^^^ - Support ``var set``s of enums for ``array_union`` and ``array_intersect``. - Support ``var`` enums for the ``..`` range operator. - Always perform substitution of fixed values before outputting FlatZinc for consistency. Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Make process handling more robust to failures. .. _v2.8.1: `Version 2.8.1 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 27 November 2023) Bug fixes: ^^^^^^^^^^ - Fix incorrect message for par array out of bounds indicating that array is empty - Fix incorrect propagation of Boolean variables potentially causing output not accepted by Gecode and Chuffed (:bugref:`748`). - Fix a problem where the usage of ``lb`` on a Boolean expression would return ``-infinity``. (:bugref:`749`). - Fix omission of error location when there is no stack trace available. - Fix type specialisation to always make par versions of functions available for output (:bugref:`751`). - Fix internal error when checking return value of functions involving arrays of optional values (:bugref:`752`). - Fix incorrect ``false`` values for ``has_output_item`` when running with ``--model-interface-only`` - Fix translation of search annotations with multi-dimensional arrays as arguments (:bugref:`750`). - Fix bug in output generation for some visualisation functions. - Fix problem where tuple or record assignments would sometimes trigger segmentation faults. - Fix context when binding the result of flattening a concatenation operation, resolving a possible segmentation fault (:bugref:`754`). - Fix incorrect possible evaluation error for ``in`` operator involving an array RHS. Changes: ^^^^^^^^ - Add ``--solution-checker`` option to allow specifying the solution checker (allowing use from a parameter configuration ``..mpc`` file). - Produce tighter bounds in ``compute_mod_bounds`` for the ``mod`` operator. Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Fix command used to run findMUS and Globalizer. - Add ability to set the ports used for the visualisation server. - Add option for printing the visualisation server URL for debugging purposes. - Add more information to subprocess error messages. .. _v2.8.0: `Version 2.8.0 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 16 November 2023) Changes in interfaces to solvers: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - `OR-Tools `_ is now bundled with the MiniZinc IDE on all platforms. - HiGHS is now loaded as a dynamic plugin instead of statically linked, and now supports outputting intermediate solutions for optimisation problems. - Add support for producing a JSON-based version of FlatZinc as the output format of the MiniZinc compiler. - Replace ``supportsMzn``, ``supportsFzn`` and ``supportsNL`` solver configuration flags with new option ``inputType``. The old flags are still supported for backwards compatibility. - Add *experimental* support for restart based meta-search specification for the Gecode and Chuffed solvers, as first explored in `Solver-Independent Large Neighbourhood Search `_ and `A Modern Architecture for Constraint Modelling Languages `_. - Automatically detect current versions of CPLEX (:bugref:`745`). Changes in the MiniZinc Library: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Add ``cumulatives`` scheduling global constraint. - Add the ``opt`` variants of the ``global_cardinality`` functions, and add enumerated type typesafety between the values of the decision variables and the cover parameters. - Add optional versions of ``count_*`` global constraints (:bugref:`728`). - ``(strictly_)decreasing`` will now always be rewritten into ``(strictly_)increasing`` and has support for option types. - Allow libraries to define how to iterate over ``var set of int`` using the function ``set2iter``, useful for different set representations. - Stabilise the IDE visualisation library, allowing all visualisation functions to be used from ``output`` statements, and removing the need for manual calls to ``showJSON`` in custom visualisations. This is a breaking change for users of the previous experimental API. - Add ``mzn_half_reify_clause`` compiler option to allow solvers to disable the half reification of ``bool_clause`` constraints. - Update the reflection functions ``ub``, ``lb``, and ``dom`` to return enum values. - Use tuples to implement the decomposition of optional variables, avoiding possible CSE aliasing problems. Changes in the compiler ^^^^^^^^^^^^^^^^^^^^^^^ - CSE has been adjusted to handle commutative functions when annotated using the ``promise_commutative`` annotation. - ``mzn_reverse_map_var`` is now only called on output variables that do not yet have reverse mappers after initial flattening, but are required by the output model. - Improve error messaging for invalid parameter configuration (``.mpc``) files. - Add a list of messages generated by solution checkers to the ``checker`` message when using ``--json-stream``. - Support output of command line argument parsing errors in ``--json-stream`` mode. Bug fixes: ^^^^^^^^^^ - Fix restoration of tuple/record domains when flattening ``let`` expressions. - Fix type checking error due to creation of incorrect par versions of functions involving tuples/records. - Ensure that when ``--solver `` is used, the given solver configuration file is always selected even when it collides with a solver in the search paths (:bugref:`715`). - Fix error when running satisfaction problems using the Gecode presolver where an output variable is also an introduced variable. - Resolve a problem where unification in the optimization phase might remove variables part of the output (:bugref:`716`). - Fix possible crash when printing the final solution using the built-in Chuffed interface. - Don't print the final status line from solution checkers. - Fix typechecking of par type-inst identifiers when instantiated using structured types involving ``var`` types. - Implement ``fix`` and ``is_fixed`` for strucutred types. - Ensure reverse mappers are created when flattening tuple/record literals. This resolves certain errors during output processing in models using these types. - Fix problem where certain strings in exceptions might be garbage collected before they are output (:bugref:`725`). - Fix problem where argument names of generated functions could conflict with model declared names (:bugref:`726`). - Fix problem where the common type of complex records or tuples was not correctly determined in the array literals. - Fix a problem in the parser where a nullptr would be used before a syntax error was thrown (:bugref:`730`). - Fix error management when reading preference files (:bugref:`729`). - Fix segmentation fault caused by the creation of invalid domain constraints generated for functions with arrays of tuples or records parameters (:bugref:`732`). - Fix crash when instantiating a type-inst identifier using only ``<>``. - Fix evaluation of comprehensions containing ``opt string``. - Fix crash when instantiating polymorphic functions using tuples/records with many ``var`` or ``opt`` fields. - Do not generate default DZN output when there are only sectioned ``output`` items present (:bugref:`733`). - Fix the edge indexing of the edges for the final node in the ``neural_net`` global constraint (:bugref:`738` :bugref:`573`). - Add better error messaging when an index set mismatch is encountered in the standard library (:bugref:`740`). - Fix evaluation error when indexing into an array using ``<>``. - Fix incorrect unsatisfiability when equating optional variables with non-intersecting domains. - Fix array access using optional indices for multidimensional arrays. - Fix output of zero length arrays of optional variables. - Fix output processing performance degradation when printing arrays in DZN output mode. - Fix card function on set of floats and bools. - Make set literals containing strings or annotations a type error. Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Fix unreadable cheat sheet font colour in dark mode (:idebugref:`191`). - Add option to output objective value and enable by default. - Show manually input parameters in output window. - Fix missing checker messages (:idebugref:`192`). - Fix incorrect OpenSSL version in Linux packages (:idebugref:`189`). .. _v2.7.6: `Version 2.7.6 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 20 June 2023) Changes: ^^^^^^^^ - Change the library and solver configuration path of builtin version of Chuffed to prevent file conflicts (:bugref:`708`). - Use the verbose compilation flag to control the verbosity of the MIP domains stage (:bugref:`705`). Bug fixes: ^^^^^^^^^^ - Resolve issue where right hand assignment of set types could potentially be replaced by literal value (:bugref:`700`). - Fix incorrect undefinedness of element access of arrays of empty sets. - Fix possible incorrect type error when calling an overloaded function with an argument whose true type after flattening causes ambiguity when finding a better match. - Accept ``--num-solutions`` rather than only ``-n`` in the Gecode presolver. - Fix crash when using a record type with a field that is itself a record or tuple. - Fix type error when calling ``show`` on var enum (:bugref:`711`). .. _v2.7.5: `Version 2.7.5 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 7 June 2023) Changes: ^^^^^^^^ - Introduces the ``arg_val`` and ``arg_val_weak`` globals that return the index of the first occurrence of a value in a given array. (:bugref:`544`). - Introduces the ``var_perm_sym`` and ``var_sqr_sym`` symmetry breaking globals. - Enable parallel search for the built-in Gecode presolver. Bug fixes: ^^^^^^^^^^ - Resolve problem in the optimization of set variable constraints (:bugref:`693`). - Fix regression in the context determination of negated binary operators (:bugref:`695`). - Ensure statistics are output when MiniZinc is interrupted with JSON stream output enabled (:bugref:`692`). - Add ``par`` version of ``set_in_imp`` to the ``nosets.mzn`` library to warnings about out-of-bound indices in non-user models (:bugref:`696`). - Add missing bounds calculation for ``symdiff`` (:bugref:`700`). Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Use native Qt dark mode on Windows where supported. - Improve behaviour of the custom solver parameter dialog. .. _v2.7.4: `Version 2.7.4 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 11 May 2023) Changes: ^^^^^^^^ - ``ASTString`` constructor that uses ``std::string`` is now explicit to avoid unexpected or unnecessary GC allocation. - Circular definitions through the use of annotations will now be reported as type errors, rather incurring infinite recursion (:bugref:`680`). - Optimize the compilation of identical calls in different contexts by recursively changing the contexts of the (uncompiled) dependent calls, instead of flattening multiple times. - Change domains of set variables when encountering (par) equalities, or negated ``in`` constraints at the root level. Bug fixes: ^^^^^^^^^^ - Remove redundant function return simplification that could create invalid tuple/record types (:bugref:`681`). - Fix regression in the creation of seperate domain constraints where domains contained infinity (:bugref:`684`). - Fix a flattening the decompositions of lex_less(eq) reifications in the standard library, caused by a missing ``promise_total`` annotation (:bugref:`685`). - Fix incorrect context being used when flattening some binary operators (:bugref:`683`). - Fix with problem with domain copies when varifying a type-inst synonyms (:bugref:`687`). - Add missing support for floating point literals containing exponents in the JSON parser (:bugref:`690`). - Fix a problem where the compiler would incorrectly set the computed domain flag (:bugref:`691`). - Resolve garbage collection issue in the typechecker (:bugref:`688`). - Add missing error message for sets of records and sets of tuples. .. _v2.7.3: `Version 2.7.3 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 20 April 2023) Changes: ^^^^^^^^ - Calls to ``min`` and ``max`` with ``par set of int`` type argument will now be undefined (becoming ``false`` in the closest Boolean context). This makes them consistent with the calls with an argument of type ``var set of int``. Note that previous behaviour would have returned ``infinity`` or ``-infinity`` respectively (:bugref:`661`). Bug fixes: ^^^^^^^^^^ - Fix incorrect handling of enum types during return type specialisation of functions (:bugref:`670`). - Fix incorrect restriction of domains for arrays containing tuples/records (:bugref:`669`). - Fix crashes/invalid FlatZinc generated due to incorrect aggregation of boolean operators involving optional arguments (:bugref:`668`). - Fix handling of absent values when checking the return value of par functions against the type-inst (:bugref:`673`). - Fix small redundancy in the flat_cv_exp that triggers errors (and assertions) in some cases (:bugref:`674`). - Fix a mistake in the context when binding the result of builtins returning an expression (:bugref:`667`). - Fix problem with function domain constraints containing infinity. - Fix crash when flattening field access in negative context (:bugref:`675`). - Fix crash when flattening variable declaration annotations for tuple variables with paths enabled (:bugref:`675`). - Fix incorrect ordering of enum parts when using separate assignment items. - Simplify fixed arrays by pushing them on the queue, rather than using simplify_bool_constraint. Handle boolean variables with fixed domain correctly in fixed literal counting (:bugref:`671`). - Propagate more Boolean constraints during the compiler optimisation phase (:bugref:`676`). - Fix the translation of domains of floating point variables that contain multiple ranges and include an infinity value. - Fix an issue where JSON arrays of sets where parsed incorrectly (:bugref:`679`). - Fix common subexpression elimination for expressions used in incompatible contexts (:bugref:`666`). - Add missing ``::promise_total`` to functional version of ``nvalue``. Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Only show MOOC error code when response is actually an error (:idebugref:`176`). .. _v2.7.2: `Version 2.7.2 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 5 April 2023) Bug fixes: ^^^^^^^^^^ - Fix crash when specialising a function to return an array with enum index sets but integer element type. - Fix decompositions for ``ceil`` and ``floor`` functions (:bugref:`657`). - Fix incorrect resultant domain when binding identifiers with domains to variable declarations (:bugref:`660`). - Fix incorrect unknown status given by Chuffed builtin solver interface on timeout. - Fix segmentation fault that occurred when using some models with checkers (:bugref:`662`). - Fix incorrect type error when an empty array literal would be used in a if-then-else expression with type ``array[_] of set of int`` (:bugref:`664`). - Add support for unicode escapes in JSON input strings. - Fix possible crash when outputting JSON parsing errors. - Fix possible crash during flattening of ``++`` operator. Changes: ^^^^^^^^ - Add documentation for ``--input-is-flatzinc`` flag (:bugref:`655`). .. _v2.7.1: `Version 2.7.1 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 31 March 2023) Changes: ^^^^^^^^ - Add ``ceil``, ``floor`` and ``round`` functions for ``var float``, and corresponding FlatZinc builtins ``float_ceil``, ``float_floor`` and ``float_round`` that can be overridden by solvers in the new ``redefinitions-2.7.1.mzn`` library file (:bugref:`636`). - Make deopt on par absent values return undefined instead of error. Bug fixes: ^^^^^^^^^^ - Fix incorrect chain compression when Boolean variables had constrained domains (:bugref:`638`). - Fix incorrect compilation of let expressions in recursive functions (:bugref:`637`). - Fix the evaluation of ``par`` optional types with a singular value in their domain (:bugref:`639`). - Fix common subexpression elimination for Boolean expressions that contain an undefined result that needs to become false in the Boolean context (:bugref:`639`). - Fix linear aggregation to only aggregate non-optional values (:bugref:`644`). - Fix rewriting to counting constraints to only occur when result is not optional (:bugref:`644`). - Add missing internal builtin for xor on optional bool variables (:bugref:`644`). - Fix evaluation of par array access with absent value (:bugref:`644`). - Fix potential crash when evaluating bounds of par let expressions that contain a variable (:bugref:`646`). - Add missing ``par opt int`` versions of ``~+``, ``~-`` and ``~*`` (:bugref:`644`). - Add missing ``count`` function on ``array[_] of var opt bool`` (:bugref:`640`). - Fix potential crash in typechecking of array of record access (:bugref:`647`). - Fix output of tuples and records that contain enumerated types. - Add missing newline to solver comment output when using ``--json-stream`` (:bugref:`649`). - Fix problem where field names of record types could be removed during garbage collections. - Fix the detection of Gurobi 10 (:bugref:`653`). - Fix performance degradation for models with variables that appear in a large number of constraints (:bugref:`645`). - Fix the definition of ``pow`` involving negative exponents. - Ensure errors/warnings do not output mangled function names (:bugref:`648`). - Fix the decomposition of optional ``inverse``. - Fix various issues with the instantiation of generic functions involving tuples or records. - Fix the parsing multidimensional arrays containing values of enumerated types in JSON. - Fix performance degradation for models with variables that appear in a large number of constraints (:bugref:`645`). - Fix bug in enumerated types with non-contiguous constructor sets. - Fix possible crash when simplifying static function bodies. - Fix handling of set literals and search annotation calls in built-in Chuffed interface. - Fix bug where an already defined variable was made the argument of a ``defines_var`` annotation for a constraint. - Fix handling of domains for tuple and record types. - Fix index set checking for tuples and records which contain arrays. - Fix the handling of domain and index set expressions in aliases. - Fix incorrect coercion of sets into multidimensional arrays (:bugref:`656`). - Fix incorrect simplification of Boolean constraints that contain a fixed Boolean variable in an annotation. Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Fix highlighting of multiline comments starting with ``/*/`` (:idebugref:`172`). - Fix bundling of incompatible OpenSSL version in linux packages. - Remove support for glibc 2.27 and earlier from AppImage and tarball linux packages. The Snap package may be used instead on such systems. .. _v2.7.0: `Version 2.7.0 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 23 February 2023) Major changes: ^^^^^^^^^^^^^^ - Support for tuple and record types as well as type-inst synonyms has been added. - Extended enumerated types can now be constructed from non-contiguous sets. - WebAssembly is now fully supported as a target platform. Changes: ^^^^^^^^ - The compiler will no longer introduce ``array_bool_or``, only ``bool_clause``. - Improve translation of some simple constraints, which avoids introducing unnecessary ``int_eq`` (and similar) constraints. - Remove more subsumed clauses and foralls in the optimisation phase of the compiler. - Report approximate error locations for type errors in function arguments that are literals without location information. - Many internal structures, such as the CSE table, and the representation of variable declarations and calls have been optimised to require less memory. - The compiler now accepts absolute and relative paths as arguments of the `-G` flag. - Functions in the standard library that return arrays of variables are now also annotated with ``is_defined_var`` and ``defines_var(x)`` annotations. - Revert changes in the ``fzn_count_*`` variants that tried to introduce more positive contexts, but inadvertently came at the cost of count aggregation. - The Gecode-based pre-solver can now accept ``--backend-flags`` to allow processing of options whose names conflict with other flags. - The Gecode-based pre-solver is now made available using the ``gecode`` solver tag when using the WebAssembly version of MiniZinc. - Remove unnecessary file packager patch from WebAssembly build. - There is now a version of the ``regular`` constraint that uses enumerated types to represent the states of the automaton. - Revert change in the standard decomposition of ``lex_less(eq)`` so it no longer uses implications which were intended promote half-reification, because this introduced free variables. - Calls to par functions with constrained arguments now result in an undefined value (just like calls to var functions) rather than an abort. Changes in interfaces to solvers: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - MiniZinc now includes a solver interface for the `HiGHS `_ linear optimisation suite. HiGHS is included by default in the MiniZincIDE package, and available using ``--solver highs``. - The SCIP interface has been updated and is now compatible with version 7 and 8 only. - A solver's globals library specified in a configuration file will now always be passed to the compiler using the ``-G`` flag. This allows users to easily override this library from command line when required. - Automatically detect Gurobi 10.0 and potential future versions. - Avoid loading all solver plugin DLLs on startup, instead loading when required. - A built-in solver interface for `Chuffed `_ has been added primarily for use with the WebAssembly version of MiniZinc. - The non-FlatZinc interfaces now also accept the ``--free-search`` flag in addition to the ``-f`` flag. - The SCIP interface will now also try to find the SCIP library files in the Homebrew locations. Bug fixes: ^^^^^^^^^^ - Fix the parsing of JSON enum constructor functions with integer arguments. - Fix the ``..`` operator on variable integers to create sets with tighter bounds. - Fix incorrect memory allocation in Gecode interface (:bugref:`618`). - Fix an error thrown when the declaration of a polymorphic function is split from its definition. - Fix assignment items of enumerated types using the ``++`` operator. - Fix behaviour of overloading involving polymorphic functions which overlap with more specific functions. - Fix extended enum constructors with empty enums. - Fix a bug that prevented the use of polymorphic optional arrays as function arguments. - Generated FlatZinc files are now closed before a solver is called. - Disable inlining for one function when creating webassembly output, to prevent the clang compiler from exploiting undefined behaviour that our code relies on. - Fix Gecode-based presolver to not crash when solving problems with a constant objective, or optimisation problems where some variables are not part of the search or output. - Fix default search for Gecode-based presolver to be the same as standalone Gecode solver. - Fix possible extraneous newline when printing warnings in ``--json-stream`` mode. - Allow option types to be declared with empty domains. - Fix an error in checking floating point array domains for functions with defined domains. - Fix a bug in the evaluation of array comprehensions with option types. - Fix type inference for variables declared ``any`` in let expressions. - Fix possible crashes during garbage collection of identifiers and variable declarations. - Boolean par functions (as declared using ``test``) now behave correctly when they contain partial operations that result in undefined values. - Fix optimisation of values used in float arrays (:bugref:`635`). - Ensure that combining ``--solver-statistics`` and ``--compiler-statistics`` behaves the same as using the ``--statistics`` flag (:bugref:`607`). Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Fix a bug where model selection dialog could run the wrong model. - Fix a bug where the same data file could be added to the MiniZinc command twice. - Ensure user config directory is created when modifying solver search paths (:idebugref:`167`). - Ensure that IDE windows cannot spawn off-screen. - Add tooltips to the CP-Profiler status bar legend. - Add support for mooc submissions which include file editing history. .. _v2.6.4: `Version 2.6.4 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 23 June 2022) Changes: ^^^^^^^^ - All considered function items are now checked to ensure that they can be correctly evaluated or flattened. This means that, to avoid a type error, all functions must have a function body or, in case of a ``var`` function, be valid FlatZinc builtins (i.e., they are predicates/return ``var bool``, and their arguments are valid FlatZinc types) or, in case of a ``par`` function, must have an internal definition in the MiniZinc compiler. Functions that are defined with ``var`` types for convient use in output can be annotated ``output_only``. The compiler will check that a valid ``par`` version of this function is available. Bug fixes: ^^^^^^^^^^ - Fix a bug in the type checker where unsupported coercions could cause crashes. (:bugref:`581`). - Fix a bug in the flattening of binary operators when types of flattened arguments match a different version function than matched by the type checker. (:bugref:`588`) - Fix a bug where statistics without a ``%%%mzn-stat-end`` were not always printed in ``--json-stream`` mode. - Fix a bug in the task decomposition of the cumulative global constraint where resource requirement would not always be correctly be ignored when the task duration is zero. (:bugref:`589`) - Fix handling of float values in ``.mpc`` parameter configuration files. - Fix crash in SCIP plugin due to incorrect loading of ``SCIPinfinity`` symbol. - Fix crash in CBC when there is a heuristic solution but no best solution (:bugref:`592`). Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Ensure the extra parameter filter is cleared when the textbox is cleared. .. _v2.6.3: `Version 2.6.3 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 6 May 2022) Changes: ^^^^^^^^ - Avoid the creation of intermediate ``bool_clause_imp`` calls. - Add the ``no_cse`` annotation to allow CSE storage optimization. - Improve documentation for ``all_different`` with optional variables. - Make breaking of ``defines_var`` cycles deterministic (:bugref:`563`). - Improve documentation for warm start search annotations. - Automatically detect up to SCIP version 8.0.0 for Windows. - Add ``global_cardinality`` and ``global_cardinality_closed`` for arrays of sets. - Categorise all global constraints into documentation groups. Bug fixes: ^^^^^^^^^^ - Fix a bug where variables required by a solution checker were not always correctly passed to the checker, triggering a type error in the checker output. - Fix garbage collection bug during typechecking (:bugref:`564`). - Fix optimisation of reified ``bool_eq`` constraint where the result must be ``false`` (:bugref:`565`). - Restore missing documentation for functions in the top-level ``globals`` group. - Restore ``warm_start`` search annotations for optional values (:bugref:`567`). - Fix broken references to top-level library documentation pages. - Fix highlighting of JSON-like code blocks in the documentation. - Fix a bug where variables used in type-insts of output variables were not correctly copied to the output model (:bugref:`570`). - Fix a possible crash when flattening ``forall`` calls. - Ensure ``pow`` functions are total (:bugref:`572`). - Fix an internal error when using an ``if-then-else`` with a branch equating ``<>`` to an expression. Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Improve UI and dark mode for CP Profiler. - Fix CP Profiler tree-builder signal/slot connection (:idebugref:`160`). - Fix deadlock in CP Profiler tree building (:idebugref:`162`). - Make project loading more resilient to errors (:idebugref:`165`). .. _v2.6.2: `Version 2.6.2 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 22 March 2022) Changes: ^^^^^^^^ - Better transformation of clauses to avoid negations when possible. Bug fixes: ^^^^^^^^^^ - Prevent possible non-deterministic function dispatch. - Fix a bug in bounds computation for sums over arrays that could result in a crash. - Fix a bug in the logical context of negated implication operators. - Fix definition of ``indomain_min`` and ``indomain_max`` for ``set_search`` in ``nosets.mzn``. - Fix type checker to consider all functions/predicates with var arguments as var type. - Ensure that the last solution is always printed for Gurobi (:bugref:`561`). - Fix the dispatch from non-overloaded operators to builtin calls for opt types. - Fix creation of ``par`` versions of ``var`` functions used in output. - Fix bounds calculation for comprehension ``in`` expressions which are ``var``. Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Don't print expected error messages for MOOC submissions. - Fix custom parameter widget dark mode CSS. .. _v2.6.1: `Version 2.6.1 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 3 March 2022) Changes: ^^^^^^^^ - Throw an error when the time limit is reached in ``mzn2fzn`` mode. - Relax a MIPD infeasibility check (:bugref:`550`). - Add half-reification possibilities for boolean builtin redefinitions. Bug fixes: ^^^^^^^^^^ - Fix bounds calculation for singleton linear expression over 0/1 variable. - Correctly set whether an array literal is flat during copying (:bugref:`536`, :bugref:`549`). - Fix compilation of SCIP and Xpress solver plugins. - Don't print the ``=====UNKNOWN=====`` status on timeout in ``mzn2fzn`` mode. - Ensure variables are always copied to the output model when required by a solution checker. - Rename clashing definition of internal version of ``arrayXd`` to ``arrayNd`` (:bugref:`552`, :bugref:`553`). - Output the correct variables when using ``--output-mode checker``. - Fix possible crash when handling errors due to incorrect garbage collection. - Fix WebAssembly build of MiniZinc. - Allow comprenhensions to iterate over the ``{}`` literal. - Fix printing of multidimensional arrays of enums in output. - Fix the output format when using ``--json-stream`` on FlatZinc files. - Rename ``member_int_reif`` to ``fzn_member_int_reif`` in the Gecode presolver library (:bugref:`556`). Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Fix crash when the solver for an unsaved configuration is removed. - Fix bug where the selected solver could incorrectly change when a configuration option is altered. .. _v2.6.0: `Version 2.6.0 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 18 February 2022) Language and library changes: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Add support for annotating :mzn:`output` items to define output sections which can be switched on/off using ``--only-sections`` and ``--not-sections``. - Add support for the :mzn:`empty_annotation`, which is removed during flattening. - Allow annotations on function parameter declarations. - Add support for reified annotations. If one of the arguments of an annotation declaration is itself annotated with :mzn:`::annotated_expression`, the annotation function will be called with the annotated variable at that argument position. - Support annotations :mzn:`::promise_monotone` and :mzn:`::promise_ctx_antitone` for function parameters and let bound variables. - Add support for capturing annotations in predicates/functions. - Add non-optional variants of the :mzn:`in` operator on arrays. - Update redefinitions of lex_less(eq) to promote half-reifications. - Add definition for bool_clause_imp in standard library. - Don't consider quotes as part of identifiers (so :mzn:`'foo'` and :mzn`foo` are the same identifier). - Add :mzn:`default` operator which takes the value of the right hand side if the left hand side is undefined or absent. - Remove :mzn:`bool2int` in sum constructs (:bugref:`472`). - Rewrite :mzn:`bool_clause_imp` to clause instead of :mzn:`bool_clause`. - Remove old, unused solver libraries. - Add debugging builtins that are only evaluated with ``--debug``. - Add :mzn:`enumOf` function and allow :mzn:`enum_next` and :mzn:`enum_prev` with a single parameter. - Add support for :mzn:`..<`, :mzn:`<..` and :mzn:`<..<` operators. - Add support for open intervals (:mzn:`a..`, :mzn:`..b`, :mzn:`a<..`, etc). - Add support for indexed array literals and comprehensions. - Allow generators to range over multi-dimensional arrays. - Add support for the :mzn:`any` type specifier. - Add support for anonymous generators like :mzn:`[ 0 | _ in 1..n ]`. - Add support for anonymous enum constructors using :mzn:`_(x)`. - Add support for enum construction from a contiguous subset of an enum. - Add :mzn:`::output` and :mzn:`::no_output` annotations for top-level and local variable declarations. - Add support for empty let expressions and trailing comma in enum declarations. - Add missing variants of :mzn:`=` and :mzn:`!=` operators on arrays by making them polymorphic. - Change propagation strength annotations from :mzn:`domain` and :mzn:`bounds` to :mzn:`domain_propagation` and :mzn:`bounds_propagation` and add :mzn:`value_propagation` as an option. - Add :mzn:`trace_exp` builtin function for easy tracing of expressions when debugging. - Add :mzn:`trace_to_section` builtin function. - Add :mzn:`relax_and_reconstruct` annotation to standard library. - Add ``_decomp`` versions of disjunctive and cumulative optional constraints. - Improve :mzn:`sqrt` function. - Add IDE visualisation library ``ide/vis.mzn`` along with helpers :mzn:`json_object` and :mzn:`json_array` for generating JSON output. - Add support for comparing infinities with variables (:bugref:`515`). - Weaken bounds to cover more cases in decomposition of :mzn:`global_cardinality_low_up`. - Allow identifiers starting with underscores in normal MiniZinc models. - Make the naming for variants of all_different consistent (:bugref:`500`). - Add if-then without else for :mzn:`string`, :mzn:`annotation`, and arrays. - Add initial textual structured output functions. - Add index poly types for several global constraints and remove top level ``_reif`` versions. - Add support for hex and octal characters in string literals. Compiler tool changes: ^^^^^^^^^^^^^^^^^^^^^^ - Add support for JSON input of enum constructors and anonymous enums. - Add ``--cmdline-json-data`` option for passing JSON data on the command line. - Add support for JSON stream machine-readable output format enabled with ``--json-stream``. - Improve generation of default random seed. - Use the random seed option for the random builtin functions. - Add timeout tracking to the flattening compiler phase. - Allow configuring solvers to always pass certain flags or arguments. - Honour the ``TMPDIR`` environment variable for placing temporary files (:bugref:`468`). - Remove temporary files/directories when interrupted (:bugref:`468`). - Add ``globals`` section to the output of ``--model-interface-only``. - Enable monomorphisation of polymorphic functions. - Output one and two-dimensional arrays using index literal syntax when possible. - Write solution checker warnings directly to the error stream instead of showing them as part of the checker output. - Make error and warning message output more uniform, improve error messages for various errors. - Improve reporting of internal errors, asking user to file a bug report. - Recognise stack overflows on supported platforms. - Add additional message for deprecated functions marked for removal. - Don't repeat warnings that are also errors (in particular ResultUndefined errors). - Add the found and expected array sizes to the error when mismatch occurs (:bugref:`510`). - Add deprecation warning for type specific usage of overloaded globals. - Add warning when included files directly override global constraints. - Add delayed rewriting of half-reified bool_clause. - Never output :mzn:`_objective` for satisfaction problems. - Never include:mzn:`_objective` in model interface output variables. - Allow optimisation checkers to take model objective as input. - Rewrite :mzn:`array_intersect`, :mzn:`array_union` and :mzn:`array2set` functions into predicate calls that can be overridden by solver libraries. - Improve error location reporting for type errors involving the objective. - Print location and better message when a constraint evaluates to false during flattening. Changes dealing with option types: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Enable automatic symmetry breaking for absent integer option types by setting the internal integer representation to zero (can be disabled with ``-Dmzn_absent_zero=false``). - Make use of new symmetry breaking in optional :mzn:`min`, :mzn:`max`, :mzn:`element` and :mzn:`value_precede`. - Add optional versions of :mzn:`circuit`, :mzn:`all_different`, :mzn:`inverse`, :mzn:`global_cardinality`, :mzn:`global_cardinality_closed`, :mzn:`value_precede_chain`, :mzn:`arg_min`, and :mzn:`arg_max`. - Add weak versions of :mzn:`!=`, :mzn:`/` and :mzn:`div` operators. - Add weak versions of :mzn:`min` and :mzn:`max` and use these in the decomposition of :mzn:`span`. - Add :mzn:`::defines_var` for :mzn:`var opt` variables. - Add missing :mzn:`opt bool` operators. - Add missing :mzn:`in` operators for optional variables. Changes in MIP solver backends: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Add half-reified alternative for :mzn:`int_ne` in linear library. - Add linear definition for :mzn:`bool_clause_imp`. - Add support for :mzn:`float_div` in Gurobi and SCIP. - Automatically detect Gurobi 9.5.0 and potential future versions. Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Add support for specifying submission terms for MOOC. - Ensure newly loaded configs override synced options (:idebugref:`144`). - Fix check for empty project to avoid incorrect warnings when closing. - Maintain modified solver configurations when using preferences dialog. - Support using arm64 version of MiniZinc with x86_64 IDE build on macOS. - Fix crash when no solver configurations are available. - Remove WebEngine-based visualisation feature and implement HTTP/WebSocket server based visualisations. - Add support for dark mode detection on Windows. - Implement foldable output widget supporting output sections. - Support both Qt 5 and Qt 6. - Allow tab to shift multiple lines right. - Re-implement support for detached solver processes. - Allow the project/solver configuration panes to take the full height of the main window. - Implement new multi-tabbed preferences dialog. - Ignore errors in non-current files during background code checking. - Fix undefined behaviour in main window event filter (:idebugref:`154`). - Fix crash when terminating solvers due to closing the main window. - Confirm before removing files from project (:idebugref:`149`). Other changes: ^^^^^^^^^^^^^^ - Improve table of contents for globals documentation. - Restructure the standard library documentation. - Add more details on solver installation paths to documentation. - Remove useless restart example from documentation. Bug fixes: ^^^^^^^^^^ - Fix reference counts for added annotations. - Fix cyclic include detection involving multiple model files with the same file name (in different directories). - Ensure executables have correct extension on Windows (:bugref:`463`). - Fix detection of multiple goal hierarchies (:bugref:`465`). - Fix :mzn:`trace_stdout` to correctly output to standard output. - Fix assertions in graph globals (:bugref:`467`). - Fix the decomposition of cumulative (:bugref:`388`). - Fix comparison of infinite domains. - Pass on fixed partiality status when flattening in root context. - Ignore solver exit code when terminating it due to timeout on Windows. - Fix the context for constraints in implied_constraint calls (:bugref:`471`). - Fix the placement of the bool_clause_imp standard redefinition. - Add slicing coercion for let body (:bugref:`483`). - Flatten calls on right hand side of variable declarations in root context unless they return bool or var bool (:bugref:`485`). - Support flattening of top-level variable declarations triggered from non-root contexts (:bugref:`485`). - Report type error when overloading on return type (:bugref:`484`). - Delay deletion of variable, to avoid deleting variable that is required for output (:bugref:`476`). - Only mark non-toplevel Ids as evaluated if they are not pointing to another Id (:bugref:`469`). - Report type errors when trying to declare :mzn:`var ann`, :mzn:`var string`, :mzn:`var set of bool` or :mzn:`var set of float` (:bugref:`487`). - Add missing comparison operators on array (:bugref:`428`). - Fix par comparison of sets. - Make fix builtin on arrays return array with the same index sets as its argument. - Don't try to compute bounds for par array literals if they contain var types. - Only fail on empty domain if the variable is not a set variable (:bugref:`493`). - Don't evaluate type-inst variable when creating new flat variable (:bugref:`494`). - Add missing conditional decomposition for var opt float type (:bugref:`495`). - Only extract equalities from if-then-else expressions if they are not on arrays. - Fix bug that prevented type-checking of type-inst expressions in :mzn:`let` variables. - Fix cumulative decomposition for fixed resource requirements. - Avoid problems with internal annotations in the ``VarOccurrence`` count. - Do not pass value from model for :mzn:`var` variable in solution checkers. - Correctly handle empty 2D array in :mzn:`show2d` function and empty 3D array in :mzn:`show3d` (:bugref:`501`). - Fix lost output for functional ``_eq`` constraints (:bugref:`503`). - Never insert empty arrays into weak ref tables. (:bugref:`509`). - Make sure the new objective variable declaration item is not garbage collected before being added to the main model (:bugref:`513`). - Fix unification of float variable bounds (:bugref:`514`). - Fix :mzn:`deopt` scoping issue in optional :mzn:`min` and :mzn:`max` (:bugref:`518`). - Create dummy value for option types (:bugref:`521`). - Don't rewrite count to :mzn:`count_...` if the counted variables are optional (:bugref:`527`). - Treat :mzn:`<>` in conditionals as arbitrary type, not int (:bugref:`529`). - Fix :mzn:`value_precede_chain` for non 1-based array indexes (:bugref:`530`, :bugref:`531`). - Ensure the ``Location`` objects in ``Warning`` and ``LocationException`` are marked alive (:bugref:`538`). - Fix non-reified decomposition of seq_precede_chain for sets. - Fixes optional commas and pipes in 2d literals. - Ignore :mzn:`<>` in :mzn:`lb_array`, :mzn:`ub_array` and :mzn:`dom_array`. - Fix incorrect generation of :mzn:`int_lt` when an optional operand is flattened to become non optional. - Ensure chain compression considers functional :mzn:`exists` calls in positive context. - Consider clauses that are not direct implications during chain compression - Fix definition of :mzn:`array_intersect`. - Fix output of :mzn:`arrayXd` with enum index sets. - Fix handling of internal annotations during flattening. - Fix JSON output of annotations. - Correctly quote DZN IDs in output and correctly escape output variable names in model interface. - Fix the generation of assertions for enumerated types. - Fix computation of function return type with type-inst variable index set and enum argument. - Move includes from stdlib into solver_redefinitions to ensure any corresponding solver-specific predicates get declared in the produced latZinc. - Fix element functions for arrays of var opt type to work in negative contexts. - Avoid duplicating expressions in the desugaring of slicing operations. - Fix coercion of [] to arbitrary dimensions when used as variable initialiser. - Fix calculation of argument type to include actual array argument dimensions. - Fix computation of float bounds involving absent value. - Fix bind to allow the usage of absent literals in opt float arrays. - Always add coercions to variable declarations to make sure array slicing is resolved correctly. - Make sure the TypeInst of a variable is also scanned for dependencies that need to go into the output model. - Produce type error for non-Boolean constraint items. - Flatten par comprehension generators that contain variables. - Flatten boolean array literals and comprehensions in mixed context. - Fix :mzn:`var_dom` to correctly handle :mzn:`<>`. - Fix segmentation fault in output generation. - Ensure that the argument to ``--backend-flags`` does not get consumed early. - Fix slice functions to return arrays with enum index set where appropriate. - Correctly flatten indexed comprehension with variable :mzn:`where` clause or generator. - Don't copy comprehensions with variable where clause or generator into output model. - Restore bindings for lets and calls when an exception is thrown during evaluation. - Do not output invalid MIP objective statistics for satisfaction problems. - Fix flattening of limited partial if-then-else expressions. - Fix the rewriting of bool_not reifications when argument is defined. - Don't assume all array literals can be evaluated during bounds calculation. - Use correct infinite set for floats. - Check for undefined results in flat_cv_exp. - Don't fail on empty arrays with empty domain (:bugref:`534`). .. _v2.5.5: `Version 2.5.5 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 19 March 2021) Changes: ^^^^^^^^ - Make min/max on an array of optional variables return a non-optional var, behaving as if absent values are not in the array. Bug fixes: ^^^^^^^^^^ - Insert par array literals in the common subexpression elimination map, fixing a FlatZinc code bloat issue (:bugref:`458`). Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Fix editing of custom string parameters so they don't get converted to floats. - Fix crash on Windows caused when the ``PATH`` environment contains unicode characters. .. _v2.5.4: `Version 2.5.4 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 16 March 2021) Changes: ^^^^^^^^ - Allow empty arrays in global cardinality constraints (:bugref:`440`). - Add piecewise_linear for non-continuous intervals. - Fail on empty variable domains in agenda. - Allow coercion of JSON lists to enum definitions (:bugref:`441`). - Update strictly_decreasing with documentation and opt version (:bugref:`454`). - Remove MIP-specific ``fzn_less(eq)_bool(_reif).mzn``. - Add ``mzn_in_symmetry_breaking_constraint()`` for internal use. - Add MIP decompositions for ``lex_less[eq]_*``. - Add ``lex_chain_*`` globals, and use them in ``lex2[_strict]``. - Improve detection of variable declarations which are actually par to allow more use of overloaded par versions of predicates. - Update documentation on installation of OR-Tools. - Report CPU time in ``solveTime`` statistic for MIP solvers. Bug fixes: ^^^^^^^^^^ - Fix handling of bad Xpress licenses when collecting extra flags. - Don't propagate annotations into annotation calls to infinite recursion. - Add missing par opt versions of coercion functions. - Revert incorrect renaming of ``has_output_item`` to ``has_outputItem`` in model interface output. - Fix incorrect grammar specification in documentation (:bugref:`453`). - Fix crash when defining enums with no members (:bugref:`443`, :bugref:`444`). - Support undefined enums in the type checker. - Fix CPLEX solver ID in documentation. - Never insert par expressions in the common subexpression elimination map. - Fix cv flag propagation when the body of a let or function is cv. - Fix equality test for annotations involving indirection. - Don't modify the infinite domain of optional variables (:bugref:`456`). - Don't immediately evaluate output_only arrays when generating dzn output. - Coerce boolean objectives to integers. - Don't create copies of global declarations when creating par versions of functions. - Compile infinite domains with holes into constraints (:bugref:`457`). - Use generic flattening inside generators, disallowing free boolean variables inside ``in`` expressions (:bugref:`451`). - Strip library paths from includes in multi-pass compilation (:bugref:`455`). - Canonicalise file names of includes to ensure the same file is not included multiple times. - Escape paths in printed ``include`` items, fixing backslash problems on Windows. - Follow ids to declarations when flattening par arrays (:bugref:`448`). - Ignore par constants during chain compression. - Fix flattening of all-par set literals. Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Fix possible crash due to incorrect use of WriteFile on Windows. - Ensure Gecode Gist dependencies are present in the Linux bundle and AppImage (:idebugref:`132`). - Fix crash when stopping solver during exit. - Don't show irrelevant context menu entries in the project explorer. - Add support for HTTP/S links in the output pane. - Fix crash when saving CP Profiler executions where there is no info associated with a node. - Show a warning when there are open files which are not part of a MOOC submission. - Fix double spinbox precision issues (:idebugref:`134`). - Include Gecode Gist and CP Profiler dependencies in Snap package. - Allow opening of multiple files through the open file menu option. - Ensure file dialogs save last path when opening files. - Make the escape key close the find/replace dialog when focussed on any child widget. - Allow setting MOOC submission items as mandatory. .. _v2.5.3: `Version 2.5.3 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 24 November 2020) Changes: ^^^^^^^^ - Fully reify -> (x != y) in the linear library. - Allow printing of comprehensions using introduced variables. - Allow increasing/decreasing over multidimensional arrays. - Add mzn_ignore_symmetry_breaking_constraints and mzn_ignore_redundant_constraints options, allowing the symmetry_breaking_constraint and redundant_constraint predicates to be overridden, so that those constraints can be disabled independent of the solver library that's being used (:bugref:`429`). - Add automatic coercion of strings in JSON input data to enum constants where needed. - Add automatic coercion of lists in JSON input data to sets where needed. Bug fixes: ^^^^^^^^^^ - Fix int_lin_eq_imp in the linear library. - Use variable declaration location for invalid type-inst error messages without locations. - Rewrite par versions of fzn_count_* into var versions, allowing solvers that only redefine the bar version to use their built-in propagators even if the value to count is fixed at compile time (:bugref:`427`). - Add multi-level array construction for enumerated types when outputting in JSON format. - Ensure that functions can only be used as par if their return type is par (:bugref:`431`). - Fix parser default location macro, preventing loss of location filenames in some cases. - Fix parser rule for non-opt sets to give the correct starting location. - Fix fzn_bin_packing_capa_reif.mzn and fzn_bin_packing_load_reif.mzn (:bugref:`435`). - Update decl for binary and unary operators when creating par versions of functions (:bugref:`437`). - Only throw type errors for enum type identifier mismatch in strict enums mode. - Only post cumulative constraints if there is at least one task, preventing an assertion about the lower bound from failing. Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Only reset config window item focus if it is still focused, preventing spurious changes in focus during code checking. - Fix handling of final statuses, including UNSAT (:idebugref:`123`). - Remove -s flag support from Gecode Gist solver configuration (:idebugref:`125`). - Fix crash when saving a project with no solver selected (:idebugref:`127`). - Correctly remove temporary parameter configuration files after use (:idebugref:`128`, :idebugref:`129`). - Fix the time limit readout in the status bar when solving. .. _v2.5.2: `Version 2.5.2 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 6 November 2020) Changes: ^^^^^^^^ - Use full reification in int_ne_imp. - Add support for redefining 2d element constraints in the solver library. - Produce warning when shadowing a variable in a let or comprehension in the same function (or toplevel) scope (:bugref:`419`). - Rewrite symmetric_all_different to inverse (:bugref:`426`). - Add link icons to globals etc in the reference documentation (:bugref:`425`). - Make the nodes statistic show the total number of nodes across all restarts for SCIP. - Add support for multidimensional arrays in counting constraints (:bugref:`413`). - Allow .json files to be specified using the --data option (in addition to .dzn files). - When specifying relative paths inside parameter configuration files, resolve them relative to the config file. Bug fixes: ^^^^^^^^^^ - Correctly add file extension to plugin libraries when omitted. - Fix JSON array index coercion when the first index is undefined. - Catch ResultUndefined exception when evaluating cv par expressions, and turn into undefined result. - Fix trailing for lets and comprehensions, resolving some issues with recursive functions containing lets and/or comprehensions. - Only create par version of functions that do not refer to any toplevel variables (:bugref:`418`). - Keep correct location information for identifiers. - Print warnings from solns2out. - Fix the removal of reverse mapped arrays when they contain aliases. - Disallow macro replacement when call has reification implementation. - Fix the behaviour of passing an invalid version hint to --solver. Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Properly resize extra flags table after adding parameters (:idebugref:`119`). - Use the minimal configuration to check the model interface (:idebugref:`118`). - Allow omitting builtin solver version in project JSON. - Don't mark as modified when loading non-synced solver configurations. - Ensure the last open configuration in a project is selected when loaded. - Fix the default values of solution truncation and output window clearing. - Process unrecognised extra flags from old project configurations. - Fix watching for modification of the additional data box. - Fix the alignment of line numbers. - Make behaviour controls more narrow to accommodate smaller window sizes. - Defocus config window widgets when updating solver config so values of currently edited fields are updated. - Pass user input data correctly during compilation. - Remove solns2out options from MiniZinc call when compiling. .. _v2.5.1: `Version 2.5.1 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 22 October 2020) Changes: ^^^^^^^^ - Rewrite alldifferent_except_0 to fzn_alldifferent_except_0, to enable solvers to implement that constraint if it is available (:bugref:`414`). - Propagate domains for variables even when reverse-mapped. This ensures that variables with multiple encodings can be created with the tightest possible bounds. - Fail instead of producing empty domains when simplifying int_le constraints. - Allow parsing of nested objects in parameter configuration files. - Add --backend-flags option to provide a uniform way of passing flags to an underlying solver. - Add extra flags support to the MIP solver interfaces, allowing parameters to be set in the IDE. - Improve automatic detection of the Xpress solver and license file. - Allow the use of spaces in the --solver flag argument. - Automatically add the last part of the solver ID as a tag. - Improve handling of var functions in output, automatically creating par versions of var functions if possible. Bug fixes: ^^^^^^^^^^ - Fix parsing of empty multidimensional JSON arrays. - Allow use of --parallel long form option in MIP solvers. - Fix item lookup when increasing annotation usage in annotate builtin. - Fix JSON array coercion to handle arrays with 1 unknown index. - Don't try to access array dimensions for output of empty multi-dimensional arrays. - Print verbose version information to stderr instead of stdout. - Fix context handling when flattening par expressions that contain variables (:bugref:`415`). - Flatten string expressions if they contain variable parts in assert/abort/trace calls. - Fix breakage on older versions of Windows due to UTF-8 conversion failing. - Remove defines_var/is_defined_var annotations when simplifying boolean constraints. - Fix transfer of cv status from where parts to newly generated conjunctions during typechecking. - Fix multiple issues with the defined_var / is_defined_var annotations. - Move all included files from stdlib into solver_redefinitions.mzn, so that solver redefinitions are not marked as belonging to the standard library (:bugref:`416`). - Fix documentation group for standard annotations (:bugref:`417`). - Show correct version of solver plugins which have their DLLs specified using a command-line parameter (:bugref:`411`). - Fix arbitrary flag support for NL solvers. - Kill child processes if exception occurs during solns2out on Unix-like platforms. Changes in the IDE: ^^^^^^^^^^^^^^^^^^^ - Fix typo when passing solver statistics option to minizinc (:idebugref:`112`). - Fix missing statistics output (:idebugref:`112`). - Add support for colour themes (:idebugref:`110`). - Don't prompt for saving after adding/removing files from the Untitled project. - Fix running of compiled FlatZinc files. - Show error message when trying to load an invalid configuration file. - Ensure all output is sent to the output console, and that fragments in standard error output appear when a newline is written to standard output (:idebugref:`114`). - Fix running of solver configurations from the project explorer. - Improve performance of adding a large number of extra flags at once. - Add support for 64-bit integer extra flags. - Add support for setting both solver backend flags and MiniZinc command flags (:idebugref:`113`). - Improve interface for adding extra parameters, allowing search/filter and multiselection of known parameters. .. _v2.5.0: `Version 2.5.0 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 6 October 2020) Language, tool and library changes: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Allow `reading command line arguments from JSON config file `__. - Add support for `enum constructors `__. - Put subprocesses in their own process group so that they don't receive signals from both the console and MiniZinc. - Implement soft and hard process timeouts on Windows, allow triggering of shutdown from named pipe on Windows for the IDE. - Make MiniZinc unicode-aware on Windows. - Better error messages for index set mismatches. - Report similar identifiers when matching fails. - Better error messages when a call cannot be matched to an existing function or predicate. - Print error stack if top of stack is a single identifier (i.e., error occurred while flattening a variable declaration). - Add new separate flags for intermediate and all solutions. -i enables intermediate solutions for optimisation problems and --all-satisfaction enables all solutions for satisfaction problems. Changes in interfaces to solvers: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Solvers which only support intermediate solutions now can now support the standard flag -i rather than -a. - Restructure the `MiniZinc standard library `__. Changes in MIP solver backends: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Remove non-conforming -n flags for MIP solver configs standard flags. - Improve autodetection of Gurobi DLL. - Find Gurobi 9.0.2 when building. - Don't create gurobi log. - Interface to concurrent solves in Gurobi (--readConcurrentParam). - Add -DMinMaxGeneral option for min/max as fzn_array_float_minimum for Gurobi - Find SCIP 7.0 on Windows - Use -Glinear library, built-in cumulative by default for SCIP. - Use quadratics in Gurobi and SCIP by default. - Add options --xpress-root and --xpress-password for finding Xpress installation directory and licence file. - Add MIQCP quadratic constraints for Gurobi and SCIP. Changes dealing with option types: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Add opt versions of several globals. - Define weak equality for var opt bool. - Add set_in definitions for var opt int. - Add opt versions of enumerated type functions (to_enum, enum_next, enum_prev etc). - Enable set literals with optional values (which will be ignored), including var set literals with var opt int elements. - Add opt version of float_dom to stdlib. - Change unary not for opt bool to use absorption lifting. - Add array2set functions on var opt int arrays. - Add opt versions of dom, dom_array and dom_bounds_array. - Add missing logical operators to var opt bool. Changes in the MiniZinc IDE: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Remove support for the old binary storage format of projects. These must be opened and re-saved with version 2.4.3 to remain compatible. - Include experimental CP-profiler through the \*MiniZinc\* > \*Profile search\* option for supported solvers. - Redesign the solver configuration window. - Use parameter configuration files rather than passing command-line options directly. - Show solver configurations and checkers in their own sections in the project explorer. - Allow multiselection in the project explorer for running particular sets of files. - Allow MiniZinc to manage subprocesses by itself. - Allow non-privileged installs of the IDE on Windows. - Correctly remove files from old installations of the IDE on Windows. - Enable scroll bars in the preferences dialog to allow for low resolution displays. - Prompt to save modified files before performing MOOC submissions or running models. - Fix infinite recursion when a model file for a MOOC submission doesn't exist. - Use --output-mode checker for MOOC solution submission where supported. - Fully support unicode on Windows. Minor changes: ^^^^^^^^^^^^^^ - Clean up code base and format using clang-format and clang-tidy. - Update WebAssembly build for new versions of emscripten. - Support --cp-profiler option to activate search profiler for IDE. - Add --solver-json to output single solver config as JSON. - Coerce JSON arrays to match the MiniZinc TypeInst. - Add more informative README file. - Split shared MIP cpp code into seperate CMake object target. - Compile with POSITION_INDEPENDENT_CODE targets by default. - Change ASTString to use String Interning. - Add included_files output to model interface. - Update Bison parsers to be compatible with Bison 3.7. - Allow annotating enum declarations. - Add support for --c_d and --a_d options to set recomputation commit/adaption distance for Gecode presolver. - Place float_set_in in a version redefinition documentation group. - Place int_pow_fixed into a version redefinitions group. - Move set_in(var int, set of int) to the Integer FlatZinc Builtins. - Make "show" display contents of arrays rather than array identifiers if the array is var - Add support for checking statistics after solving has finished. - Include preferences set by IDE repository. - Add has_ann(var, ann) annotation introspection builtin. - Use reverse mapped version for output if FlatZinc contains an aliased variable. - Remove NDEBUG flag from the compile flags added by CPLEX and Gurobi. - Use integer variables in decomposition for array_int_element, array_var_int_element, array_int_minimum, and array_int_maximum. - More preprocessing for pow(int, int). - Add is_same builtin. - Add multiobjective annotation for Gurobi and Yuck (in std/experimental.mzn). - Add --output-mode checker, which outputs exactly the variables that are required for a given solution checker. - Improve propagation of annotations, especially for redefined forall, exists, clause, xor - Make omitting RHS from output_only variable a type error. - Add support for var set comprehensions - Make sets inside set literals a type error (rather than evaluation error). - Aggregate bool_not into exists/clause, use bool_not(e) for clause([],[e]) expressions - Cleanup the common-subexpression elimination table. - Generate bool_not calls (instead of bool_eq_reif) and add both "x=not y" and "y=not x" into the CSE map, to avoid double negations. - Add arg_max and arg_min builtins for boolean arrays. - Remove -O flag from ozn file naming. - Allow var items in checkers to be omitted from the model. - Add builtins for binary operators that have a var redefinition. - When an integer or bool variable has a singleton domain, use the value. This enables more overloading to par functions. - Check if domain becomes empty when binding variable to value, avoiding empty domains (such as 1..0) in FlatZinc. - Ignore unknown JSON data items instead of throwing an error. - Add trace_logstream and logstream_to_string builtins. These can be used for writing model checkers/graders, but also for general logging. - Clean up CMake configuration - Allow any installed solver to be used with the test suite, add ability to test for expected ozn output. .. _bug-fixes-1: Bug fixes: ^^^^^^^^^^ - Fix error message for type errors in domains that are integer literals (:bugref:`408`). - Fix comprehensions over option types, which could cause crashes and incorrect flattening (:bugref:`407`). - Fix the usage count of annotations added using the annotate function - Flatten "in" expressions in comprehensions when required. - Check if operator is built-in after evaluating arguments, to make sure it is rewritten into the correct predicate. - Use dom(x) instead of lb(x)..ub(x) for opt int. - Use eval_par to compute bounds for par expressions since they might be opt. - Use library defined operators where available. - Fix -O flag parsing for optimisation level. - Fix par set inequality calculation. - Flatten domain expressions that contain variables. - Catch ResultUndefined when flattening an array with an undefined expression in a generator - Fix source paths in MD5 generation scripts. - Fix crash when reporting undefined result in assignment generator. - Only add coercion for normal generators, not for assignment generators. - Check output var status on actual item being removed. - Include absolute path instead of filename in multipass processing. - Coerce comprehension generators if necessary, so that slicing notation can be used there. - Fix copying of comprehensions with followIds. - Fix the method signature of printStatistics for Geas. - Ensure the definition of reverse mappers are copied into the output model. - Print solns2out statistics to stdout to comply with MiniZinc spec. - Minor doc-fix for global_cardinality_closed. - Make statistics output comply with MiniZinc spec. - Fix reverse function to work with empty arrays - Fix the coercion of boolean sum in aggregation. - Remove eval_par on var expressions in show builtin. - Fix the table construction for the Geas solver interface - Fixed wrong sign in Boolean linear constraints in Geas solver interface. - Fix istrue and isfalse by using flat_cv_exp if necessary. - Fix the excess flattening of items marked for removal. - Do not add newline to output when killing FlatZinc solver process, since this may be in the middle of a line - Fix typo in loop for Geas solver instance. - Don't call doAddVars when there are no variables, fixing a crash in MIP solvers for empty models. - Do not copy type of lhs onto rhs when parsing solutions. This tagged some literals as cv(), which broke the evaluation. - Fix flattening of all par set literals. - Fix error macro to be compatible with newer versions of Bison (:bugref:`389`). - Fix printing of if-then-else expressions without an else branch. - Fix allowed solvers option in test suite. - Make bind only create an int_eq constraint if a variable has a reverse mapper. - Fix automatic coercions to keep cv type attribute of their argument (:bugref:`387`). - Fix copying of output_only variables to the output model. - Only print checker output for unique solutions. - Fix rewriting of lin_exp into int/float_lin_eq. - Fix flattening of calls and let expressions that have par type but contain var expressions. - Use eval_bool instead of eval_par for boolean evaluation. - Remove the direct assignment to a domain if it has a reverse mapper. - Fix arg_max and arg_min for array index sets not starting at 1. - Add missing set_superset_reif FlatZinc predicate. - Fix counting of non-fixed variables in Boolean constraints. Could previously lead to incorrect simplifications. - Enable eval_floatset for SetLits that contain an IntSetVal. This is used during chain compression and could previously result in incorrect domains. - Fix bugs in chain compressor caused by modifying multimaps while iterating over them. - Fix crash when cleaning up after running builtin Gecode. - MIPdomains: don't assume equations have no literals. - Only fix domain after flattening bool_eq. - Only return singleton domain as value for non-optional variables. - When evaluating identifier that is bound to a fixed value, check that the value is inside the domain to correctly detect model inconsistency. - Add missing assert and trace builtin overloads. - Flatten expressions that may contain variables in par where clauses. - Fix segmentation fault when the declaration of an array is passed to setComputedDomains with the -g parameter. - Consider single-valued domain variables to be fixed - Add missing definition of to_enum for arrays of sets. - Evaluate partiality of arguments even if call was already in CSE table (:bugref:`374`). .. _v2.4.3: `Version 2.4.3 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 4 March 2020) .. _changes-1: Changes: ^^^^^^^^ - Enable CPLEX 12.10. - Add checker output to generated output items. - Short-circuit evaluation for mixed par/var conjunctions, disjunctions, and clauses. - Add inverse_in_range global. - Pretty printing set ranges now uses union instead of ++ to be compatible with DZN. - Add array2set for par bool and float arrays - The \_objective variable is no longer added to FlatZinc input files. - JSON representation of sets with ranges can now be parsed (previously they could only be output). - Check index sets to arguments of global_cardinality_low_up. - Xpress and SCIP are not compiled as plugins and no longer require recompilation to enable. - If-then-else for opt are no longer written in terms of the non-opt version, allowing them to return absent. .. _bug-fixes-2: Bug fixes: ^^^^^^^^^^ - Fix checking of domains and index sets in par arrays inside lets. - Remove duplicate call stack items to improve error messages. - Ignore absent values when computing domains. - Generate call for actual binary operator (after optimising double negation). Fixes :bugref:`364`. - Fix non-associative operators on optional values. - Only output optional parameters in model interface if they were undefined (rather than assigned to <>). - Fix some issues with evaluating par opt expressions. - Make solution checkers work for multi-dimensional arrays and arrays with enum index sets - Fix Boolean aggregation for expressions that are defined recursively. - Use correct index set for nosets set_lt and similar (partial fix for :bugref:`369`) - Fix coercion of sets to arrays (previously, coercing a set of X to an array of X to an array of Y did not work correctly). - Fix infinite loop when printing infinite set range - Add assertion so that array2set can only be used for arrays with bounds (:bugref:`370`, :bugref:`371`). - Fix typing and pretty printing of par bool sets. - Use output_array dims for output vars in FlatZinc files (previously, a type-checker error would occur when running a solver through MiniZinc on a FlatZinc file with multidimensional arrays). - The Xpress backend was made functional again. - Fix segmentation fault in output_only type-checking. - Compute correct array enum type for array slices (:bugref:`372`). - Fix behaviour of using undefined expressions in var comprehensions guarded against by where clauses (previously, these undefined expressions would bubble up regardless of the where clause, constraining the model). - IDE: Disable menu items that don't make sense when all tabs are closed, fix behaviour of stop button when all tabs closed (fixes several crashes). - IDE: Add x86_64 suffix to linux package name (:idebugref:`96`). - IDE: Make boolean extra solver options with a default of true functional. - IDE: Only read linter results if it exited normally (:idebugref:`97`). - IDE: Resolve paths in \_mooc to paths (allowing submission of models in subdirectories). .. _v2.4.2: `Version 2.4.2 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 10 January 2020) .. _changes-2: Changes: ^^^^^^^^ - The test suite is now integrated into the continuous integration system. .. _bug-fixes-3: Bug fixes: ^^^^^^^^^^ - Fix flattening of negated disjunctions (:bugref:`359`). - Fix simplification of Boolean constraints (repeated simplification could sometimes crash). - Fix memory management during flattening of conditionals (:bugref:`358`). - Fix type inference for rewriting of sums into count constraints, and only apply the rewriting for var type-insts. - Fix handling of solution checkers (these used to produce spurious error messages). - IDE: Fix syntax highlighting of keywords, and add syntax highlighting for interpolated strings. - IDE: Redraw when switching to/from dark mode, and fix dark mode header colours. - IDE: Fix "Select all" menu item. .. _v2.4.1: `Version 2.4.1 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 20 December 2019) .. _changes-3: Changes: ^^^^^^^^ - Improve compiler optimisation for some linear, multiplication and Boolean constraints. - Improved translation of lex and all_equal constraints when the arrays have no or only one variable. - IDE: Display error message when submission to MOOC provider fails. - IDE: Make "previous tab" and "next tab" actions cycle rather than stop at first/last tab. .. _bug-fixes-4: Bug fixes: ^^^^^^^^^^ - Fixed regular expression constraint for expressions containing negated character classes (^ operator). - Fix element constraint in nosets.mzn library when set domains are not contiguous. - Correctly identify Windows paths starting with // or \\\\ as absolute (this enables the parser to open files stored on network drives). - Use set_in constraints (rather than int_in) for internal Gecode-based presolver. This fixes some issues when compiling with -O3. - The optimisation phase of the compiler now fully substitutes par bool variables (these can be introduced into the FlatZinc during multipass compilation). (:bugref:`357`) - Fixed the reference counting for variables that are re-used in multipass compilation. (:bugref:`357`) - Remove incorrect error handling when parsing from strings rather than files. Partially fixes (:bugref:`357`) - Made the is_fixed builtin work for more types. (:bugref:`356`) - Enable rewriting of sum(i in x)(i=c) op d and count(x,y) op z into global counting constraints. - Split up count global constraints into separate files for reified versions. - Use contiguous range for array index set in set_lt for nosets.mzn. - Negate results of conditionals if required. (:bugref:`355`) - Partiality of conditional needs to be translated in root context (even if conditional itself is negated). (:bugref:`355`) - Don't copy function into output again if it was already copied (and made par) before. (:bugref:`323`) - Define card function on var sets in terms of set_card FlatZinc builtin. - Don't set bounds for set variables in internal Gecode presolver. - IDE: Fix shift left and shift right indentation behaviour when selecting text backwards. - IDE: Fix OpenSSL library in binary distribution to enable update checks and submission to MOOCs again. .. _v2.4.0: `Version 2.4.0 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 13 December 2019) .. _changes-4: Changes: ^^^^^^^^ - The compiler now detects counting constraints in expressions such as count(i in x)(i=3) <= 4 and rewrites them into global counting constraints. This is now the preferred way to specify counting. The atmost/atleast/exactly constraints on integer variables have been deprecated, and versions of count predicates with par variables have been added. FlatZinc solvers that supported atmost/atleast/exactly should now support the corresponding fzn_count\_?_par predicates. - The compiler now supports the command line option --output-detailed-timing, which provides timing information for each toplevel constraint item, or for each line of code when used in conjunction with the --keep-paths option. - The library now contains annotations for deprecated library functions. - A par version of the inverse function has been added (include inverse_fn.mzn to use it). - The common case of sums of optional variables is now handled more efficiently. This case often arises from generator expressions with variable where clauses. - Added set_to_ranges built-ins to enable efficient iteration over sets. These are used to implement set_in for float variables, which was missing before. - The Gurobi and CPLEX backends now support the --random-seed command line option. - The Gurobi and CPLEX backends now use nodefile for search trees exceeding 500 MB (--nodefilestart can change this value and --nodefiledir the folder.) - The MIPDomains optimisations have been switched back on by default. The optimisations have also been strengthened for some special cases. - Without the MIPdomains postprocessing, linearisation of variable domains with holes now uses set_in instead of individual not-equal constraints, which may result in more compact FlatZinc. - Linearisation of multiplication can now consider the exact domain of a factor. - The product functions have been made non-recursive in order to support longer arrays. - Bounds inference for results of if-then-else expressions has been improved. - Support for optional float variables has been added. - The interfaces to CBC, CPLEX and Gurobi now report correctly that they support verbose output during solving (so that the "verbose solving" option is available from the MiniZinc IDE). - IDE: Parse timing and statistics output produced by compiler, and display as profiling information next to each line in the model. - IDE: Enable run/compile action on data files. This automatically selects the model file if there is only one, or presents a dialog for selecting the model if there are multiple. - IDE: Select first data file in parameter dialog if there was no previous selection, and always focus parameter dialog. - IDE: Highlight current line. - IDE: Support .json as file extension for data files. - IDE: Remember whether wrap around, case sensitivity and regular expression was selected in find/replace dialog, pre-select the find/replace text when find/replace widget is openend, and close find/replace widget when ESC is pressed while editor has focus. .. _bug-fixes-5: Bug fixes: ^^^^^^^^^^ - Fixed output handling on Windows (output is now processed on the main thread, so that exceptions thrown during output are printed correctly, and memory management is thread safe). - Fixed decomposition of reified mdd constraint, and strengthened decompositions of mdd and cost_mdd. - Fix handling of variable re-definitions (e.g. converting sets to arrays of bools), which would previously sometimes result in variables being removed although they were required for output, or the reverse mapping function not being available in the output model. - Include regular.mzn from regular_regexp.mzn. (:bugref:`351`) - Inlining of function calls has been moved from the flattener into the type checker, and it now is more strict about which functions can be inlined in order to avoid overloading issues. - Updated fzn_count_{neq,leq,lt,geq,gt}, fzn_global_cardinality_low_up{,_reif} to use use the count_eq predicate. (:bugref:`334`, :bugref:`335`) - Fixed the documentation for several constraints, which did not display as bullet point lists as intended. - Copy function/predicate declarations into FlatZinc without annotations, since most FlatZinc parsers would not expect annotations and fail to parse. - Process right hand side of par VarDecls to make sure any identifiers it uses are copied into the output model. Fixes :bugref:`336`. - Fix type checking for conditionals where the else branch has enum type but the then branch has int type. - Make the deopt function return correct enum instead of int type. - Fix for path handling when 'needRangeDomains' is active. Avoids infinite recursion in the compiler. - Fix race condition in temporary file generator for Windows. (:bugref:`349`) - Register fzn\_ names for Gecode presolver. Fixes command line flags -O3 and above. - Fix par evaluation of float and bool set comprehensions. - Fix documentation of array_bool_xor. Fixes :docbugref:`13`. - Fix the round() built-in to correctly round negative numbers - Fix computation of intersection of domains when assigning an array to an array variable. Fixes :bugref:`310`. - Add defines_var annotations for functional global constraints. Fixes :bugref:`345`. - Add set_lt_reif/set_le_reif to flatzinc builtins library. Fixes :bugref:`338`. - Clarify set order based on spec. Fixes :bugref:`339`. - Don't return already removed VarDecl objects from CSE. Fixes :bugref:`346`. - Do not post y!=0 constraint if 0 is not in the domain (workaround for a limitation in the handling of basic float constraints). Fixes :bugref:`344`. - Help type checker by making deopt/occurs argument types explicit. Fixes :bugref:`331`. - Fix transfer of domains when aliasing one variable to another - MIP: fix for aux_float_ne_if_1 - MIP: int_(eq/ne)_imp: don't force eq_encode without MIPdomains - Fix a typo in the definition of fzn_at_least_int{,_reif} - Fix dependency problem in the gecode_presolver table specification - Add seq_precede_chain.mzn to globals.mzn. Fixes :bugref:`332`. - Don't assign right hand side of set variables if domain is singleton. Fixes :bugref:`330`. - Don't invalidate float bound just because an expression contains an integer. - Fix copying of let expressions. - Put lexer and parser helper functions into MiniZinc namespace to avoid linker issues. Fixes :bugref:`325`. - Reset array index sets defined in lets inside recursive function calls. - Arrays copied into output model need to have par type-inst. Fixes :bugref:`322`. - Don't complain when same function is registered twice. Fixes :bugref:`323`. - Fix partiality handling of if-then-else expressions. - Track whether variable is used in an output array before making decision to compress implication chains. Fixes :bugref:`318`. - IDE: Fix dark mode detection on macOS 10.15, improve dark mode colors a bit and fixed some dark mode bugs. - IDE: Make background compilation of a model (used to display syntax and type errors) a bit more stable. - IDE: Avoid infinite loop in wrap around replace all. - IDE: Fix memory management for HTML visualisation windows, and resize docked HTML visualisation widgets to take up equal space. .. _v2.3.2: `Version 2.3.2 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 12 September 2019) .. _changes-5: Changes: ^^^^^^^^ - Add warm starts and subtour cuts to CBC interface. - Add documentation and assertion requiring that mdds are deterministic, and add nondeterministic variant of mdd constraint. - Add -s to the standard flags supported by MIP interfaces. - Add flag --output-output-item to include user specified output item in the formatted JSON and DZN output. .. _bug-fixes-6: Bug fixes: ^^^^^^^^^^ - Fix a bug that could leave unused variables in the resulting FlatZinc. - bounded_dpath should rewrite to fzn_bounded_dpath. Fixes :bugref:`300`. - Fix definition of sum_set. - Check if overloaded function required for output. Fixes :bugref:`303`. - Move regular constraint with set argument to its own file. - Flatten assignment generators if necessary. - Simplify fzn_value_precede_chain_int and avoid use of element predicate. Fixes :bugref:`307`. - Only initialise par opt variables as absent if they are not arrays. - Fix the description of the neural_net predicate. - Fix regular constraint with regular expressions (stopped working in 2.3.0). - Fix the model interface output to include the same variables as the generated output statement. - Fix CSE for removed variable declarations. Could lead to reified constraints not being compiled correctly when the control variable got fixed to true. .. _v2.3.1: `Version 2.3.1 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 10 July 2019) .. _bug-fixes-7: Bug fixes: ^^^^^^^^^^ - Report error when trying to assign an array literal to an array variable with incompatible index set. - Fix partial evaluation of expressions, so that only par expressions are fully evaluated. Fixes :bugref:`298`. - Remove carriage returns when reading piped solver output on Windows. - Canonicalize paths of executables to avoid spurious warnings about multiple executables for the same solver. - Add implementations for != on arrays. - Compute quotient bounds before decomposition of int_div in linearisation library. - Propagate domain constraints on variables that are aliased (previously domain constraints could get lost). - Propagate domain constraints from left-hand-side to right-hand-side in variable assignments. - piecewise-linear: reuse decomposition for X when only Y-values change. - nosets: add set_in_imp(var set) and simplify set_in_reif, set_eq(var set, var set). - linearisation: improved compilation of set_in constraints. - MiniZinc IDE: Remove incorrect symbolic link and fix qt.conf for some bundled distributions. - MiniZinc IDE: Fix check for availability of dark mode on older versions of macOS. - MiniZinc IDE: Fix a typo in the cheat sheet. - MiniZinc IDE: Provide more robust solution for checking the model parameters, which will get rid of some "internal error" messages. - MiniZinc IDE: Always show directory selection dialog in the Windows installer. Addresses :idebugref:`89`. - MiniZinc IDE: Improved the configuration files for some bundled solvers, provides nicer configuration interface. .. _v2.3.0: `Version 2.3.0 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 26 June 2019) Major changes: ^^^^^^^^^^^^^^ - The compiler can now generate FlatZinc with half reified constraints. See https://www.minizinc.org/doc-2.3.0/en/fzn-spec.html#reified-and-half-reified-predicates for more details. - The standard library of global constraints has been reorganised, making it easier for solvers to override just the bits that they support. See https://www.minizinc.org/doc-2.3.0/en/fzn-spec.html#solver-specific-libraries for more details. - There is experimental support for solvers that can read AMPL NL files. See https://www.minizinc.org/doc-2.3.0/en/solvers.html#non-linear-solvers for details. .. _minor-changes-1: Minor changes: ^^^^^^^^^^^^^^ - The JSON input and output has been improved, with full support for enums and optional types. - A new compiler option -g has been added, which turns variable domain changes into constraints (useful for debugging models). - The SCIP interface has been updated, with support for indicator constraints, bounds disjunctions and a native cumulative constraint. - Error reporting has been improved, with location information available for errors in par float expressions as well as include items. - The timeout command line parameter now also applies to compilation itself (:bugref:`281`). - Operations on par float values are now checked for overflows. - The arg_min/arg_max constraints have been improved, with new special versions for Boolean variables, and a better standard decomposition. - if-then-else-endif expressions with variable conditions are now compiled to a predicate call (rather than handled by the compiler), which enables solver libraries to implement these as native constraints or special decompositions. - Dividing a variable by a constant is now translated as a multiplication (to keep the constraints linear). - A new piecewise_linear predicate has been added to the library to make it easier to specify piecewise linear constraints. - Print number of solutions as mzn-stat after solving (:bugref:`244`). - Make search annotations work for arbitrary array index sets. - MiniZinc IDE: The IDE will now check MiniZinc code for syntax and type errors, and the editor performs simple code completion for MiniZinc keywords - MiniZinc IDE: The find/replace dialog is now an inline widget and supports incremental search. - MiniZinc IDE: Now supports dark mode on macOS. - MiniZinc IDE: Add support for extra solver flags (parsed from solver configuration). .. _bug-fixes-8: Bug fixes: ^^^^^^^^^^ - Translate let expressions that contain constraints or variables as var type-inst. Fixes :bugref:`263`. - Fix JSON array parsing by counting elements instead of commas. - Fix parsing of the -p flag (:bugref:`271`). - Fix type checking for array declarations with single enum type inst identifier. E.g. array[$$T] of $U previously matched any multi-dimensional array, and now only matches one-dimensional arrays with any enum index set. - Fix computation of function return type when using type inst variables (:bugref:`272`). - Evaluate each variable declaration only once in a par let expression. - Check domain constraints on variable declarations in par let expressions. - Try .exe/.bat on windows when using (constructed) absolute paths. - Fix array slicing to support empty slices (:bugref:`275`). - Fix a bug in the parser that could cause crashes on certain syntax errors. - Fix the type of bool2int for arrays. - Initialise counter for introduced variable ids based on names in original model. This avoids reusing variable names if the user model contains names such as X_INTRODUCED_0\_. - Fix compilation of nested clause/exist constraints, and improve handling of negation. Tries to use primitive negation instead of creating negated constraints. Should help with half-reification by creating more positive contexts. - Reorder fields in basic data structures to reduce padding on 64 bit platforms (improved memory footprint). - Perform type coercion after desugaring array slicing. - Translate arguments to bool2int, exists, forall in positive context even if those functions are redefined. - Don't evaluate par array literals twice (inefficient, and can lead to incorrect results when using random number generators). - Terminate child processes when minizinc process is terminated by signal. - Fix function return value array index check for empty arrays (:bugref:`286`). - Fix translation of constant false where clause in array comprehension. - Report error when json multi-dimensional array is not rectangular. - Check index sets of function arguments (:bugref:`273`). - Ignore partiality variables from CSE table when compiling \_reif and \_imp predicates (:bugref:`269`). - Flatten comprehensions with variable generators or where conditions before evaluating any par functions on them (:bugref:`259`). - Add missing redefinitions of basic operators and search annotations for optional integers. - Resolve filenames given on the command line relative to working directory, and warn if file in working directory has same name as included file from the library. Fixes :bugref:`276`. - Update nosets library with a valid redefinition of set_less over booleans. - Fix translation of showJSON (:bugref:`294`). - Only apply set2array coercion for supported types, otherwise report error (:bugref:`295`). - Improve special case reasoning for abs on strictly negative variables. - Add bounds for floating point min/max result in the standard library. - MiniZinc IDE: Ensure cursor is visible (editor scrolls to cursor position) when pressing tab or enter. Fixes :idebugref:`71` :idebugref:`71`. - MiniZinc IDE: Re-dock configuration editor when closing un-docked window. - MiniZinc IDE: Handle quotes when parsing additional solver command line arguments. Fixes :idebugref:`77`. - MiniZinc IDE: Add workaround for the missing libnss requirements. Fixes :idebugref:`79`. - MiniZinc IDE: Allow spaces in $DIR in MiniZincIDE.sh Fixes :idebugref:`81`. .. _v2.2.3: `Version 2.2.3 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 31 October 2018) .. _bug-fixes-9: Bug fixes: ^^^^^^^^^^ - Fix some typos in the library documentation. - Fix solution checking. - Fix line numbers in parsed locations on 64 bit platforms. - Fix bounds computation for calls. - Fix translation of var where clauses with more than 3 par components. - IDE: Only run solution checker if it is enabled in the solver configuration dialog. .. _v2.2.2: `Version 2.2.2 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 26 October 2018) .. _changes-6: Changes: ^^^^^^^^ - Some changes to the optimisation phase of the compiler, to take into account more variables and constraints. - Preliminary support for MIP cuts based on graph algorithms (only available when compiled with boost C++ libraries; not part of the binary distribution). - Set Release as default build type when nothing is specified (for CMake platforms that do not support multiple build types, like Makefiles). - Add builtins outputJSON() and outputJSONParameters() for creating an array of strings that capture the output and parameters of the model as JSON. - On Linux and macOS, add /usr/share/minizinc/solvers and /usr/local/share/minizinc/solvers to list of paths where solver configuration files can be placed. - Add OSICBC_INCLUDEDIR and OSICBC_LIBDIR cmake flags. - Output search paths for solver configurations using --solvers command line option. - Add support for Gurobi 8.1 - Support parsing from stdin and files at the same time. - IDE: Add line/column display in status bar. - IDE: Optional parameters don't have to be defined in input dialog. - IDE: Provide mzn-json-init / mzn-json-init-end handlers to initialise HTML window before first solution is produced. - IDE: Add version information and minimum system version into Info.plist on macOS. - IDE: Manage multiple open visualisation windows, and implement re-solve function that can be initiated from a visualisation. - Binary bundle: Gecode updated to version 6.1.0, Chuffed updated to version 0.10.3 .. _bug-fixes-10: Bug fixes: ^^^^^^^^^^ - Fix crash when flattening top-level array comprehensions with var where clauses. - Support input files with more than 1M lines. - Special case handling for array literals in top-level foralls: flatten in root context. - Fix translation of if-then-else for branches with undefined right hand sides. - Only propagate defines_var annotation to the variable that's actually being defined (not others that arise from the same decomposition). - Don't flatten arguments of predicates like symmetry_breaking_constraint. - Remove output_var and output_array annotations from user models (these could cause crashes). - Fix precedences for weak operators (~+, ~-, ~=, ~*). - Fix min and max for opt var arrays to work when the bounds of the arrays are unknown. - Fix a bug in bounds computations for function calls. - Add missing superset FlatZinc builtin. - Fix includes in file values.hh for some platforms. - Fix a garbage collection issue when printing solutions. - Deal with the case that a variable that's required for output is assigned to a par variable. - Throw type error when an array has only absent values. - Flatten all arrays in FlatZinc, also those coming from functional definitions. - Use list of strings as mzn_solver_path entry in the preferences json file. - Fix crash when output variable is defined using recursive function - IDE: Fix race condition in constructor of HTMLWindow. .. _v2.2.1: `Version 2.2.1 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 6 September 2018) .. _changes-7: Changes: ^^^^^^^^ - all_different, all_equal, {int,set,float,bool}_search now accept multi-dimensional arrays. - Add exponentiation operator (^). - Improve layout of generated library documentation for some constraints. - Relax typechecking to allow assignment of empty array ([]) to multi-dimensional array variables. This is required to make empty arrays work in JSON data files. - Enumerated types can now be initialised using lists of strings. This enables enumerated type support in JSON. .. _bug-fixes-11: Bug fixes: ^^^^^^^^^^ - Cumulative constraint for linear solvers now accepts empty arrays. - show2d/show3d functions now do not add quotes around array elements and work for empty arrays. - Add support for slicing of arrays with enumerated types. - Fix slicing of 1d arrays. - Fix bounds computation for float variable declarations. - When FlatZinc solver is terminated due to a timeout, do not report this as an error. - Fix pretty-printing of multi-dimensional arrays where dimensions other than the first one are empty. - Add support for where clauses on generator assignment expressions. - MiniZinc IDE: Improve dark mode by changing line numbers to dark background. - MiniZinc IDE: Make parameter input dialog scrollable. - MiniZinc IDE: Fix solution compression limit, and output one solution per block of compressed solutions. .. _v2.2.0: `Version 2.2.0 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 24 August 2018) This is a major release of MiniZinc, introducing many new features and improvements. Major new features: ^^^^^^^^^^^^^^^^^^^ - **New minizinc command line tool** Previous releases contained a ``minizinc`` command line tool that was not much more than a simple script that could execute the compiler, solver and output processor. The ``minizinc`` executable in version 2.2.0 is now the main frontend to compilation and solving and integrates all of the functionality. It has access to all installed MiniZinc solvers (both internal solvers and those interfaced through FlatZinc files), and can automatically select the required options (e.g., to include the solver-specific MiniZinc globals library). You can get a list of available solvers using the ``--solvers`` command line option, and select a solver using ``--solver``. The ``minizinc`` executable can now also be used as a replacement for ``mzn2fzn`` (using ``-c``) and ``solns2out`` (using ``--ozn-file``). - **Multi-pass compilation** The compiler can now perform multiple passes in order to improve the target FlatZinc code. This can be controlled using the ``-O`` command line flags (``-O0`` to ``-O4``). Multi-pass compilation is particularly useful when the target solver requires sophisticated decomposition of global constraints (such as for MIP solvers). - **Solution checking** You can now supply an additional model that will be used to check each solution produced by your main model. This can be useful for teaching MiniZinc (to give students automatic feedback) and if your main model is very complex but checking that a solution is correct is easy. - **MIP solvers:** support for FICO Xpress, and loading IBM ILOG CPLEX as a plugin We have added support for FICO Xpress (this requires compiling MiniZinc from sources). CPLEX can now be loaded as a plugin, which means that the binary distribution of MiniZinc has built-in CPLEX support (just bring your own CPLEX dll). - **Language extensions** The MiniZinc language has been extended with two new features. - Array slicing introduces syntax to conveniently select rows, columns or entire slices of arrays. For example, ``x[3,..]`` selects the third row of array ``x``, while ``x[..,4]`` selects the fourth column, and ``x[3..5,2..7]`` selects a slice of rows 3 to 5 and columns 2 to 7. - Generator expressions can now contain multiple where clauses, e.g. ``forall (i in S where foo(i), j in T where i < j) (bar(i,j))`` This enables more efficient compilation compared to evaluating all where clauses in the inner-most generator. In addition to iteration (``i in S``), generators can now contain assignment expressions (``j=foo(i)``). This enables intermediate definitions that can then be used in further generators. Changes and minor features: ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - The value of the objective can now be added automatically to the output using the ``--output-objective`` command line option. Using ``--output-mode dzn``, this allows automatic output of all the free variables of the model. - Models that do not contain a solve item are now accepted and treated as ``solve satisfy`` - Support for naming constraints and expressions (using ``::"name"`` syntax) - Error messages have been improved, they now contain more accurate location information. - The compiler can be instructed to accept multiple assignments to the same parameter (as long as they are all identical), using the ``--allow-multiple-assignments`` command line option. - Annotations for supplying warm start values have been added to the standard library (currently supported by the MIP solvers Gurobi and IBM ILOG CPLEX). - The compiler now accepts multiple .mzn files as input. - Memory consumption and garbage collection performance has been improved. - The conditional expression has been extended to support ``if then endif`` (where ```` is bool) - Decomposition of one variable type to another (e.g. set into array of bool) has been improved. - MIP solvers Gurobi and IBM ILOG CPLEX use node files when over 3GB working memory - Gurobi and CPLEX support the MIPfocus parameter - Gurobi supports MiniZinc search annotations by setting fixed branching priorities .. _bug-fixes-12: Bug fixes: ^^^^^^^^^^ Consult the bug tracker at https://github.com/MiniZinc/libminizinc/issues .. _v2.1.7: `Version 2.1.7 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 10 January 2018) .. _changes-8: Changes: ^^^^^^^^ - Improved linearisation for some element constraints. - Improve performance of optimisation phase by using a queue instead of a stack. - Add --dll option for Gurobi backend to specify the Gurobi DLL to load. - Add more defines_var annotations. .. _bug-fixes-13: Bug fixes: ^^^^^^^^^^ - Fix generation of variable names in output model (sometimes could contain duplicates). - Fix enum type inference for array literals with empty sets as their first arguments. Fixes :bugref:`180`. - Fix incorrect simplification of float domain constraints. Fixes :bugref:`159`. - Fix ceil builtin for float values. - Add superset decomposition for solvers that do not support set variables. - Fix three bugs in the garbage collector. - Fix a bug in flattening that would create duplicate variables when a variable declaration referred to another one in its type-inst. - Fix a crash in flattening of partial functions. Fixes :bugref:`187`. - Add missing deopt builtins for all par types. - Fix output for arrays of sets of enums. - Define more functions on par opt types. Fixes :bugref:`188`. - Fix type checker to accept arrays of opt set values. - Support printing of opt enum types. Fixes :bugref:`189`. - Fix evaluation of comprehensions in recursive functions. - Fix output of Gurobi backend when used in conjunction with solns2out. - Fix pthread linking for mzn-cbc. - Catch type error when set literal is declared that contains another set. IDE changes and bug fixes: ^^^^^^^^^^^^^^^^^^^^^^^^^^ - Fix problem where files with a . in the filename could not be run. - Fix font settings (were not saved reliably on some platforms). - Enable generic interface for submitting assignments (not just to Coursera). - Fix output handling for solvers that do not run mzn2fzn. - Fix hidden solution display when there are exactly as many solutions as the configured threshold for hiding solutions. - Add configuration option to print timing information for each solution. .. _v2.1.6: `Version 2.1.6 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 22 September 2017) .. _bug-fixes-14: Bug fixes: ^^^^^^^^^^ - Fully evaluate parameters before binding formal arguments when evaluating call expressions. Fixes :bugref:`177`. - Fix incorrect simplification of Boolean constraints assigned to variables that are assigned to false. - Fix bug in flattening of linear equations that contain the same variable on both sides. - Fix un-trailing for let expressions, which could sometimes cause incorrect code to be emitted when lets are evaluated in nested loops. Fixes :bugref:`166`. - Fix bug in JSON output of one-dimensional array literals. - Fix unification of enum type-inst variables. .. _v2.1.5: `Version 2.1.5 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 17 May 2017) .. _changes-9: Changes: ^^^^^^^^ - Some improvements to the linearisation library. - Make parser read multiple .mzn files correctly. - Enable better bounds computation for array access expressions on fixed arrays. - Perform better constant folding during optimisation phase. Fixes :bugref:`155`. - Don't rewrite pow function into multiplication in the case of power of 2. - Save some memory by making certain internal data structures more compact. - Improve source code location of identifiers in generator calls (should give more precise error messages). - Produce an error message when a comprehension attempts to iterate over an infinite set. - Produce better error messages for operations on infinite values (previously some errors did not contain a source code location). - Speed up garbage collection by pre-allocating some memory. .. _bug-fixes-15: Bug fixes: ^^^^^^^^^^ - Fix range check for float literals in arrays. - Fix a bug where a constraint could be removed incorrectly. Fixes :bugref:`150`. - Include variables for dzn and json output from all included models, not just the main model. Fixes :bugref:`153`. - Produce multi-dimensional arrays in json output. Fixes :bugref:`156` and :bugref:`157`. - Remove incorrect closing bracket from json output. Fixes :bugref:`154`. - Fix bounds computation of par int and float arrays. - Don't allow var access to arrays of strings or annotations (since that would require an element constraint and var string / var ann types). - Introduce int2float constraints where necessary for some linearisations. .. _v2.1.4: `Version 2.1.4 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 13 March 2017) .. _changes-10: Changes: ^^^^^^^^ - Add warning for MIP solvers that do not support -a option for satisfaction problems. - Print introduced variable names with additional underscore to make debugging FlatZinc easier. Fixes :bugref:`147`. - Add support for pow function in linearisation library. - Add support for parallel solving with CBC. - Flatten top-level conjunctions in the order defined in the model. .. _bug-fixes-16: Bug fixes: ^^^^^^^^^^ - Fix major race condition that would crash the IDE when it didn't detect that a solver process had finished. - Improve HTML output in the IDE by making sure every line is terminated by a newline. - Fix a garbage collection bug that could cause dangling pointers when expressions were copied. - Fix type checker to allow empty arrays to be assigned to variables declared as arrays of enums. - Fix infeasibility check in MIP translation for some inequality constraints. - Improved defines_var annotations for reified xor constraints. Fixes :bugref:`146`. - Fix output of empty integer sets and deal with empty arrays in output models. - Fix MIP translation when boolean variables were removed due to aliasing. - Improve corner cases for linearisation of cumulative constraint. - Properly report undefinedness in par bool expressions. - Enable some additional constant folding during flattening. Fixes :bugref:`149`. .. _v2.1.3: `Version 2.1.3 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 6 February 2017) .. _changes-11: Changes: ^^^^^^^^ - Remove more internal annotations from the generated FlatZinc. - Detect failure earlier if optimisation pass leads to fixing of variables outside their domains. .. _bug-fixes-17: Bug fixes: ^^^^^^^^^^ - Fix CBC backend to correctly print UNSAT message for models where the compiler already detected unsatisfiability, and print solution separators even where there is no other output. - Add missing var_dom function for arrays of optional integer variables. Fixes :bugref:`133`. - Fix aliasing for optional integer variables. Fixes :bugref:`132`. - Remove all annotations from output model. - Fix computation of return type for functions that return arrays of enums. - Don't output newline if user-defined solution separator or status message is empty - Fix return type computation for functions where return type contains enums. - Check finiteness of float literals and bounds. Fixes :bugref:`138`. - More checks for function return values. Fixes :bugref:`136`. - Fix var int comprehensions (now triggers error message instead of crash for var set of int comprehensions). Fixes :bugref:`135`. - Fix output of variables with quoted identifiers. - Fix flattening of let expressions that contain variables with undefined (i.e., partial) right hand side. - Make printing of error messages to stdout or stderr more consistent across executables. - Fix type checking of initialisation of enum types. - Improve error messages for array access and index set errors. Fixes :bugref:`131`. - Fix definition of multi-dimensional element constraints to impose correct bounds on index variables. - Fix binding analysis during type checking, which did not handle the shadowing of top-level declarations by comprehension generators correctly. Fixes :bugref:`129`. .. _v2.1.2: `Version 2.1.2 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 20 December 2016) .. _bug-fixes-18: Bug fixes: ^^^^^^^^^^ - Fix a bug in the type checking for generators that iterate over arrays of enums. - Fix a bug in the output handling of arrays of enums. - Fix handling of multiple output items (only the last item was compiled, now the concatenation is used for output as defined in the specification). .. _v2.1.1: `Version 2.1.1 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 14 December 2016) .. _changes-12: Changes: ^^^^^^^^ - Add missing min/max functions for set variables. Can be redefined to solver builtins using the new redefinitions-2.1.1.mzn library file. - Add support for option type expressions as objective functions. - Automatically coerce arrays constructed using ++ to any enum index set (in addition to array literals and comprehensions). .. _bug-fixes-19: Bug fixes: ^^^^^^^^^^ - Include cmath header to fix compilation issues with some compilers. Fixes :bugref:`125`. - Fix a garbage collection bug in the type checking for enumerated types that would sometimes lead to crashes or incorrect error messages. - Fix type checking of comprehensions that involve enumerated types. - Fix bounds computation for var sets of enumerated types. - Support anon_enum function as documented. .. _v2.1.0: `Version 2.1.0 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 17 November 2016) .. _changes-13: Changes: ^^^^^^^^ - MiniZinc now supports enumerated types. - Solvers can be interfaced directly to the MiniZinc library, and MiniZinc comes with direct support for the CBC, Gurobi and CPLEX MIP solvers. - The linearisation library has been updated, resulting in much better FlatZinc being generated for MIP solvers. - Data files can be in JSON format, and MiniZinc can produce JSON output (using the --output-mode command line option). - Variables can be annotated as ::add_to_output instead of writing an output item. - The compiler can output information about the parameters and output variables of a model (using the --model-interface-only option). - Floats are handled better (detecting infinities and handling sets of floats). - Bounds can be computed for more expressions (instead of failing with an error message). .. _bug-fixes-20: Bug fixes: ^^^^^^^^^^ - Fix a bug in optimization that could remove variables even if they are used. Fixes :bugref:`123`. - Fix float variable declarations with sets of floats as domains. Fixes :bugref:`117` and :bugref:`98`. - Fix type checking and evaluation of asserts with array arguments. Fixes :bugref:`109`. - Fix abs(var float) declaration to work on floats without declared bounds. Fixes :bugref:`106`. - Fix a bug in the computation of int and float bounds that could result in incorrect bounds in some cases. Fixes :bugref:`94`. - Fix garbage collection when creating output models. Fixes :bugref:`77`. - Fix binary operators on optional variables (in some cases comparison operators were reversed). - Fix optimization of unconstrained variables (could sometimes lead to constraints being removed although they were not subsumed). .. _v2.0.14: `Version 2.0.14 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 31 July 2016) .. _changes-14: Changes: ^^^^^^^^ - Less aggressive aggregation of linear expressions in cases where it leads to much less efficient FlatZinc. - Don't create temporary variable for an array literal if it is discarded immediately anyway. - Only create new partiality variable for if-then-else expression if there's at least one var condition. - Replace recursive definitions of array_intersect and array_union with iterative ones. .. _bug-fixes-21: Bug fixes: ^^^^^^^^^^ - Don't report warnings about partiality when using extended generator expressions. - Include cmath to enable building with some versions of gcc. - Constrain result of function call based on function return type if necessary. - Make sure linear expressions generated during binding of variables are properly flattened (including simplification of the linear expression) .. _v2.0.13: `Version 2.0.13 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 26 March 2016) .. _bug-fixes-22: Bug fixes: ^^^^^^^^^^ - Fix a bug in the Common Subexpression Elimination table of the compiler, which could lead to some constraints being dropped (especially when using linear redefinitions). - The output model sometimes did not include all required definitions, in particular when array declarations used identifiers to specify the dimensions. - The generated FlatZinc sometimes still contained bool variables that were not connected to the rest of the model, which could produce incorrect solutions being printed. - Fix a bug where warnings (e.g. about partial functions) could lead to crashes. - Fix the bounds computation for integer and float variables, which could produce incorrect bounds for linear expressions. Fixes :bugref:`94`. - Fix a bug in the IDE that caused solver output to be shown incompletely in some cases. .. _v2.0.12: `Version 2.0.12 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 25 February 2016) .. _changes-15: Changes: ^^^^^^^^ - Partial functions are now always evaluated in their Boolean context, independent of whether they are par or var. If the result of a partial function is statically known to be undefined (such as division by zero or array access out of bounds), and it is used in a constraint expression, this now results in a warning instead of an error. Warnings can be turned off using the ::maybe_partial annotation. Fixes :bugref:`43` and :bugref:`74`. .. _bug-fixes-23: Bug fixes: ^^^^^^^^^^ - Fix a bug in the optimisation phase related to unification of aliased variables. - Fix short-circuit evaluation of Boolean expressions. - Fix a bug in the optimisation phase related to repeated simplification of some Boolean expressions. - Handle errors in output produced by solver without solns2out crashing. Fixes :bugref:`80`. - Fix a bug in the integer bounds computation that caused bool2int with an embedded conditional to crash. - Fix a problem with short-circuit compilation of == expressions when one side was a var opt bool. - Stop compilation when model is failed. Fixes a bug where mzn2fzn would sometimes not clean up the FlatZinc enough for the solver. .. _v2.0.11: `Version 2.0.11 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 15 January 2016) .. _bug-fixes-24: Bug fixes: ^^^^^^^^^^ - Fix parsing of hex and octal literals. Fixes :bugref:`71`. - Fix compilation of extended comprehensions. Fixes :bugref:`72`. - Fix computation of float array access bounds. - Fix aggregation of clauses (could sometimes ignore the negative literals). .. _v2.0.10: `Version 2.0.10 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 9 December 2015) .. _bug-fixes-25: Bug fixes: ^^^^^^^^^^ - Fix a bug in the optimiser that could lead to undefined variables in the generated FlatZinc. Fixes :bugref:`70`. .. _v2.0.9: `Version 2.0.9 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 6 December 2015) .. _bug-fixes-26: Bug fixes: ^^^^^^^^^^ - Need to take return type into account when copying functions to output model. Fixes :bugref:`55`. - Evaluate calls that result in arrays using eval_arraylit. Fixes :bugref:`57`. - Move inverse function to its own library file, so that it remains available when a solver provides an alternative for the inverse predicate. - Optimisation phase now recursively checks constraints when elements in an array become fixed. - Fix CMakeLists file to work for paths that contain spaces. - Distinguish between infix operators and regular functions in the generated html documentation. Fixes :bugref:`61`. - Made parser more robust against incorrect code. - Fix increment/decrement operators for IntVals and make all operations throw correct overflow exceptions. - Fix automatic type coercion for variables declared in let expressions. - Fix a crash when printing some error messages. - Fix compute_div_bounds builtin to return correct result for a division by zero. - Fix optimisation of Boolean constraints to use pointer equality instead of structural equality (same expression can occur multiple times in the FlatZinc). - Only optimise constraints that have not been removed yet. - Fix declaration of functional version of bin_packing_load. Fixes :bugref:`64`. - Set type of arrays returned from polymorphic functions. Fixes :bugref:`65`. - Fix parsing of quoted unary operator calls. - Only compute set functions when bounds are valid. Fixes :bugref:`66`. - Compute proper bounds for if-then-else expressions. - Report error when no reified version of a constraint is available. Fixes :bugref:`67`. - Fix type checking of annotations on binary operators. - Keep annotations when rewriting linear constraints and remove is_defined_var annotations from fixed variables. Fixes :bugref:`69`. .. _changes-16: Changes: ^^^^^^^^ Integer, Boolean and float literals are now cached to achieve better memory performance for some models. Improve performance of parsing integer literals. Improve handling of clause constraints. Add source files of MiniZinc specification to the repository. Limit maximum array size to enable better error messages. Add implied_constraint predicate as a synonym for redundant_constraint. .. _v2.0.8: `Version 2.0.8 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 19 October 2015) .. _bug-fixes-27: Bug fixes: ^^^^^^^^^^ - Fix incorrect negation of some reified comparisons. - Make lb/ub functions work in more cases. - Fix several bugs in the optimisation phase (could lead to incorrect FlatZinc and crashes). - Fix a problem with reverse mapper functions when the result of the reverse mapper can be fixed to a constant. .. _v2.0.7: `Version 2.0.7 `__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (released 5 October 2015) .. _changes-17: Changes: ^^^^^^^^ - Improved propagation of Boolean constants in the optimisation phase. This should result in far fewer aliases and improves simplification of conjunctions, disjunctions and clauses. - Add special case handling for integer division by 1. .. _bug-fixes-28: Bug fixes: ^^^^^^^^^^ - Fix FlatZinc generator phase, need to turn all array literal arguments into 1-based single dimensional arrays. - Fix compilation of if-then-else expressions with var conditions (which didn't implement proper partiality/totality semantics). Fixes :bugref:`42`. - Provide correct bounds for weak opt var arithmetic. Fixes :bugref:`51`. - Need to be able to handle unflattened annotations. Fixes :bugref:`53`. - Fix generation of output model (needs to ignore items that have been removed previously). - Add missing lb(var set of int) builtin. Fixes :bugref:`47`. - Check that var set declarations have a finite element type. Fixes :bugref:`46`. - Fix translation context for binary operators on arrays. - Need to access IntVal::infinity as a function, otherwise depending on linker etc it may become 0 in some cases. Fixes :bugref:`40`. - Change pretty printer to use one less digit when printing float literals. This fixes :bugref:`41` (or at least provides a workaround), but some double constants may still be rounded incorrectly when pretty printing and reading them back in. The real fix will be to output hex float literals (coming soon). - Distinguish between generalised comprehensions (iterating over sets) and iterating over arrays. Fixes compilation of comprehensions where iteration over an array is combined with var where clauses. Fixes :bugref:`45`. - Fix bug in creation of output model where sometimes chains of variable definitions could lead to crashes. - Avoi creating mutually recursive definitions in some corner cases, which could cause the compiler to run into infinite loops. - Don't copy vardecl items to output model that are already there. Fixes :bugref:`44`. - Remove domain from array declarations in FlatZinc (avoids problems with domains where holes need to be removed and when there are infinities in the domains) - Fix flattening of equality operator between non-opt and opt vars. - Check that model contains a single solve and output item during type checking (previously, multiple output items were not detected and resulted in incorrect .ozn files). - Fix flattening of xor (arguments need to be in mixed context). - Use is_fixed in cumulative definition. - Fix bug where a par right hand side of a variable mentioned in the output would cause a crash. - Fix variable dependency tracking during rewriting in the optimisation phase. Could previously lead to variables being removed that are still required. Fixes :bugref:`54`. .. _v2.0.6: Version 2.0.6 ~~~~~~~~~~~~~ (released 2 August 2015) .. _changes-18: Changes: ^^^^^^^^ - Add parser support for hexadecimal floating point constants. .. _bug-fixes-29: Bug fixes: ^^^^^^^^^^ - Fix bounds computation for some calls (abs, int_times). - Fix flattening of some array declarations (when right hand side is an identifier). - Add four missing GC locks (could lead to incorrect garbage collection). - Compact output model only after optimisation phase (could lead to incorrect items being removed from output model). .. _v2.0.5: Version 2.0.5 ~~~~~~~~~~~~~ (released 31 July 2015) .. _changes-19: Changes: ^^^^^^^^ - Improve the standard decomposition for the cumulative constraint. - Better handling of binary operators during type checking and flattening, can sometimes avoid stack overflows (e.g. for large conjunctions). - Make ++ operator left associative (avoid stack overflows in the parser). - Add ::domain annotations to linear constraints generated from multi-dimensional element constraints. - Greatly improved linearisation library. .. _bug-fixes-30: Bug fixes: ^^^^^^^^^^ - Fix recursive function calls that contain let expressions. - Fix compilation of comprehensions inside parametric functions. - Fix a memory leak in solns2out. - Fix a problem in the evaluation of binary operators. - Fix a bug in the flattening of array literals. - Fix a bug that would crash the parser on certain syntax errors in let expressions. .. _v2.0.4: Version 2.0.4 ~~~~~~~~~~~~~ (released 1 July 2015) .. _changes-20: Changes: ^^^^^^^^ - Models can now be read from standard input (using the "-" or "--input-from-stdin" command line options). Thanks to Sebastian Kosch. - Improved handling of bool2int during FlatZinc generation. .. _bug-fixes-31: Bug fixes: ^^^^^^^^^^ - Fix unification of aliased variables which could sometimes result in variables being removed although had a constraining right hand side. - Fix evaluation of set comprehensions. - Fix command line flag --no-output-ozn - Fix performance problem when evaluating array expressions inside lets. - Fix flattening of bool_xor redefinitions. - Fix partial evaluation of some array access expressions with var indexes. - Fix definition of geost constraint. - User-defined functions are now copied correctly into the output model if they are referenced in the output item. - Set comprehensions are fully evaluated. .. _v2.0.3: Version 2.0.3 ~~~~~~~~~~~~~ (Internal release that did not contain some essential fixes) .. _v2.0.2: Version 2.0.2 ~~~~~~~~~~~~~ (released 26 May 2015) .. _changes-21: Changes: ^^^^^^^^ - The optimiser now removes simple domain constraints from the FlatZinc - The compiler now checks for integer overflows in all built-in operations - Report an error when the FlatZinc or ozn file cannot be opened for writing - Add support for 3d array literals (e.g. [\| \|1,2|3,4|,|5,6|7,8\| \|] ) - Add show2d and show3d functions for formatting array output - Add row/col functions for variable arrays (fixes :bugref:`2`) - Introduce builtins for creating random distributions - Add reverse library function - Postpone flattening of some reified constraints - Slightly improved compilation of partial function calls when it can be inferred at compile time that their result is undefined - Allow functions with empty argument lists to be declared as function int: foo(); instead of just function int: foo; - Improve error reporting, in particular for errors in comprehensions - Enable expressions a..b where a and b are integer variables - Add redundant_constraint and symmetry_breaking_constraint builtins, these can be rewritten by solver libraries to allow e.g. local search solvers to ignore redundant constraints. - Improve flattening of predicates that simply return their arguments (makes the redundant_constraint and symmetry_breaking_constraint predicates work in more situations). - Replace command line option --only-range-domains by optional boolean value so that solver libraries can set the flag directly in their redefinitions file. - Stop flattening immediately when a model has been found to contain an inconsistency. - Improve flattening of array access expressions, in particular for nested array accesses that can be combined into a single element constraint - Add command line option -s or --statistics to print statistics about the generated FlatZinc - Improve bounds computation for if-then-else expressions - Clause arguments are compiled in positive and negative contexts instead of mixed. That means that predicates that introduce free variables can now be used in the positive part of a clause. .. _bug-fixes-32: Bug fixes: ^^^^^^^^^^ - Fix simplification of linear expressions, negative coefficients could sometimes result in incorrect bounds - Fix bounds computation for unary minus operator - Add missing par set comparison builtins - Fix bounds computation for extended comprehension syntax - Fix a bug in the garbage collector that could sometimes lead to premature deletion of expressions - Fix bounds computation for set difference - Fix duplication of some arrays in the FlatZinc (fixes :bugref:`3`) - Fix bounds inference for variables bound to empty sets (fixes :bugref:`3`) - Fix bug in error reporting function, which would sometimes not report the entire call stack - Fix the generation of fresh variable names for generator expressions - Fix subtype check to allow empty arrays as subtype of arrays of sets - Fix crash when using assert/2 - Fix bug when function used in output referred to par variable - Fix bug in type checker, the detection of cyclic definitions was not correct and could lead to stack overflows - Fix parser to accept expressions with two consecutive array accesses (like x[3][4], which are valid MiniZinc if x is an array of sets) - Fix error reporting when an evaluation error occurs within a comprehension generator - Report type error on some ambiguous function calls - Report type error on var sets with element type other than int - Report type error when trying to coerce a var set into an array - Report error when calling function with a value that is outside the declared parameter bounds - Fix arg_sort builtin to implement the correct semantics - Fix sort_by builtin to sort in non-decreasing order, and work with floats - Fix bug in type checker, now automatic coercions in functions defined with type variables (like the comparison operators) work correctly - Check that index sets match for arrays assigned in let expressions - Fix bug in bounds inference for integer expressions with annotations - Fix propagation of defines_var annotation to be pushed through calls - Fix parser to accept empty 2d and 3d array literals - Fix flattening to remove defines_var annotations with par argument, e.g. defines_var(2), which could be introduced by the optimisation pass - Fix output model creation for variables that have been redefined, and remove more unused variables from the FlatZinc. - Fix bug in the garbage collector that could result in function items not being kept alive in rare cases. .. _v2.0.1: Version 2.0.1 ~~~~~~~~~~~~~ (released 15 December 2014) Major bugs and changes: ^^^^^^^^^^^^^^^^^^^^^^^ - Fix optimisation phase, which was previously incorrectly removing variables - Add support for trigonometric functions (built-ins were missing in 2.0.0) and pow (var versions were missing) - Fix equality operator on par arrays - All expressions in output model are now made par - Improve bounds computation for float variables - Fix translation of functions that need automatic coercion of their return value - Fix the array_lb and array_ub builtins, which would return incorrect bounds in some cases Minor bugs and changes: ^^^^^^^^^^^^^^^^^^^^^^^ - Add space between "array" and "[" in the pretty printer, to be compatible with 1.6 output - Output all par declarations before the var declarations in FlatZinc - Fix parser, which could sometimes crash on invalid input - Improve efficiency of bounds computation on some float expressions - Add special case handling for division by 1 - Add missing float_times definition to the flatzinc builtins - Use correct version of var_dom for float variables - Output information about which files are included in verbose mode - Only compute bounds for "then" expressions if the "if" is not fixed to false .. _v2.0.0: Version 2.0.0 ~~~~~~~~~~~~~ (released 9 December 2014) MiniZinc 2.0 contains many new features and is based on a complete rewrite of the MiniZinc-to-FlatZinc compiler. If you are currently using the previous version 1.6, the new tools can be used as drop-in replacements. The generated FlatZinc is compatible with version 1.6, so all FlatZinc solvers should work without changes. MiniZinc language changes ^^^^^^^^^^^^^^^^^^^^^^^^^ - MiniZinc now supports user-defined functions. Details have been published in the paper "MiniZinc with Functions". Both functions and predicates can be recursive. - MiniZinc now supports option types. Details have been published in the paper "Modelling with Option Types in MiniZinc". - Let expressions have been generalised. They can now contain constraint items in addition to variable declarations. - Array index sets can be declared using arbitrary set expressions as long as they evaluate to contiguous ranges. - The if-then-else expression has been generalised to allow the condition to be a var bool expression (instead of only par bool). - Array and set comprehensions as well as generator calls can now iterate over variables and use var bool where conditions. - Any bool expression can now automatically coerce to an int expression, likewise for int and float. This means that you don't have to write bool2int or int2float in you models any more. - Equality constraints can now be posted between array expressions. - Arbitrary expressions can now be included ("interpolated") into strings, using the syntax "some text \\(e) some more text", where e is any expression. It is the same as writing "some text "++show(e)++" some more text". New built-in functions ^^^^^^^^^^^^^^^^^^^^^^ - Array functions: array1d, arrayXd, row, col, has_index, has_element, sort_by, sort, arg_sort, arg_min, arg_max New global constraints ^^^^^^^^^^^^^^^^^^^^^^ - arg_max, arg_min - arg_sort - k-dimensional diffn - disjunctive - geost - knapsack - network_flow - regular with NFAs - symmetric all different - optional scheduling constraints: alternative, span, disjunctive, cumulative - functional versions of many global constraints New tool chain ^^^^^^^^^^^^^^ - There are a few new builtins that solvers can reimplement, these are listed in the redefinitions-2.0 file. - Include items use a different method for finding included files. Paths are now interpreted as relative to the file that has the include item. That way, the mzn2fzn compiler can be called from a different working directory. - A new tool, mzn2doc, can produce html output from the documentation comments. The MiniZinc distribution contains the documentation for global constraints and builtins generated directly from the library source code. libminizinc-2.8.2/solvers/0000755000175000017500000000000014536677021014200 5ustar kaolkaollibminizinc-2.8.2/solvers/geas/0000755000175000017500000000000014536677021015117 5ustar kaolkaollibminizinc-2.8.2/solvers/geas/geas_solverfactory.cpp0000644000175000017500000000123514536677021021525 0ustar kaolkaol/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Jip J. Dekker */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include namespace MiniZinc { namespace { void get_wrapper() { static GeasSolverFactory _geas_solverfactory; } } // namespace GeasSolverFactoryInitialiser::GeasSolverFactoryInitialiser() { get_wrapper(); } } // namespace MiniZinc libminizinc-2.8.2/solvers/geas/geas_solverinstance.cpp0000644000175000017500000007340714536677021021674 0ustar kaolkaol/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Jip J. Dekker */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include namespace MiniZinc { GeasSolverInstance::GeasSolverInstance(Env& env, std::ostream& log, SolverInstanceBase::Options* opt) : SolverInstanceImpl(env, log, opt), _flat(env.flat()) { registerConstraints(); } void GeasSolverInstance::registerConstraint(const std::string& name, poster p) { _constraintRegistry.add("geas_" + name, p); _constraintRegistry.add(name, p); } void GeasSolverInstance::registerConstraints() { GCLock lock; /* Integer Comparison Constraints */ registerConstraint("int_eq", GeasConstraints::p_int_eq); registerConstraint("int_ne", GeasConstraints::p_int_ne); registerConstraint("int_le", GeasConstraints::p_int_le); registerConstraint("int_lt", GeasConstraints::p_int_lt); registerConstraint("int_eq_imp", GeasConstraints::p_int_eq_imp); registerConstraint("int_ne_imp", GeasConstraints::p_int_ne_imp); registerConstraint("int_le_imp", GeasConstraints::p_int_le_imp); registerConstraint("int_lt_imp", GeasConstraints::p_int_lt_imp); registerConstraint("int_eq_reif", GeasConstraints::p_int_eq_reif); registerConstraint("int_ne_reif", GeasConstraints::p_int_ne_reif); registerConstraint("int_le_reif", GeasConstraints::p_int_le_reif); registerConstraint("int_lt_reif", GeasConstraints::p_int_lt_reif); /* Integer Arithmetic Constraints */ registerConstraint("int_abs", GeasConstraints::p_int_abs); registerConstraint("int_times", GeasConstraints::p_int_times); registerConstraint("int_div", GeasConstraints::p_int_div); // registerConstraint("int_mod", GeasConstraints::p_int_mod); registerConstraint("int_min", GeasConstraints::p_int_min); registerConstraint("int_max", GeasConstraints::p_int_max); /* Integer Linear Constraints */ registerConstraint("int_lin_eq", GeasConstraints::p_int_lin_eq); registerConstraint("int_lin_ne", GeasConstraints::p_int_lin_ne); registerConstraint("int_lin_le", GeasConstraints::p_int_lin_le); registerConstraint("int_lin_eq_imp", GeasConstraints::p_int_lin_eq_imp); registerConstraint("int_lin_ne_imp", GeasConstraints::p_int_lin_ne_imp); registerConstraint("int_lin_le_imp", GeasConstraints::p_int_lin_le_imp); registerConstraint("int_lin_eq_reif", GeasConstraints::p_int_lin_eq_reif); registerConstraint("int_lin_ne_reif", GeasConstraints::p_int_lin_ne_reif); registerConstraint("int_lin_le_reif", GeasConstraints::p_int_lin_le_reif); /* Boolean Comparison Constraints */ registerConstraint("bool_eq", GeasConstraints::p_bool_eq); registerConstraint("bool_ne", GeasConstraints::p_bool_ne); registerConstraint("bool_le", GeasConstraints::p_bool_le); registerConstraint("bool_lt", GeasConstraints::p_bool_lt); registerConstraint("bool_eq_imp", GeasConstraints::p_bool_eq_imp); registerConstraint("bool_ne_imp", GeasConstraints::p_bool_ne_imp); registerConstraint("bool_le_imp", GeasConstraints::p_bool_le_imp); registerConstraint("bool_lt_imp", GeasConstraints::p_bool_lt_imp); registerConstraint("bool_eq_reif", GeasConstraints::p_bool_eq_reif); registerConstraint("bool_ne_reif", GeasConstraints::p_bool_ne_reif); registerConstraint("bool_le_reif", GeasConstraints::p_bool_le_reif); registerConstraint("bool_lt_reif", GeasConstraints::p_bool_lt_reif); /* Boolean Arithmetic Constraints */ registerConstraint("bool_or", GeasConstraints::p_bool_or); registerConstraint("bool_and", GeasConstraints::p_bool_and); registerConstraint("bool_xor", GeasConstraints::p_bool_xor); registerConstraint("bool_not", GeasConstraints::p_bool_not); registerConstraint("bool_or_imp", GeasConstraints::p_bool_or_imp); registerConstraint("bool_and_imp", GeasConstraints::p_bool_and_imp); registerConstraint("bool_xor_imp", GeasConstraints::p_bool_xor_imp); registerConstraint("bool_clause", GeasConstraints::p_bool_clause); registerConstraint("array_bool_or", GeasConstraints::p_array_bool_or); registerConstraint("array_bool_and", GeasConstraints::p_array_bool_and); registerConstraint("bool_clause_imp", GeasConstraints::p_bool_clause_imp); registerConstraint("array_bool_or_imp", GeasConstraints::p_array_bool_or_imp); registerConstraint("array_bool_and_imp", GeasConstraints::p_array_bool_and_imp); registerConstraint("bool_clause_reif", GeasConstraints::p_bool_clause_reif); /* Boolean Linear Constraints */ registerConstraint("bool_lin_eq", GeasConstraints::p_bool_lin_eq); registerConstraint("bool_lin_ne", GeasConstraints::p_bool_lin_ne); registerConstraint("bool_lin_le", GeasConstraints::p_bool_lin_le); registerConstraint("bool_lin_eq_imp", GeasConstraints::p_bool_lin_eq_imp); registerConstraint("bool_lin_ne_imp", GeasConstraints::p_bool_lin_ne_imp); registerConstraint("bool_lin_le_imp", GeasConstraints::p_bool_lin_le_imp); registerConstraint("bool_lin_eq_reif", GeasConstraints::p_bool_lin_eq_reif); registerConstraint("bool_lin_ne_reif", GeasConstraints::p_bool_lin_ne_reif); registerConstraint("bool_lin_le_reif", GeasConstraints::p_bool_lin_le_reif); /* Coercion Constraints */ registerConstraint("bool2int", GeasConstraints::p_bool2int); /* Element Constraints */ registerConstraint("array_int_element", GeasConstraints::p_array_int_element); registerConstraint("array_bool_element", GeasConstraints::p_array_bool_element); registerConstraint("array_var_int_element", GeasConstraints::p_array_var_int_element); registerConstraint("array_var_bool_element", GeasConstraints::p_array_var_bool_element); /* Global Constraints */ registerConstraint("all_different_int", GeasConstraints::p_all_different); registerConstraint("alldifferent_except_0", GeasConstraints::p_all_different_except_0); registerConstraint("at_most", GeasConstraints::p_at_most); registerConstraint("at_most1", GeasConstraints::p_at_most1); registerConstraint("cumulative", GeasConstraints::p_cumulative); registerConstraint("cumulative_var", GeasConstraints::p_cumulative); registerConstraint("disjunctive", GeasConstraints::p_disjunctive); registerConstraint("disjunctive_var", GeasConstraints::p_disjunctive); registerConstraint("global_cardinality", GeasConstraints::p_global_cardinality); registerConstraint("table_int", GeasConstraints::p_table_int); /**** TODO: NOT YET SUPPORTED: ****/ /* Boolean Arithmetic Constraints */ // registerConstraint("array_bool_xor", GeasConstraints::p_array_bool_xor); // registerConstraint("array_bool_xor_imp", GeasConstraints::p_array_bool_xor_imp); /* Floating Point Comparison Constraints */ // registerConstraint("float_eq", GeasConstraints::p_float_eq); // registerConstraint("float_le", GeasConstraints::p_float_le); // registerConstraint("float_lt", GeasConstraints::p_float_lt); // registerConstraint("float_ne", GeasConstraints::p_float_ne); // registerConstraint("float_eq_reif", GeasConstraints::p_float_eq_reif); // registerConstraint("float_le_reif", GeasConstraints::p_float_le_reif); // registerConstraint("float_lt_reif", GeasConstraints::p_float_lt_reif); /* Floating Point Arithmetic Constraints */ // registerConstraint("float_abs", GeasConstraints::p_float_abs); // registerConstraint("float_sqrt", GeasConstraints::p_float_sqrt); // registerConstraint("float_times", GeasConstraints::p_float_times); // registerConstraint("float_div", GeasConstraints::p_float_div); // registerConstraint("float_plus", GeasConstraints::p_float_plus); // registerConstraint("float_max", GeasConstraints::p_float_max); // registerConstraint("float_min", GeasConstraints::p_float_min); // registerConstraint("float_acos", GeasConstraints::p_float_acos); // registerConstraint("float_asin", GeasConstraints::p_float_asin); // registerConstraint("float_atan", GeasConstraints::p_float_atan); // registerConstraint("float_cos", GeasConstraints::p_float_cos); // registerConstraint("float_exp", GeasConstraints::p_float_exp); // registerConstraint("float_ln", GeasConstraints::p_float_ln); // registerConstraint("float_log10", GeasConstraints::p_float_log10); // registerConstraint("float_log2", GeasConstraints::p_float_log2); // registerConstraint("float_sin", GeasConstraints::p_float_sin); // registerConstraint("float_tan", GeasConstraints::p_float_tan); /* Floating Linear Constraints */ // registerConstraint("float_lin_eq", GeasConstraints::p_float_lin_eq); // registerConstraint("float_lin_eq_reif", GeasConstraints::p_float_lin_eq_reif); // registerConstraint("float_lin_le", GeasConstraints::p_float_lin_le); // registerConstraint("float_lin_le_reif", GeasConstraints::p_float_lin_le_reif); /* Coercion Constraints */ // registerConstraint("int2float", GeasConstraints::p_int2float); } void GeasSolverInstance::processFlatZinc() { auto _opt = static_cast(*_options); // Create variables zero = _solver.new_intvar(0, 0); for (auto it = _flat->vardecls().begin(); it != _flat->vardecls().end(); ++it) { if (!it->removed() && it->e()->type().isvar() && it->e()->type().dim() == 0) { VarDecl* vd = it->e(); if (vd->type().isbool()) { if (vd->e() == nullptr) { Expression* domain = vd->ti()->domain(); long long int lb; long long int ub; if (domain != nullptr) { IntBounds ib = compute_int_bounds(_env.envi(), domain); lb = ib.l.toInt(); ub = ib.u.toInt(); } else { lb = 0; ub = 1; } if (lb == ub) { geas::patom_t val = (lb == 0) ? geas::at_False : geas::at_True; _variableMap.insert(vd->id(), GeasVariable(val)); } else { auto var = _solver.new_boolvar(); _variableMap.insert(vd->id(), GeasVariable(var)); } } else { Expression* init = vd->e(); if (init->isa() || init->isa()) { GeasVariable& var = resolveVar(init); assert(var.isBool()); _variableMap.insert(vd->id(), GeasVariable(var.boolVar())); } else { auto b = init->cast()->v(); geas::patom_t val = b ? geas::at_True : geas::at_False; _variableMap.insert(vd->id(), GeasVariable(val)); } } } else if (vd->type().isfloat()) { if (vd->e() == nullptr) { Expression* domain = vd->ti()->domain(); double lb; double ub; if (domain != nullptr) { FloatBounds fb = compute_float_bounds(_env.envi(), vd->id()); lb = fb.l.toDouble(); ub = fb.u.toDouble(); } else { std::ostringstream ss; ss << "GeasSolverInstance::processFlatZinc: Error: Unbounded variable: " << vd->id()->str(); throw Error(ss.str()); } // TODO: Error correction from double to float?? auto var = _solver.new_floatvar(static_cast(lb), static_cast(ub)); _variableMap.insert(vd->id(), GeasVariable(var)); } else { Expression* init = vd->e(); if (init->isa() || init->isa()) { GeasVariable& var = resolveVar(init); assert(var.isFloat()); _variableMap.insert(vd->id(), GeasVariable(var.floatVar())); } else { double fl = init->cast()->v().toDouble(); auto var = _solver.new_floatvar(static_cast(fl), static_cast(fl)); _variableMap.insert(vd->id(), GeasVariable(var)); } } } else if (vd->type().isint()) { if (vd->e() == nullptr) { Expression* domain = vd->ti()->domain(); if (domain != nullptr) { IntSetVal* isv = eval_intset(env().envi(), domain); assert(!isv->empty()); auto var = _solver.new_intvar(static_cast(isv->min().toInt()), static_cast(isv->max().toInt())); if (isv->size() > 1) { vec vals(static_cast(isv->card().toInt())); int i = 0; for (int j = 0; j < isv->size(); ++j) { for (auto k = isv->min(j).toInt(); k <= isv->max(j).toInt(); ++k) { vals[i++] = static_cast(k); } } assert(i == isv->card().toInt()); auto res = geas::make_sparse(var, vals); assert(res); } _variableMap.insert(vd->id(), GeasVariable(var)); } else { std::ostringstream ss; ss << "GeasSolverInstance::processFlatZinc: Error: Unbounded variable: " << vd->id()->str(); throw Error(ss.str()); } } else { Expression* init = vd->e(); if (init->isa() || init->isa()) { GeasVariable& var = resolveVar(init); assert(var.isInt()); _variableMap.insert(vd->id(), GeasVariable(var.intVar())); } else { auto il = init->cast()->v().toInt(); auto var = _solver.new_intvar(static_cast(il), static_cast(il)); _variableMap.insert(vd->id(), GeasVariable(var)); } } } else { std::stringstream ssm; ssm << "Type " << *vd->ti() << " is currently not supported by Geas."; throw InternalError(ssm.str()); } } } // Post constraints for (ConstraintIterator it = _flat->constraints().begin(); it != _flat->constraints().end(); ++it) { if (!it->removed()) { if (auto* c = it->e()->dynamicCast()) { _constraintRegistry.post(c); } } } // Set objective SolveI* si = _flat->solveItem(); if (si->e() != nullptr) { _objType = si->st(); if (_objType == SolveI::ST_MIN) { _objVar = std::unique_ptr(new GeasTypes::Variable(resolveVar(si->e()))); } else if (_objType == SolveI::ST_MAX) { _objType = SolveI::ST_MIN; _objVar = std::unique_ptr(new GeasTypes::Variable(-asIntVar(si->e()))); } } if (!si->ann().isEmpty()) { std::vector flatAnn; flattenSearchAnnotations(si->ann(), flatAnn); for (auto& ann : flatAnn) { if (ann->isa()) { Call* call = ann->cast(); if (call->id() == "warm_start") { auto* vars = eval_array_lit(env().envi(), call->arg(0)); auto* vals = eval_array_lit(env().envi(), call->arg(1)); assert(vars->size() == vals->size()); vec ws(static_cast(vars->size())); if (vars->type().isIntArray()) { assert(vals->type().isIntArray()); for (int i = 0; i < vars->size(); ++i) { geas::intvar var = asIntVar((*vars)[i]); int val = asInt((*vals)[i]); ws.push(var == val); } } else if (vars->type().isBoolArray()) { assert(vals->type().isBoolArray()); for (int i = 0; i < vars->size(); ++i) { geas::patom_t var = asBoolVar((*vars)[i]); bool val = asBool((*vals)[i]); ws.push(val ? var : ~var); } } else { std::cerr << "WARNING Geas: ignoring warm start annotation of invalid type: " << *ann << std::endl; continue; } _solver.data->branchers.push(geas::warmstart_brancher(ws)); continue; } vec pids; geas::VarChoice select = geas::Var_FirstFail; geas::ValChoice choice = geas::Val_Min; if (call->id() == "int_search") { vec iv = asIntVar(eval_array_lit(env().envi(), call->arg(0))); pids.growTo(iv.size()); for (int i = 0; i < iv.size(); ++i) { pids[i] = iv[i].p; } } else if (call->id() == "bool_search") { vec bv = asBoolVar(eval_array_lit(env().envi(), call->arg(0))); pids.growTo(bv.size()); for (int i = 0; i < bv.size(); ++i) { pids[i] = bv[i].pid; } } else { std::cerr << "WARNING Geas: ignoring unknown search annotation: " << *ann << std::endl; continue; } ASTString select_str = call->arg(1)->cast()->str(); if (select_str == "input_order") { select = geas::Var_InputOrder; } else if (select_str == "first_fail") { select = geas::Var_FirstFail; } else if (select_str == "largest") { select = geas::Var_Largest; } else if (select_str == "smallest") { select = geas::Var_Smallest; } else { std::cerr << "WARNING Geas: unknown variable selection '" << select_str << "', using default value First Fail." << std::endl; } ASTString choice_str = call->arg(2)->cast()->str(); if (choice_str == "indomain_max") { choice = geas::Val_Max; } else if (choice_str == "indomain_min") { choice = geas::Val_Min; } else if (choice_str == "indomain_split") { choice = geas::Val_Split; } else { std::cerr << "WARNING Geas: unknown value selection '" << choice_str << "', using Indomain Min." << std::endl; } geas::brancher* b = geas::basic_brancher(select, choice, pids); if (_opt.freeSearch) { vec brv({b, _solver.data->last_branch}); _solver.data->branchers.push(geas::toggle_brancher(brv)); } else { _solver.data->branchers.push(b); } } } } } bool GeasSolverInstance::addSolutionNoGood() { assert(!_varsWithOutput.empty()); geas::model solution = _solver.get_model(); vec clause; for (auto& var : _varsWithOutput) { if (Expression::dynamicCast(get_annotation( var->ann(), Constants::constants().ann.output_array.aststr())) != nullptr) { if (auto* al = var->e()->dynamicCast()) { for (int j = 0; j < al->size(); j++) { if (Id* id = (*al)[j]->dynamicCast()) { auto geas_var = resolveVar(id); if (geas_var.isBool()) { geas::patom_t bv = geas_var.boolVar(); clause.push(solution.value(bv) ? ~bv : bv); } else if (geas_var.isFloat()) { geas::fp::fpvar fv = geas_var.floatVar(); clause.push(fv < solution[fv]); clause.push(fv > solution[fv]); } else { geas::intvar iv = geas_var.intVar(); clause.push(~(iv == solution[iv])); } } } } } else { auto geas_var = resolveVar(var); if (geas_var.isBool()) { geas::patom_t bv = geas_var.boolVar(); clause.push(solution.value(bv) ? ~bv : bv); } else if (geas_var.isFloat()) { geas::fp::fpvar fv = geas_var.floatVar(); clause.push(fv < solution[fv]); clause.push(fv > solution[fv]); } else { geas::intvar iv = geas_var.intVar(); clause.push(iv != solution[iv]); } } } return geas::add_clause(*_solver.data, clause); } SolverInstanceBase::Status MiniZinc::GeasSolverInstance::solve() { SolverInstanceBase::Status status = SolverInstance::ERROR; auto _opt = static_cast(*_options); auto remaining_time = [_opt] { if (_opt.time == std::chrono::milliseconds(0)) { return 0.0; } using geas_time = std::chrono::duration; static auto timeout = std::chrono::high_resolution_clock::now() + _opt.time; return geas_time(timeout - std::chrono::high_resolution_clock::now()).count(); }; if (_objType == SolveI::ST_SAT) { int nr_solutions = 0; geas::solver::result res = geas::solver::UNKNOWN; while ((_opt.allSolutions || nr_solutions < _opt.nrSolutions) && remaining_time() >= 0.0) { res = _solver.solve({remaining_time(), _opt.conflicts - _solver.data->stats.conflicts}); printSolution(); if (res != geas::solver::SAT) { break; } nr_solutions++; _solver.restart(); if (!addSolutionNoGood()) { res = geas::solver::UNSAT; break; } } switch (res) { case geas::solver::SAT: status = SolverInstance::SAT; break; case geas::solver::UNSAT: if (nr_solutions > 0) { status = SolverInstance::OPT; } else { status = SolverInstance::UNSAT; } break; case geas::solver::UNKNOWN: if (nr_solutions > 0) { status = SolverInstance::SAT; } else { status = SolverInstance::UNKNOWN; } break; default: status = SolverInstance::ERROR; break; } } else { assert(_objType == SolveI::ST_MIN); // TODO: Add float objectives assert(_objVar->isInt()); geas::intvar obj = _objVar->intVar(); geas::solver::result res; while (true) { res = _solver.solve({remaining_time(), _opt.conflicts - _solver.data->stats.conflicts}); geas::intvar::val_t obj_val; if (res != geas::solver::SAT) { break; } status = SolverInstance::SAT; if (_opt.allSolutions) { printSolution(); } obj_val = _solver.get_model()[obj]; int step = 1; while (_opt.objProbeLimit > 0) { geas::intvar::val_t assumed_obj; assumed_obj = obj_val - step; assumed_obj = obj.lb(_solver.data) > assumed_obj ? obj.lb(_solver.data) : assumed_obj; if (!_solver.assume(obj == assumed_obj)) { _solver.retract(); break; } res = _solver.solve({remaining_time(), _opt.objProbeLimit}); _solver.retract(); if (res != geas::solver::SAT) { break; } step *= 2; if (_opt.allSolutions) { printSolution(); } obj_val = _solver.get_model()[obj]; } _solver.post(obj < obj_val); } if (status == SolverInstance::ERROR) { switch (res) { case geas::solver::UNSAT: status = SolverInstance::UNSAT; break; case geas::solver::UNKNOWN: status = SolverInstance::UNKNOWN; break; default: assert(false); status = SolverInstance::ERROR; break; } } else { if (res == geas::solver::UNSAT) { status = SolverInstance::OPT; } if (!_opt.allSolutions) { printSolution(); } } } if (_opt.statistics) { printStatistics(); } return status; } Expression* GeasSolverInstance::getSolutionValue(Id* id) { id = id->decl()->id(); if (id->type().isvar()) { GeasVariable& var = resolveVar(id->decl()->id()); geas::model solution = _solver.get_model(); switch (id->type().bt()) { case Type::BT_BOOL: assert(var.isBool()); return Constants::constants().boollit(solution.value(var.boolVar())); case Type::BT_FLOAT: assert(var.isFloat()); return FloatLit::a(solution[var.floatVar()]); case Type::BT_INT: assert(var.isInt()); return IntLit::a(solution[var.intVar()]); default: return nullptr; } } else { return id->decl()->e(); } } void GeasSolverInstance::resetSolver() { assert(false); } GeasTypes::Variable& GeasSolverInstance::resolveVar(Expression* e) { if (auto* id = e->dynamicCast()) { return _variableMap.get(id->decl()->id()); } if (auto* vd = e->dynamicCast()) { return _variableMap.get(vd->id()->decl()->id()); } if (auto* aa = e->dynamicCast()) { auto* ad = aa->v()->cast()->decl(); auto idx = aa->idx()[0]->cast()->v().toInt(); auto* al = eval_array_lit(_env.envi(), ad->e()); return _variableMap.get((*al)[idx]->cast()); } std::stringstream ssm; ssm << "Expected Id, VarDecl or ArrayAccess instead of \"" << *e << "\""; throw InternalError(ssm.str()); } vec GeasSolverInstance::asBool(ArrayLit* al) { vec vec(static_cast(al->size())); for (int i = 0; i < al->size(); ++i) { vec[i] = asBool((*al)[i]); } return vec; } geas::patom_t GeasSolverInstance::asBoolVar(Expression* e) { if (e->type().isvar()) { GeasVariable& var = resolveVar(follow_id_to_decl(e)); assert(var.isBool()); return var.boolVar(); } if (auto* bl = e->dynamicCast()) { return bl->v() ? geas::at_True : geas::at_False; } std::stringstream ssm; ssm << "Expected bool or int literal instead of: " << *e; throw InternalError(ssm.str()); } vec GeasSolverInstance::asBoolVar(ArrayLit* al) { vec vec(static_cast(al->size())); for (int i = 0; i < al->size(); ++i) { vec[i] = this->asBoolVar((*al)[i]); } return vec; } vec GeasSolverInstance::asInt(ArrayLit* al) { vec vec(static_cast(al->size())); for (int i = 0; i < al->size(); ++i) { vec[i] = this->asInt((*al)[i]); } return vec; } geas::intvar GeasSolverInstance::asIntVar(Expression* e) { if (e->type().isvar()) { GeasVariable& var = resolveVar(follow_id_to_decl(e)); assert(var.isInt()); return var.intVar(); } IntVal i; if (auto* il = e->dynamicCast()) { i = il->v().toInt(); } else if (auto* bl = e->dynamicCast()) { i = static_cast(bl->v()); } else { std::stringstream ssm; ssm << "Expected bool or int literal instead of: " << *e; throw InternalError(ssm.str()); } if (i == 0) { return zero; } return _solver.new_intvar(static_cast(i.toInt()), static_cast(i.toInt())); } vec GeasSolverInstance::asIntVar(ArrayLit* al) { vec vec(static_cast(al->size())); for (int i = 0; i < al->size(); ++i) { vec[i] = this->asIntVar((*al)[i]); } return vec; } void GeasSolverInstance::printStatistics() { auto& st = _solver.data->stats; auto* solns2out = getSolns2Out(); StatisticsStream ss(solns2out->getOutput(), solns2out->opt.flagEncapsulateJSON); ss.add("failures", st.conflicts); // TODO: Statistic name ss.add("solveTime", st.time); ss.add("solutions", st.solutions); ss.add("restarts", st.restarts); ss.add("nogoods", st.num_learnts); // TODO: Statistic name ss.add("learntLiterals", st.num_learnt_lits); // TODO: Statistic name } GeasSolverFactory::GeasSolverFactory() { SolverConfig sc("org.minizinc.geas", getVersion(nullptr)); sc.name("Geas"); sc.mznlib("-Ggeas"); sc.mznlibVersion(1); sc.supportsMzn(false); sc.description(getDescription(nullptr)); sc.tags({ "api", "cp", "float", "int", "lcg", }); sc.stdFlags({"-a", "-f", "-n", "-s", "-t"}); sc.extraFlags({ SolverConfig::ExtraFlag("--conflicts", "Limit the maximum number of conflicts to be used during solving.", SolverConfig::ExtraFlag::FlagType::T_INT, {}, "0"), SolverConfig::ExtraFlag( "--obj-probe", "Number of conflicts to use to probe for better solutions after a new solution is found.", SolverConfig::ExtraFlag::FlagType::T_INT, {}, "0"), }); SolverConfigs::registerBuiltinSolver(sc); }; SolverInstanceBase::Options* GeasSolverFactory::createOptions() { return new GeasOptions; } SolverInstanceBase* GeasSolverFactory::doCreateSI(Env& env, std::ostream& log, SolverInstanceBase::Options* opt) { return new GeasSolverInstance(env, log, opt); } bool GeasSolverFactory::processOption(SolverInstanceBase::Options* opt, int& i, std::vector& argv, const std::string& workingDir) { auto* _opt = static_cast(opt); if (argv[i] == "-a" || argv[i] == "--all-solutions") { _opt->allSolutions = true; } else if (argv[i] == "--conflicts") { if (++i == argv.size()) { return false; } int nodes = atoi(argv[i].c_str()); if (nodes >= 0) { _opt->conflicts = nodes; } } else if (argv[i] == "-f" || argv[i] == "--free-search") { _opt->freeSearch = true; } else if (argv[i] == "-n") { if (++i == argv.size()) { return false; } int n = atoi(argv[i].c_str()); if (n >= 0) { _opt->nrSolutions = n; } } else if (argv[i] == "--obj-probe") { if (++i == argv.size()) { return false; } int limit = atoi(argv[i].c_str()); if (limit >= 0) { _opt->objProbeLimit = limit; } } else if (argv[i] == "--solver-statistics" || argv[i] == "-s") { _opt->statistics = true; } else if (argv[i] == "--solver-time-limit" || argv[i] == "-t") { if (++i == argv.size()) { return false; } int time = atoi(argv[i].c_str()); if (time >= 0) { _opt->time = std::chrono::milliseconds(time); } } else { return false; } return true; } void GeasSolverFactory::printHelp(std::ostream& os) { os << "Geas solver plugin options:" << std::endl << " --conflicts " << std::endl << " Limit the maximum number of conflicts to be used during solving." << std::endl << " --obj-probe " << std::endl << " Number of conflicts to use to probe for better solutions after a new solution is " "found." << std::endl << std::endl; } } // namespace MiniZinc libminizinc-2.8.2/solvers/geas/geas_constraints.cpp0000644000175000017500000005547714536677021021213 0ustar kaolkaol/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Jip J. Dekker */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma clang diagnostic push #pragma ide diagnostic ignored "cppcoreguidelines-pro-type-static-cast-downcast" #include #include #include #include namespace MiniZinc { namespace GeasConstraints { #define SI (static_cast(s)) #define SD SI.solverData() #define SOL SI.solver() #define EXPR(X) call->arg(X) #define BOOL(X) SI.asBool(EXPR(X)) #define BOOLARRAY(X) SI.asBool(ARRAY(X)) #define BOOLVAR(X) SI.asBoolVar(EXPR(X)) #define BOOLVARARRAY(X) SI.asBoolVar(ARRAY(X)) #define INT(X) SI.asInt(EXPR(X)) #define INTARRAY(X) SI.asInt(ARRAY(X)) #define INTVAR(X) SI.asIntVar(EXPR(X)) #define INTVARARRAY(X) SI.asIntVar(ARRAY(X)) #define PAR(X) call->arg(X)->type().isPar() #define ARRAY(X) eval_array_lit(s.env().envi(), call->arg(X)) void p_int_eq(SolverInstanceBase& s, const Call* call) { geas::int_eq(SD, INTVAR(0), INTVAR(1)); } void p_int_ne(SolverInstanceBase& s, const Call* call) { geas::int_ne(SD, INTVAR(0), INTVAR(1)); } void p_int_le(SolverInstanceBase& s, const Call* call) { geas::int_le(SD, INTVAR(0), INTVAR(1), 0); } void p_int_lt(SolverInstanceBase& s, const Call* call) { geas::int_le(SD, INTVAR(0), INTVAR(1), -1); } void p_int_eq_imp(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_int_eq(s, call); } } else { geas::int_eq(SD, INTVAR(0), INTVAR(1), BOOLVAR(2)); } } void p_int_ne_imp(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_int_ne(s, call); } } else { geas::int_ne(SD, INTVAR(0), INTVAR(1), BOOLVAR(2)); } } void p_int_le_imp(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_int_le(s, call); } } else { geas::int_le(SD, INTVAR(0), INTVAR(1), 0, BOOLVAR(2)); } } void p_int_lt_imp(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_int_lt(s, call); } } else { geas::int_le(SD, INTVAR(0), INTVAR(1), -1, BOOLVAR(2)); } } void p_int_eq_reif(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_int_eq(s, call); } else { p_int_ne(s, call); } } else { geas::int_eq(SD, INTVAR(0), INTVAR(1), BOOLVAR(2)); geas::int_ne(SD, INTVAR(0), INTVAR(1), ~BOOLVAR(2)); } } void p_int_ne_reif(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_int_ne(s, call); } else { p_int_eq(s, call); } } else { geas::int_ne(SD, INTVAR(0), INTVAR(1), BOOLVAR(2)); geas::int_eq(SD, INTVAR(0), INTVAR(1), ~BOOLVAR(2)); } } void p_int_le_reif(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_int_le(s, call); } else { auto* nc = Call::a(Location().introduce(), call->id(), {call->arg(1), call->arg(0)}); p_int_lt(s, nc); } } else { geas::int_le(SD, INTVAR(0), INTVAR(1), 0, BOOLVAR(2)); geas::int_le(SD, INTVAR(1), INTVAR(0), -1, ~BOOLVAR(2)); } } void p_int_lt_reif(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_int_lt(s, call); } else { auto* nc = Call::a(Location().introduce(), call->id(), {call->arg(1), call->arg(0)}); p_int_le(s, nc); } } else { geas::int_le(SD, INTVAR(0), INTVAR(1), -1, BOOLVAR(2)); geas::int_le(SD, INTVAR(1), INTVAR(0), 0, ~BOOLVAR(2)); } } void p_int_abs(SolverInstanceBase& s, const Call* call) { geas::int_abs(SD, INTVAR(1), INTVAR(0)); } void p_int_times(SolverInstanceBase& s, const Call* call) { geas::int_mul(SD, INTVAR(2), INTVAR(0), INTVAR(1)); } void p_int_div(SolverInstanceBase& s, const Call* call) { geas::int_div(SD, INTVAR(2), INTVAR(0), INTVAR(1)); } void p_int_max(SolverInstanceBase& s, const Call* call) { vec vars = {INTVAR(0), INTVAR(1)}; geas::int_max(SD, INTVAR(2), vars); } void p_int_min(SolverInstanceBase& s, const Call* call) { vec vars = {-INTVAR(0), -INTVAR(1)}; geas::int_max(SD, -INTVAR(2), vars); } void p_int_lin_eq(SolverInstanceBase& s, const Call* call) { vec pos = INTARRAY(0); vec neg(pos.size()); for (int i = 0; i < neg.size(); ++i) { neg[i] = -pos[i]; } vec vars = INTVARARRAY(1); // TODO: Rewrite using MiniZinc Library?? geas::linear_le(SD, pos, vars, INT(2)); geas::linear_le(SD, neg, vars, -INT(2)); } void p_int_lin_ne(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = INTVARARRAY(1); geas::linear_ne(SD, cons, vars, INT(2)); } void p_int_lin_le(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = INTVARARRAY(1); geas::linear_le(SD, cons, vars, INT(2)); } void p_int_lin_eq_imp(SolverInstanceBase& s, const Call* call) { vec pos = INTARRAY(0); vec neg(pos.size()); for (int i = 0; i < neg.size(); ++i) { neg[i] = -pos[i]; } vec vars = INTVARARRAY(1); // TODO: Rewrite using MiniZinc Library?? geas::linear_le(SD, pos, vars, INT(2), BOOLVAR(3)); geas::linear_le(SD, neg, vars, -INT(2), BOOLVAR(3)); } void p_int_lin_ne_imp(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = INTVARARRAY(1); geas::linear_ne(SD, cons, vars, INT(2), BOOLVAR(3)); } void p_int_lin_le_imp(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = INTVARARRAY(1); geas::linear_le(SD, cons, vars, INT(2), BOOLVAR(3)); } void p_int_lin_eq_reif(SolverInstanceBase& s, const Call* call) { vec pos = INTARRAY(0); vec neg(pos.size()); for (int i = 0; i < neg.size(); ++i) { neg[i] = -pos[i]; } vec vars = INTVARARRAY(1); // TODO: Rewrite using MiniZinc Library?? geas::linear_le(SD, pos, vars, INT(2), BOOLVAR(3)); geas::linear_le(SD, neg, vars, -INT(2), BOOLVAR(3)); geas::linear_ne(SD, pos, vars, INT(2), ~BOOLVAR(3)); } void p_int_lin_ne_reif(SolverInstanceBase& s, const Call* call) { vec pos = INTARRAY(0); vec neg(pos.size()); for (int i = 0; i < neg.size(); ++i) { neg[i] = -pos[i]; } vec vars = INTVARARRAY(1); // TODO: Rewrite using MiniZinc Library?? geas::linear_ne(SD, pos, vars, INT(2), BOOLVAR(3)); geas::linear_le(SD, pos, vars, INT(2), ~BOOLVAR(3)); geas::linear_le(SD, neg, vars, -INT(2), ~BOOLVAR(3)); } void p_int_lin_le_reif(SolverInstanceBase& s, const Call* call) { vec pos = INTARRAY(0); vec neg(pos.size()); for (int i = 0; i < neg.size(); ++i) { neg[i] = -pos[i]; } vec vars = INTVARARRAY(1); geas::linear_le(SD, pos, vars, INT(2), BOOLVAR(3)); geas::linear_le(SD, neg, vars, -INT(2) - 1, ~BOOLVAR(3)); } void p_bool_eq(SolverInstanceBase& s, const Call* call) { if (PAR(0)) { SOL.post(BOOL(0) ? BOOLVAR(1) : ~BOOLVAR(1)); } else if (PAR(2)) { SOL.post(BOOL(1) ? BOOLVAR(0) : ~BOOLVAR(0)); } else { geas::add_clause(SD, BOOLVAR(0), ~BOOLVAR(1)); geas::add_clause(SD, ~BOOLVAR(0), BOOLVAR(1)); } } void p_bool_ne(SolverInstanceBase& s, const Call* call) { if (PAR(0)) { SOL.post(BOOL(0) ? ~BOOLVAR(1) : BOOLVAR(1)); } else if (PAR(1)) { SOL.post(BOOL(1) ? ~BOOLVAR(0) : BOOLVAR(0)); } else { geas::add_clause(SD, BOOLVAR(0), BOOLVAR(1)); geas::add_clause(SD, ~BOOLVAR(0), ~BOOLVAR(1)); } } void p_bool_le(SolverInstanceBase& s, const Call* call) { if (PAR(0)) { if (BOOL(0)) { SOL.post(BOOLVAR(1)); } } else if (PAR(1)) { if (!BOOL(1)) { SOL.post(~BOOLVAR(0)); } } else { geas::add_clause(SD, ~BOOLVAR(0), BOOLVAR(1)); } } void p_bool_lt(SolverInstanceBase& s, const Call* call) { SOL.post(~BOOLVAR(0)); SOL.post(BOOLVAR(1)); } void p_bool_eq_imp(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_bool_eq(s, call); } } else { geas::add_clause(SD, ~BOOLVAR(2), ~BOOLVAR(0), BOOLVAR(1)); geas::add_clause(SD, ~BOOLVAR(2), BOOLVAR(0), ~BOOLVAR(1)); } } void p_bool_ne_imp(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_bool_ne(s, call); } } else { geas::add_clause(SD, ~BOOLVAR(2), BOOLVAR(0), BOOLVAR(1)); geas::add_clause(SD, ~BOOLVAR(2), ~BOOLVAR(0), ~BOOLVAR(1)); } } void p_bool_le_imp(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_bool_le(s, call); } } else { geas::add_clause(SD, ~BOOLVAR(2), ~BOOLVAR(0), BOOLVAR(1)); } } void p_bool_lt_imp(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_bool_lt(s, call); } } else { geas::add_clause(SD, ~BOOLVAR(2), ~BOOLVAR(0)); geas::add_clause(SD, ~BOOLVAR(2), BOOLVAR(1)); } } void p_bool_eq_reif(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_bool_eq(s, call); } else { p_bool_ne(s, call); } } else { geas::add_clause(SD, BOOLVAR(2), BOOLVAR(0), BOOLVAR(1)); geas::add_clause(SD, BOOLVAR(2), ~BOOLVAR(0), ~BOOLVAR(1)); geas::add_clause(SD, ~BOOLVAR(2), ~BOOLVAR(0), BOOLVAR(1)); geas::add_clause(SD, ~BOOLVAR(2), BOOLVAR(0), ~BOOLVAR(1)); } } void p_bool_ne_reif(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_bool_ne(s, call); } else { p_bool_eq(s, call); } } else { geas::add_clause(SD, BOOLVAR(2), ~BOOLVAR(0), BOOLVAR(1)); geas::add_clause(SD, BOOLVAR(2), BOOLVAR(0), ~BOOLVAR(1)); geas::add_clause(SD, ~BOOLVAR(2), BOOLVAR(0), BOOLVAR(1)); geas::add_clause(SD, ~BOOLVAR(2), ~BOOLVAR(0), ~BOOLVAR(1)); } } void p_bool_le_reif(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_bool_le(s, call); } else { auto* nc = Call::a(Location().introduce(), call->id(), {call->arg(1), call->arg(0)}); p_bool_lt(s, nc); } } else { geas::add_clause(SD, BOOLVAR(2), ~BOOLVAR(1)); geas::add_clause(SD, BOOLVAR(2), BOOLVAR(0)); geas::add_clause(SD, ~BOOLVAR(2), ~BOOLVAR(0), BOOLVAR(1)); } } void p_bool_lt_reif(SolverInstanceBase& s, const Call* call) { if (PAR(2)) { if (BOOL(2)) { p_int_lt(s, call); } else { auto* nc = Call::a(Location().introduce(), call->id(), {call->arg(1), call->arg(0)}); p_int_le(s, nc); } } else { geas::add_clause(SD, ~BOOLVAR(2), ~BOOLVAR(0)); geas::add_clause(SD, ~BOOLVAR(2), BOOLVAR(1)); geas::add_clause(SD, BOOLVAR(2), BOOLVAR(0), ~BOOLVAR(1)); } } void p_bool_or(SolverInstanceBase& s, const Call* call) { geas::add_clause(SD, BOOLVAR(2), ~BOOLVAR(0)); geas::add_clause(SD, BOOLVAR(2), ~BOOLVAR(1)); geas::add_clause(SD, ~BOOLVAR(2), BOOLVAR(0), BOOLVAR(1)); } void p_bool_and(SolverInstanceBase& s, const Call* call) { geas::add_clause(SD, ~BOOLVAR(2), BOOLVAR(0)); geas::add_clause(SD, ~BOOLVAR(2), BOOLVAR(1)); geas::add_clause(SD, BOOLVAR(2), ~BOOLVAR(0), ~BOOLVAR(1)); } void p_bool_xor(SolverInstanceBase& s, const Call* call) { if (call->argCount() == 2) { p_bool_ne(s, call); } else { p_bool_ne_reif(s, call); } } void p_bool_not(SolverInstanceBase& s, const Call* call) { p_bool_ne(s, call); } void p_bool_or_imp(SolverInstanceBase& s, const Call* call) { geas::add_clause(SD, ~BOOLVAR(2), BOOLVAR(0), BOOLVAR(1)); } void p_bool_and_imp(SolverInstanceBase& s, const Call* call) { geas::add_clause(SD, ~BOOLVAR(2), BOOLVAR(0)); geas::add_clause(SD, ~BOOLVAR(2), BOOLVAR(1)); } void p_bool_xor_imp(SolverInstanceBase& s, const Call* call) { p_bool_ne_imp(s, call); } void p_bool_clause(SolverInstanceBase& s, const Call* call) { auto& gi = static_cast(s); auto* pos = ARRAY(0); auto* neg = ARRAY(1); vec clause; for (int i = 0; i < pos->size(); ++i) { clause.push(SI.asBoolVar((*pos)[i])); } for (int j = 0; j < neg->size(); ++j) { clause.push(~SI.asBoolVar((*neg)[j])); } geas::add_clause(*SD, clause); } void p_array_bool_or(SolverInstanceBase& s, const Call* call) { auto* arr = ARRAY(0); vec clause; clause.push(~BOOLVAR(1)); for (int i = 0; i < arr->size(); ++i) { geas::patom_t elem = SI.asBoolVar((*arr)[i]); geas::add_clause(SD, BOOLVAR(1), ~elem); clause.push(elem); } geas::add_clause(*SD, clause); } void p_array_bool_and(SolverInstanceBase& s, const Call* call) { auto* arr = ARRAY(0); vec clause; clause.push(BOOLVAR(1)); for (int i = 0; i < arr->size(); ++i) { geas::patom_t elem = SI.asBoolVar((*arr)[i]); geas::add_clause(SD, ~BOOLVAR(1), elem); clause.push(~elem); } geas::add_clause(*SD, clause); } void p_bool_clause_imp(SolverInstanceBase& s, const Call* call) { auto* pos = ARRAY(0); auto* neg = ARRAY(1); vec clause; clause.push(~BOOLVAR(2)); for (int i = 0; i < pos->size(); ++i) { clause.push(SI.asBoolVar((*pos)[i])); } for (int j = 0; j < neg->size(); ++j) { clause.push(~SI.asBoolVar((*neg)[j])); } geas::add_clause(*SD, clause); } void p_array_bool_or_imp(SolverInstanceBase& s, const Call* call) { auto* arr = ARRAY(0); vec clause; clause.push(~BOOLVAR(1)); for (int i = 0; i < arr->size(); ++i) { geas::patom_t elem = SI.asBoolVar((*arr)[i]); clause.push(elem); } geas::add_clause(*SD, clause); } void p_array_bool_and_imp(SolverInstanceBase& s, const Call* call) { auto* arr = ARRAY(0); for (int i = 0; i < arr->size(); ++i) { geas::add_clause(SD, ~BOOLVAR(1), SI.asBoolVar((*arr)[i])); } } void p_bool_clause_reif(SolverInstanceBase& s, const Call* call) { auto* pos = ARRAY(0); auto* neg = ARRAY(1); vec clause; clause.push(~BOOLVAR(2)); for (int i = 0; i < pos->size(); ++i) { geas::patom_t elem = SI.asBoolVar((*pos)[i]); geas::add_clause(SD, BOOLVAR(2), ~elem); clause.push(elem); } for (int j = 0; j < neg->size(); ++j) { geas::patom_t elem = SI.asBoolVar((*neg)[j]); geas::add_clause(SD, BOOLVAR(2), elem); clause.push(~elem); } geas::add_clause(*SD, clause); } void p_bool_lin_eq(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = BOOLVARARRAY(1); // TODO: Rewrite using MiniZinc Library?? geas::bool_linear_le(SD, geas::at_True, SI.zero, cons, vars, -INT(2)); geas::bool_linear_ge(SD, geas::at_True, SI.zero, cons, vars, -INT(2)); } void p_bool_lin_ne(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = BOOLVARARRAY(1); geas::bool_linear_ne(SD, cons, vars, INT(2)); } void p_bool_lin_le(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = BOOLVARARRAY(1); geas::bool_linear_ge(SD, geas::at_True, SI.zero, cons, vars, -INT(2)); } void p_bool_lin_eq_imp(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = BOOLVARARRAY(1); // TODO: Rewrite using MiniZinc Library?? geas::bool_linear_le(SD, BOOLVAR(3), SI.zero, cons, vars, -INT(2)); geas::bool_linear_ge(SD, BOOLVAR(3), SI.zero, cons, vars, -INT(2)); } void p_bool_lin_ne_imp(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = BOOLVARARRAY(1); geas::bool_linear_ne(SD, cons, vars, INT(2), BOOLVAR(3)); } void p_bool_lin_le_imp(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = BOOLVARARRAY(1); geas::bool_linear_ge(SD, BOOLVAR(3), SI.zero, cons, vars, -INT(2)); } void p_bool_lin_eq_reif(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = BOOLVARARRAY(1); // TODO: Rewrite using MiniZinc Library?? geas::bool_linear_le(SD, BOOLVAR(3), SI.zero, cons, vars, -INT(2)); geas::bool_linear_ge(SD, BOOLVAR(3), SI.zero, cons, vars, -INT(2)); geas::bool_linear_ne(SD, cons, vars, INT(2), ~BOOLVAR(3)); } void p_bool_lin_ne_reif(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = BOOLVARARRAY(1); // TODO: Rewrite using MiniZinc Library?? geas::bool_linear_ne(SD, cons, vars, INT(2), BOOLVAR(3)); geas::bool_linear_le(SD, ~BOOLVAR(3), SI.zero, cons, vars, -INT(2)); geas::bool_linear_ge(SD, ~BOOLVAR(3), SI.zero, cons, vars, -INT(2)); } void p_bool_lin_le_reif(SolverInstanceBase& s, const Call* call) { vec cons = INTARRAY(0); vec vars = BOOLVARARRAY(1); // TODO: Rewrite using MiniZinc Library?? geas::bool_linear_ge(SD, BOOLVAR(3), SI.zero, cons, vars, -INT(2)); geas::bool_linear_le(SD, ~BOOLVAR(3), SI.zero, cons, vars, -INT(2) - 1); } void p_bool2int(SolverInstanceBase& s, const Call* call) { geas::add_clause(SD, BOOLVAR(0), INTVAR(1) <= 0); geas::add_clause(SD, ~BOOLVAR(0), INTVAR(1) >= 1); } void p_array_int_element(SolverInstanceBase& s, const Call* call) { assert(ARRAY(1)->min(0) == 1 && ARRAY(1)->max(0) == ARRAY(1)->size() + 1); vec vals = INTARRAY(1); if (PAR(0)) { SOL.post(INTVAR(2) == vals[INT(0) - 1]); } else if (PAR(2)) { for (int j = 0; j < vals.size(); ++j) { if (vals[j] != INT(2)) { SOL.post(INTVAR(0) != j + 1); } } } else { geas::int_element(SD, INTVAR(2), INTVAR(0), vals); } } void p_array_bool_element(SolverInstanceBase& s, const Call* call) { assert(ARRAY(1)->min(0) == 1 && ARRAY(1)->max(0) == ARRAY(1)->size() + 1); vec vals = BOOLARRAY(1); if (PAR(0)) { SOL.post(vals[INT(0) - 1] ? BOOLVAR(2) : ~BOOLVAR(2)); } else if (PAR(2)) { for (int j = 0; j < vals.size(); ++j) { if (static_cast(vals[j]) != BOOL(2)) { SOL.post(INTVAR(0) != j + 1); } } } else { for (int j = 0; j < vals.size(); ++j) { geas::add_clause(SD, INTVAR(0) != j + 1, vals[j] ? BOOLVAR(2) : ~BOOLVAR(2)); } } } void p_array_var_int_element(SolverInstanceBase& s, const Call* call) { assert(ARRAY(1)->min(0) == 1 && ARRAY(1)->max(0) == ARRAY(1)->size() + 1); if (PAR(1)) { return p_array_int_element(s, call); } if (PAR(0) && PAR(2)) { SOL.post(SI.asIntVar((*ARRAY(1))[INT(0) - 1]) == INT(2)); } else if (PAR(0)) { Expression* elem = (*ARRAY(1))[INT(0) - 1]; if (elem->type().isPar()) { return p_array_int_element(s, call); } geas::int_eq(SD, SI.asIntVar(elem), INTVAR(2)); } else if (PAR(2)) { for (int j = 0; j < ARRAY(1)->size(); ++j) { Expression* elem = (*ARRAY(1))[j]; if (elem->type().isvar()) { geas::add_clause(SD, INTVAR(0) != j + 1, SI.asIntVar(elem) == INT(2)); } else { if (SI.asInt(elem) != INT(2)) { SOL.post(INTVAR(0) != j + 1); } } } } else { vec vals = INTVARARRAY(1); geas::var_int_element(SD, INTVAR(2), INTVAR(0), vals); } } void p_array_var_bool_element(SolverInstanceBase& s, const Call* call) { assert(ARRAY(1)->min(0) == 1 && ARRAY(1)->max(0) == ARRAY(1)->size() + 1); if (PAR(1)) { return p_array_bool_element(s, call); } if (PAR(0) && PAR(2)) { SOL.post(BOOL(2) ? SI.asBoolVar((*ARRAY(1))[INT(0) - 1]) : ~SI.asBoolVar((*ARRAY(1))[INT(0) - 1])); } else if (PAR(0)) { Expression* elem = (*ARRAY(1))[INT(0) - 1]; if (elem->type().isPar()) { return p_array_bool_element(s, call); } geas::add_clause(SD, BOOLVAR(2), ~SI.asBoolVar(elem)); geas::add_clause(SD, ~BOOLVAR(2), SI.asBoolVar(elem)); } else if (PAR(2)) { for (int j = 0; j < ARRAY(1)->size(); ++j) { Expression* elem = (*ARRAY(1))[j]; if (elem->type().isvar()) { geas::add_clause(SD, INTVAR(0) != j + 1, INT(2) ? SI.asBoolVar(elem) : ~SI.asBoolVar(elem)); } else { if (SI.asBool(elem) != INT(2)) { SOL.post(INTVAR(0) != j + 1); } } } } else { auto vars = BOOLVARARRAY(1); for (int j = 0; j < vars.size(); ++j) { geas::add_clause(SD, INTVAR(0) != j + 1, ~vars[j], BOOLVAR(2)); geas::add_clause(SD, INTVAR(0) != j + 1, vars[j], ~BOOLVAR(2)); } } } void p_all_different(SolverInstanceBase& s, const Call* call) { vec vars = INTVARARRAY(0); geas::all_different_int(SD, vars); } void p_all_different_except_0(SolverInstanceBase& s, const Call* call) { vec vars = INTVARARRAY(0); geas::all_different_except_0(SD, vars); } void p_at_most(SolverInstanceBase& s, const Call* call) { vec ivars = INTVARARRAY(1); vec bvars; for (auto& ivar : ivars) { bvars.push(ivar == INT(2)); } if (INT(0) == 1) { geas::atmost_1(SD, bvars); } else { geas::atmost_k(SD, bvars, INT(0)); } } void p_at_most1(SolverInstanceBase& s, const Call* call) { vec ivars = INTVARARRAY(0); vec bvars; for (auto& ivar : ivars) { bvars.push(ivar == INT(1)); } geas::atmost_1(SD, bvars); } void p_cumulative(SolverInstanceBase& s, const Call* call) { vec st = INTVARARRAY(0); if (PAR(1) && PAR(2) && PAR(3)) { vec d = INTARRAY(1); vec r = INTARRAY(2); geas::cumulative(SD, st, d, r, INT(3)); } else { vec d = INTVARARRAY(1); vec r = INTVARARRAY(2); geas::cumulative_var(SD, st, d, r, INTVAR(3)); } } void p_disjunctive(SolverInstanceBase& s, const Call* call) { vec st = INTVARARRAY(0); if (PAR(1)) { vec d = INTARRAY(1); geas::disjunctive_int(SD, st, d); } else { vec d = INTVARARRAY(1); geas::disjunctive_var(SD, st, d); } } void p_global_cardinality(SolverInstanceBase& s, const Call* call) { vec x = INTVARARRAY(0); vec cover = INTARRAY(1); vec count = INTARRAY(2); vec srcs(x.size(), 1); vec flows; for (int i = 0; i < x.size(); ++i) { for (int j = 0; j < cover.size(); ++j) { if (x[i].lb(SD) <= cover[j] && cover[j] <= x[i].ub(SD)) { flows.push({i, j, x[i] == cover[j]}); } } } geas::bipartite_flow(SD, srcs, count, flows); } void p_table_int(SolverInstanceBase& s, const Call* call) { auto& gi = static_cast(s); vec vars = INTVARARRAY(0); vec tmp = INTARRAY(1); assert(tmp.size() % vars.size() == 0); vec> table(tmp.size() == 0 ? 0 : tmp.size() / vars.size()); for (int i = 0; i < table.size(); ++i) { table[i].growTo(vars.size()); for (int j = 0; j < vars.size(); ++j) { table[i][j] = tmp[i * vars.size() + j]; } } geas::table_id id = geas::table::build(SD, table); // TODO: Annotations for table versions geas::table::post(SD, id, vars); } } // namespace GeasConstraints } // namespace MiniZinc #pragma clang diagnostic pop libminizinc-2.8.2/solvers/mzn/0000755000175000017500000000000014536677021015004 5ustar kaolkaollibminizinc-2.8.2/solvers/mzn/mzn_solverfactory.cpp0000644000175000017500000000047714536677021021306 0ustar kaolkaol#include #include namespace MiniZinc { namespace { void get_wrapper() { static MZNSolverFactory _mzn_solverfactory; } } // namespace MZNSolverFactoryInitialiser::MZNSolverFactoryInitialiser() { get_wrapper(); } } // namespace MiniZinc libminizinc-2.8.2/solvers/mzn/mzn_solverinstance.cpp0000644000175000017500000001457114536677021021443 0ustar kaolkaol/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Guido Tack */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifdef _MSC_VER #define _CRT_SECURE_NO_WARNINGS #endif #include #include #include #include #include using namespace std; namespace MiniZinc { MZNSolverFactory::MZNSolverFactory() { SolverConfig sc("org.minizinc.mzn-mzn", MZN_VERSION_MAJOR "." MZN_VERSION_MINOR "." MZN_VERSION_PATCH); sc.name("Generic MiniZinc driver"); sc.mznlibVersion(1); sc.description("MiniZinc generic MiniZinc solver plugin"); sc.requiredFlags({"-m"}); sc.tags({"__internal__"}); sc.inputType(SolverConfig::O_MZN); sc.needsSolns2Out(false); SolverConfigs::registerBuiltinSolver(sc); } string MZNSolverFactory::getDescription(SolverInstanceBase::Options* /*opt*/) { string v = "MZN solver plugin, compiled " __DATE__ " " __TIME__; return v; } string MZNSolverFactory::getVersion(SolverInstanceBase::Options* /*opt*/) { return MZN_VERSION_MAJOR; } string MZNSolverFactory::getId() { return "org.minizinc.mzn-mzn"; } void MZNSolverFactory::printHelp(ostream& os) { os << "MZN-MZN plugin options:" << std::endl << " -m, --minizinc-cmd \n the backend solver filename.\n" << " --mzn-flags , --minizinc-flags , --backend-flags \n" " Specify option to be passed to the MiniZinc interpreter.\n" << " --mzn-flag