From 2c8ad0004aacbd87b80f67970c2da0d051ff8279 Mon Sep 17 00:00:00 2001 From: "Jip J. Dekker" Date: Mon, 12 Jul 2021 20:08:41 +1000 Subject: [PATCH] Squashed 'software/minizinc/' changes from 4f10c82056..93be33a6c2 93be33a6c2 Add complete predicate REVERT: 4f10c82056 Merge branch 'MiniZinc:master' into feature/on_restart REVERT: 0848ce7ec7 Add changelog for 2.5.5 REVERT: 44e2f770d5 Add test for insertion of ArrayLits into CSE REVERT: 8a68d3dea8 Don't insert par expressions into CSE map unless they're an ArrayLit REVERT: 6bf6f1180f Increase version number of development build REVERT: dcaac92a74 Make min/max on array of opt vars return non-optional var. This is consistent with other functions on optional arrays like sum, product, exists, forall. REVERT: 32aa288884 Update changelog REVERT: a4edf0669f Fix flattening of all-par set literals REVERT: 8c1c9605f6 Fix chain compressor, needs to ignore par constants REVERT: 0cad1c6306 Use file_path on include paths to ensure separator consistency REVERT: 05ad7d1931 Update changelog REVERT: 22f5e2557b Define HAVE_CONFIG_H only for UNIX REVERT: 81c7778d55 Define HAVE_CONFIG_H for CBC REVERT: 1f56608e10 mzn-test: don't check symmetry breaking constraints REVERT: 1a9767457e mzn-test: fix parsing %%%mzn-stat: ... output REVERT: a41533fd54 MIP: report CPU time in %%%mzn-stat: solveTime= REVERT: 9d490acd52 Updated docs on OR-Tools v8 installation REVERT: c513f6599f Add changelog for 2.5.4 REVERT: b2eef2772b Follow ids to declarations when flattening par arrays. Fixes #448. REVERT: c5c846d426 Check if result of flattening rhs of a vardecl is par. REVERT: c496052767 Escape strings when pretty printing include items REVERT: 9e379c995e Canonicalise file names before adding include items into "already seen" list REVERT: d5d5d0d88c Use generic flattening inside generators. Fixes #451. REVERT: dc8630a6e9 Small fix to multi-pass library change: use original include path if it is absolute REVERT: 79c6092bd8 Strip library paths from includes in multi-pass compilation. Fixes #455. REVERT: 897875d6d7 Compile infinite domains with holes into constraints. Fixes #457. REVERT: b4e700dc67 Don't create copies of global declarations when creating par versions of functions REVERT: 0e8cc42bb1 Fix typechecker to coerce bool to int in the objective. REVERT: e05523b344 Add test for dzn output of arrays REVERT: 1e0269000e Don't evaluate output_only arrays when generating dzn output. REVERT: 57018c31d6 Fix matrix transposition in lex2 globals REVERT: 2617c0c829 Fix output variables in lex_chain tests REVERT: ef1a250c98 another efort to fix tests REVERT: c00e199dfd Fix test globals_lex_chain.mzn REVERT: b5c997d045 Fix code analysis REVERT: 3352cf0bd5 SCIP constraint handler for lex_chain_..._orbitope REVERT: 4e71a2cc97 Globals lex_chain_..., including lex_chain_..._orbitope REVERT: d807428baf Move test specifcation into the correct folder REVERT: 5be74bc74d MIP decompositions for lex_less_(bool, int, float) REVERT: 36a554ba40 Don't modify infinte domain of optional variables. Fixes #456. REVERT: f9e5306d75 Run clang-format REVERT: 4b57667608 Fix comment reference to relevant test case REVERT: 648f2ab36d Fix equality of indirection annotations REVERT: ef7be5fd78 MIP decompositions for lex_lesseq_(bool=int, float) REVERT: 6511b14e73 Propagate cv flag correctly. REVERT: 6f27ecf1c0 Never insert par expressions into the CSE map. REVERT: 7414f3ca0f Fix cplex id in example configuration REVERT: 7ad7cec506 Update strictly_decreasing with documentation and opt version REVERT: 8029f6e957 Support undefined enums in type checker. REVERT: 79e0f0f546 Revert using mzn_in_symmetry_breaking_constraint() for SCIP's orbisack REVERT: e88efda76c Fix format REVERT: 4802031dc1 Added test mzn_in_symmetry_breaking_constraint() REVERT: e21cc2515a More format fixes 02 ... REVERT: 5bbd67c130 More format fixes... REVERT: d5f9b777ea Format fixes REVERT: 43757a09a0 Remove MIP-specific fzn_less(eq)_bool(_reif).mzn REVERT: c93b5736a3 SCIP: orbisack constraint handler 'fzn_lex_lesseq__orbisack' REVERT: 4516bb4e2c mzn-test.py: add OR-Tools as checker REVERT: e2176f017d Add fix and test for crash with empty enum. REVERT: ac7db35951 Fix documentation bugs. REVERT: 47ba245832 Fix the incorrect renaming of key in model output interface REVERT: 925796ed20 Fail on empty var domains in agenda REVERT: 1ec19d7025 Fix error messages in CMake FindGurobi, FindCPlex REVERT: 6d169475c1 mzn-test.py: Use -i for intermediate solutions REVERT: df2f3e423a Allow coercion of JSON lists to enum definitions REVERT: 2b0b8165e5 Fix clang-tidy errors REVERT: 6597bc1920 Change the CI build image location REVERT: 360c988452 Remove illegal duplicate keys in .gitlab-ci.yml REVERT: 6a5d69c64b Add missing par opt versions of coercion functions REVERT: 63014e3d8f Don't propagate annotations into annotation calls. Avoids infinite recursion. REVERT: 54b19428ab Don't use GRB_INT_PAR_NONCONVEX if it's undefined REVERT: a5bb56c47d Added piecewise_linear for non-continuous intervals git-subtree-dir: software/minizinc git-subtree-split: 93be33a6c254e54be7cd38abb7ebd6a6022f0c46 --- .gitlab-ci.yml | 18 +- CMakeLists.txt | 2 +- changes.rst | 104 --- cmake/modules/FindCPlex.cmake | 2 +- cmake/modules/FindGurobi.cmake | 2 +- cmake/targets/libminizinc_osicbc.cmake | 3 - docs/chi/conf.py | 2 +- docs/en/command_line.rst | 4 +- docs/en/conf.py | 2 +- docs/en/grammar.mzn | 4 +- docs/en/installation_detailed_linux.rst | 6 +- docs/en/solvers.rst | 6 +- include/minizinc/MIPdomains.hh | 22 +- include/minizinc/ast.hh | 2 - include/minizinc/eval_par.hh | 18 +- include/minizinc/flatten_internal.hh | 1 - include/minizinc/output.hh | 4 +- include/minizinc/param_config.hh | 5 +- include/minizinc/parser.hh | 10 +- include/minizinc/process.hh | 1 + include/minizinc/solns2out.hh | 2 +- include/minizinc/solver_instance.hh | 2 +- include/minizinc/solvers/MIP/MIP_scip_wrap.hh | 27 - .../solvers/MIP/MIP_solverinstance.hpp | 46 +- include/minizinc/solvers/MIP/MIP_wrap.hh | 17 +- .../minizinc/solvers/MIP/MIP_xpress_wrap.hh | 28 +- include/minizinc/utils.hh | 22 +- lib/MIPdomains.cpp | 592 +++++++-------- lib/ast.cpp | 2 - lib/builtins.cpp | 10 +- lib/cached/md5_cached.cmake | 2 +- lib/cached/minizinc/parser.tab.hh | 8 +- lib/cached/parser.tab.cpp | 708 +++++++++--------- lib/chain_compressor.cpp | 93 ++- lib/eval_par.cpp | 67 +- lib/flatten.cpp | 36 +- lib/flatten/flatten_comp.cpp | 3 + lib/flatten/flatten_par.cpp | 43 +- lib/flatten/flatten_setlit.cpp | 6 +- lib/flatten/flatten_vardecl.cpp | 7 - lib/flattener.cpp | 5 +- lib/json_parser.cpp | 5 +- lib/output.cpp | 46 +- lib/parser.cpp | 107 ++- lib/parser.yxx | 10 +- lib/passes/compile_pass.cpp | 20 +- lib/prettyprinter.cpp | 4 +- lib/solver_instance_base.cpp | 2 +- lib/typecheck.cpp | 93 +-- share/minizinc/Preferences.json | 6 +- .../linear/fzn_lex_chain_lesseq_bool.mzn | 4 - .../linear/fzn_lex_chain_lesseq_int.mzn | 23 - .../linear/fzn_lex_chain_lesseq_orbitope.mzn | 40 - share/minizinc/linear/fzn_lex_less_bool.mzn | 12 - .../linear/fzn_lex_less_bool_reif.mzn | 21 + share/minizinc/linear/fzn_lex_less_float.mzn | 38 - share/minizinc/linear/fzn_lex_less_int.mzn | 39 - share/minizinc/linear/fzn_lex_lesseq_bool.mzn | 43 +- .../linear/fzn_lex_lesseq_bool_reif.mzn | 50 ++ .../minizinc/linear/fzn_lex_lesseq_float.mzn | 38 - share/minizinc/linear/fzn_lex_lesseq_int.mzn | 77 -- share/minizinc/linear/options.mzn | 18 +- share/minizinc/std/fzn_lex2.mzn | 23 +- share/minizinc/std/fzn_lex2_reif.mzn | 19 +- .../minizinc/std/fzn_lex_chain_less_bool.mzn | 11 - .../std/fzn_lex_chain_less_bool_reif.mzn | 12 - share/minizinc/std/fzn_lex_chain_less_int.mzn | 11 - .../std/fzn_lex_chain_less_int_reif.mzn | 12 - .../std/fzn_lex_chain_lesseq_bool.mzn | 11 - .../std/fzn_lex_chain_lesseq_bool_reif.mzn | 12 - .../minizinc/std/fzn_lex_chain_lesseq_int.mzn | 11 - .../std/fzn_lex_chain_lesseq_int_reif.mzn | 12 - .../std/fzn_lex_chain_lesseq_orbitope.mzn | 23 - .../fzn_lex_chain_lesseq_orbitope_reif.mzn | 23 - share/minizinc/std/fzn_piecewise_linear.mzn | 7 +- .../fzn_piecewise_linear_non_continuous.mzn | 37 - ...n_piecewise_linear_non_continuous_reif.mzn | 7 - share/minizinc/std/fzn_strict_lex2.mzn | 24 +- share/minizinc/std/fzn_strict_lex2_reif.mzn | 22 +- .../std/fzn_strictly_decreasing_int_opt.mzn | 8 - share/minizinc/std/globals.mzn | 9 +- share/minizinc/std/lex2_strict.mzn | 8 - share/minizinc/std/lex_chain_greater.mzn | 28 - share/minizinc/std/lex_chain_greatereq.mzn | 28 - .../std/lex_chain_greatereq_orbitope.mzn | 19 - share/minizinc/std/lex_chain_less.mzn | 19 - share/minizinc/std/lex_chain_less_bool.mzn | 12 - share/minizinc/std/lex_chain_less_int.mzn | 12 - share/minizinc/std/lex_chain_lesseq.mzn | 33 - share/minizinc/std/lex_chain_lesseq_bool.mzn | 12 - share/minizinc/std/lex_chain_lesseq_int.mzn | 12 - .../std/lex_chain_lesseq_orbitope.mzn | 18 - share/minizinc/std/piecewise_linear.mzn | 8 +- .../std/piecewise_linear_non_continuous.mzn | 29 - share/minizinc/std/restart.mzn | 8 +- share/minizinc/std/stdlib/stdlib_coercion.mzn | 30 - share/minizinc/std/stdlib/stdlib_internal.mzn | 22 - share/minizinc/std/stdlib/stdlib_math.mzn | 60 +- share/minizinc/std/strictly_decreasing.mzn | 8 - solvers/MIP/MIP_cplex_wrap.cpp | 2 +- solvers/MIP/MIP_gurobi_wrap.cpp | 5 +- solvers/MIP/MIP_osicbc_wrap.cpp | 14 +- solvers/MIP/MIP_scip_wrap.cpp | 60 +- solvers/MIP/MIP_xpress_wrap.cpp | 2 +- tests/benchmarking/cmp_result_logs.py | 6 +- tests/benchmarking/mzn-test.py | 28 +- tests/spec/unit/general/test_empty_enum.mzn | 9 - .../spec/unit/general/test_undefined_enum.fzn | 0 .../spec/unit/general/test_undefined_enum.mzn | 19 - .../globals/lex_chain/globals_lex_chain.mzn | 53 -- .../lex_chain/globals_lex_chain__orbitope.mzn | 48 -- tests/spec/unit/json/json_enum_def.json | 6 - tests/spec/unit/json/json_enum_def.mzn | 24 - tests/spec/unit/optional/test_bug_456.fzn | 4 - tests/spec/unit/optional/test_bug_456.mzn | 15 - tests/spec/unit/output/dzn_output_array.mzn | 20 - tests/spec/unit/output/dzn_output_array.ozn | 11 - tests/spec/unit/regression/coercion_par.mzn | 15 - tests/spec/unit/regression/cse_array_lit.fzn | 5 - tests/spec/unit/regression/cse_array_lit.mzn | 17 - .../spec/unit/regression/flatten_comp_in.mzn | 4 +- .../spec/unit/regression/flatten_comp_in2.mzn | 6 +- .../test_equality_of_indirect_annotations.mzn | 19 - 123 files changed, 1217 insertions(+), 2475 deletions(-) delete mode 100644 share/minizinc/linear/fzn_lex_chain_lesseq_bool.mzn delete mode 100644 share/minizinc/linear/fzn_lex_chain_lesseq_int.mzn delete mode 100644 share/minizinc/linear/fzn_lex_chain_lesseq_orbitope.mzn delete mode 100644 share/minizinc/linear/fzn_lex_less_bool.mzn create mode 100644 share/minizinc/linear/fzn_lex_less_bool_reif.mzn delete mode 100644 share/minizinc/linear/fzn_lex_less_float.mzn delete mode 100644 share/minizinc/linear/fzn_lex_less_int.mzn create mode 100644 share/minizinc/linear/fzn_lex_lesseq_bool_reif.mzn delete mode 100644 share/minizinc/linear/fzn_lex_lesseq_float.mzn delete mode 100644 share/minizinc/linear/fzn_lex_lesseq_int.mzn delete mode 100644 share/minizinc/std/fzn_lex_chain_less_bool.mzn delete mode 100644 share/minizinc/std/fzn_lex_chain_less_bool_reif.mzn delete mode 100644 share/minizinc/std/fzn_lex_chain_less_int.mzn delete mode 100644 share/minizinc/std/fzn_lex_chain_less_int_reif.mzn delete mode 100644 share/minizinc/std/fzn_lex_chain_lesseq_bool.mzn delete mode 100644 share/minizinc/std/fzn_lex_chain_lesseq_bool_reif.mzn delete mode 100644 share/minizinc/std/fzn_lex_chain_lesseq_int.mzn delete mode 100644 share/minizinc/std/fzn_lex_chain_lesseq_int_reif.mzn delete mode 100644 share/minizinc/std/fzn_lex_chain_lesseq_orbitope.mzn delete mode 100644 share/minizinc/std/fzn_lex_chain_lesseq_orbitope_reif.mzn delete mode 100644 share/minizinc/std/fzn_piecewise_linear_non_continuous.mzn delete mode 100644 share/minizinc/std/fzn_piecewise_linear_non_continuous_reif.mzn delete mode 100644 share/minizinc/std/fzn_strictly_decreasing_int_opt.mzn delete mode 100644 share/minizinc/std/lex2_strict.mzn delete mode 100644 share/minizinc/std/lex_chain_greater.mzn delete mode 100644 share/minizinc/std/lex_chain_greatereq.mzn delete mode 100644 share/minizinc/std/lex_chain_greatereq_orbitope.mzn delete mode 100644 share/minizinc/std/lex_chain_less.mzn delete mode 100644 share/minizinc/std/lex_chain_less_bool.mzn delete mode 100644 share/minizinc/std/lex_chain_less_int.mzn delete mode 100644 share/minizinc/std/lex_chain_lesseq.mzn delete mode 100644 share/minizinc/std/lex_chain_lesseq_bool.mzn delete mode 100644 share/minizinc/std/lex_chain_lesseq_int.mzn delete mode 100644 share/minizinc/std/lex_chain_lesseq_orbitope.mzn delete mode 100644 share/minizinc/std/piecewise_linear_non_continuous.mzn delete mode 100644 tests/spec/unit/general/test_empty_enum.mzn delete mode 100644 tests/spec/unit/general/test_undefined_enum.fzn delete mode 100644 tests/spec/unit/general/test_undefined_enum.mzn delete mode 100644 tests/spec/unit/globals/lex_chain/globals_lex_chain.mzn delete mode 100644 tests/spec/unit/globals/lex_chain/globals_lex_chain__orbitope.mzn delete mode 100644 tests/spec/unit/json/json_enum_def.json delete mode 100644 tests/spec/unit/json/json_enum_def.mzn delete mode 100644 tests/spec/unit/optional/test_bug_456.fzn delete mode 100644 tests/spec/unit/optional/test_bug_456.mzn delete mode 100644 tests/spec/unit/output/dzn_output_array.mzn delete mode 100644 tests/spec/unit/output/dzn_output_array.ozn delete mode 100644 tests/spec/unit/regression/coercion_par.mzn delete mode 100644 tests/spec/unit/regression/cse_array_lit.fzn delete mode 100644 tests/spec/unit/regression/cse_array_lit.mzn delete mode 100644 tests/spec/unit/regression/test_equality_of_indirect_annotations.mzn diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b99db09..2f9fcaa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,7 +8,7 @@ stages: - sh download.sh vendor master vendor:${MZNARCH} vendor.zip - unzip -q vendor.zip -.download_vendor_win: &download_vendor_win +.download_vendor: &download_vendor_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 vendor master vendor:%MZNARCH% vendor.zip @@ -19,7 +19,7 @@ stages: - sh download.sh vendor master bundle:${MZNARCH} vendor.zip - unzip -q vendor.zip -.download_bundle_win: &download_bundle_win +.download_bundle: &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 vendor master bundle:%MZNARCH% vendor.zip @@ -51,7 +51,7 @@ default: build:linux: extends: .build - image: minizinc/build-environment:cpp + image: dekker1/minibuild:cpp variables: MZNARCH: "linux" CMAKE_ARCH: "Ninja" @@ -59,7 +59,7 @@ build:linux: build:musl: extends: .build - image: minizinc/build-environment:alpine + image: dekker1/minibuild:alpine variables: MZNARCH: "musl" CMAKE_ARCH: "Ninja" @@ -118,7 +118,7 @@ build:wasm_minimal: test:format: stage: test - image: minizinc/build-environment:clang-format + image: dekker1/minibuild:clang-format script: - cmake -S . -B build -GNinja -DCLANG_FORMAT_EXECUTABLE="run-clang-format" -DCLANG_FORMAT_FLAGS="--color always" - cmake --build build --target format @@ -134,7 +134,7 @@ test:format: test:analyse: extends: .build stage: test - image: minizinc/build-environment:clang-tidy + image: dekker1/minibuild:clang-tidy variables: MZNARCH: "linux" CMAKE_ARCH: "Ninja" @@ -158,7 +158,7 @@ test:analyse: before_script: - *download_bundle # TODO: Add gecode configuration to the Gecode solver - - 'echo ''{"id":"org.gecode.gecode","name":"Gecode","description":"Gecode FlatZinc executable","version":"6.1.1","mznlib":"share/gecode/mznlib","executable":"bin/fzn-gecode","tags":["cp","int","float","set","restart"],"stdFlags":["-a","-f","-n","-p","-r","-s","-t"],"extraFlags":[["-c-d","Recomputation commit distance","int","8"],["-a-d","Recomputation adaption distance","int","2"],["-decay","Decay factor","float","0.99"],["-node","Node cutoff","int","0"],["-fail","Failure cutoff","int","0"],["-restart","Restart sequence type","opt:none:constant:linear:luby:geometric","none"],["-restart-base","Base for geometric restart sequence","float","1.5"],["-restart-scale","Scale factor for restart sequence","int","250"],["-nogoods","Use no-goods from restarts","bool","false"],["-nogoods-limit","Depth limit for no-good extraction","int","128"]],"supportsMzn":false,"supportsFzn":true,"needsSolns2Out":true,"needsMznExecutable":false,"needsStdlibDir":false,"isGUIApplication":false}'' > vendor/gecode/gecode.msc' + - "echo '{\"id\":\"org.gecode.gecode\",\"name\":\"Gecode\",\"description\":\"Gecode FlatZinc executable\",\"version\":\"6.1.1\",\"mznlib\":\"share/gecode/mznlib\",\"executable\":\"bin/fzn-gecode\",\"tags\":[\"cp\",\"int\",\"float\",\"set\",\"restart\"],\"stdFlags\":[\"-a\",\"-f\",\"-n\",\"-p\",\"-r\",\"-s\",\"-t\"],\"extraFlags\":[[\"-c-d\",\"Recomputation commit distance\",\"int\",\"8\"],[\"-a-d\",\"Recomputation adaption distance\",\"int\",\"2\"],[\"-decay\",\"Decay factor\",\"float\",\"0.99\"],[\"-node\",\"Node cutoff\",\"int\",\"0\"],[\"-fail\",\"Failure cutoff\",\"int\",\"0\"],[\"-restart\",\"Restart sequence type\",\"opt:none:constant:linear:luby:geometric\",\"none\"],[\"-restart-base\",\"Base for geometric restart sequence\",\"float\",\"1.5\"],[\"-restart-scale\",\"Scale factor for restart sequence\",\"int\",\"250\"],[\"-nogoods\",\"Use no-goods from restarts\",\"bool\",\"false\"],[\"-nogoods-limit\",\"Depth limit for no-good extraction\",\"int\",\"128\"]],\"supportsMzn\":false,\"supportsFzn\":true,\"needsSolns2Out\":true,\"needsMznExecutable\":false,\"needsStdlibDir\":false,\"isGUIApplication\":false}' > vendor/gecode/gecode.msc" - export PATH=$CI_PROJECT_DIR/minizinc/bin:$PATH - minizinc --solvers - cd tests @@ -170,7 +170,7 @@ test:analyse: artifacts: when: always paths: - - tests/output + - tests/output reports: junit: tests/output/junit*.xml cache: @@ -213,7 +213,7 @@ test:analyse: - 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" + - '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"] diff --git a/CMakeLists.txt b/CMakeLists.txt index ceb5890..9eab57e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment ver # -- Project information and versioning. project(libminizinc - VERSION 2.5.5 + VERSION 2.5.4 LANGUAGES CXX C) if(NOT BUILD_REF) diff --git a/changes.rst b/changes.rst index 416e7a9..9ea4f7d 100644 --- a/changes.rst +++ b/changes.rst @@ -4,110 +4,6 @@ MiniZinc Change Log For detailed bug reports consult the issue tracker at https://github.com/MiniZinc/libminizinc/issues. -.. _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 `__ diff --git a/cmake/modules/FindCPlex.cmake b/cmake/modules/FindCPlex.cmake index a626924..2c9c5f0 100644 --- a/cmake/modules/FindCPlex.cmake +++ b/cmake/modules/FindCPlex.cmake @@ -61,7 +61,7 @@ find_package_handle_standard_args(CPlex FOUND_VAR CPLEX_FOUND REQUIRED_VARS CPLEX_INCLUDE CPLEX_LIBRARY VERSION_VAR CPLEX_VERSION - FAIL_MESSAGE "Could NOT find CPlex, use CPlex_ROOT to hint its location" + FAIL_MESSAGE "Could NOT find CPlex, use CPLEX_ROOT to hint its location" ) if(CPLEX_PLUGIN AND HAS_WINDOWS_H AND NOT HAS_DLFCN_H) diff --git a/cmake/modules/FindGurobi.cmake b/cmake/modules/FindGurobi.cmake index a308bcc..953cf1d 100644 --- a/cmake/modules/FindGurobi.cmake +++ b/cmake/modules/FindGurobi.cmake @@ -69,7 +69,7 @@ find_package_handle_standard_args(Gurobi FOUND_VAR GUROBI_FOUND REQUIRED_VARS GUROBI_INCLUDE GUROBI_LIBRARY VERSION_VAR GUROBI_VERSION - FAIL_MESSAGE "Could NOT find Gurobi, use Gurobi_ROOT to hint its location" + FAIL_MESSAGE "Could NOT find Gurobi, use GUROBI_ROOT to hint its location" ) if(GUROBI_PLUGIN AND HAS_WINDOWS_H AND NOT HAS_DLFCN_H) diff --git a/cmake/targets/libminizinc_osicbc.cmake b/cmake/targets/libminizinc_osicbc.cmake index 66091ce..a7228f8 100644 --- a/cmake/targets/libminizinc_osicbc.cmake +++ b/cmake/targets/libminizinc_osicbc.cmake @@ -13,9 +13,6 @@ if(OSICBC_FOUND) ) target_include_directories(minizinc_osicbc PRIVATE ${OSICBC_INCLUDE_DIRS}) add_dependencies(minizinc_osicbc minizinc_mip) - if (UNIX AND NOT WIN32) - target_compile_definitions(minizinc_osicbc PRIVATE HAVE_CONFIG_H) - endif() ### Setup correct compilation into the MiniZinc library target_compile_definitions(mzn PRIVATE HAS_OSICBC) diff --git a/docs/chi/conf.py b/docs/chi/conf.py index 787bdb0..50c2e56 100755 --- a/docs/chi/conf.py +++ b/docs/chi/conf.py @@ -73,7 +73,7 @@ author = 'Peter J. Stuckey, Kim Marriott, Guido Tack' # The short X.Y version. version = '2.5' # The full version, including alpha/beta/rc tags. -release = '2.5.5' +release = '2.5.4' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/en/command_line.rst b/docs/en/command_line.rst index b7a404b..5d6f4eb 100644 --- a/docs/en/command_line.rst +++ b/docs/en/command_line.rst @@ -511,8 +511,8 @@ Here is a sample configuration file: { "mzn_solver_path": ["/usr/share/choco"], - "tagDefaults": [["cp","org.choco-solver.choco"],["mip","org.minizinc.mip.cplex"],["","org.gecode.gecode"]], - "solverDefaults": [["org.minizinc.mip.cplex","--cplex-dll","/opt/CPLEX_Studio128/cplex/bin/x86-64_sles10_4.1/libcplex128.so"]] + "tagDefaults": [["cp","org.choco-solver.choco"],["mip","org.minizinc.cplex"],["","org.gecode.gecode"]], + "solverDefaults": [["org.minizinc.cplex","--cplex-dll","/opt/CPLEX_Studio128/cplex/bin/x86-64_sles10_4.1/libcplex128.so"]] } Configuration values in the user-specific configuration file override the global values, except for solver default arguments, which are only overridden if the name of the option is the same, and otherwise get added to the command line. diff --git a/docs/en/conf.py b/docs/en/conf.py index 2467977..1198b51 100755 --- a/docs/en/conf.py +++ b/docs/en/conf.py @@ -73,7 +73,7 @@ author = 'Peter J. Stuckey, Kim Marriott, Guido Tack' # The short X.Y version. version = '2.5' # The full version, including alpha/beta/rc tags. -release = '2.5.5' +release = '2.5.4' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/en/grammar.mzn b/docs/en/grammar.mzn index 0d04f8d..55d0aa4 100644 --- a/docs/en/grammar.mzn +++ b/docs/en/grammar.mzn @@ -35,7 +35,7 @@ ::= "=" % Constraint items - ::= "constraint" [ ] + ::= "constraint" % Solve item ::= "solve" "satisfy" @@ -80,7 +80,7 @@ | | | "ann" - | "{" "," ... "}" + | { "," ... } | ".." % Type-inst variables diff --git a/docs/en/installation_detailed_linux.rst b/docs/en/installation_detailed_linux.rst index b3ed249..03a2cfd 100644 --- a/docs/en/installation_detailed_linux.rst +++ b/docs/en/installation_detailed_linux.rst @@ -86,16 +86,14 @@ OR Tools You can install the OR-Tools FlatZinc module as binary or obtain the source code from GitHub (https://github.com/google/or-tools). You can find detailed compilation instructions for OR-Tools on https://developers.google.com/optimization/. -Since version 8, `cmake` is supported, see the instructions. Previously, to compile the FlatZinc module from source, -run the following in a terminal (from within the OR-Tools source code directory): +To compile the FlatZinc module from source, run the following in a terminal (from within the OR-Tools source code directory): .. code-block:: bash make fz -j8 make test_fz -Since version 8, `cmake --build . --target install` puts a solver configuration file in `/usr/share/minizinc`, so the MiniZinc finds -OR-Tools automatically. With earlier versions, in order to use OR-Tools with MiniZinc, you have to create an appropriate solver configuration file. +In order to use OR-Tools with MiniZinc, you have to create an appropriate solver configuration file. Add a file ``ortools.msc`` in an appropriate location (see :ref:`sec-cmdline-conffiles`) containing the following, where you replace ```` with the actual installation path and update the version number if necessary: diff --git a/docs/en/solvers.rst b/docs/en/solvers.rst index 606618f..bdb5ca8 100644 --- a/docs/en/solvers.rst +++ b/docs/en/solvers.rst @@ -143,11 +143,7 @@ The following parameters can be given on the command line or modified in ``share -DfIndConstr=true -DfMIPdomains=false %% Use solver's indicator constraints, see below -DMinMaxGeneral=true %% Send min/max constraints to the solver (Gurobi only) -DQuadrFloat=false -DQuadrInt=false %% Not forward float/integer multiplications for MIQCP backends, see below - -DUseCumulative=false %% Not forward cumulative with fixed durations/resources (SCIP only) - -DUseOrbisack=false %% Not forward lex_lesseq for binary/bool vectors (SCIP only) - -DOrbisackAlwaysModelConstraint=true %% lex_lesseq ignores being in symmetry_breaking_constraint() (SCIP only) - %% Required for SCIP 7.0.2, or use patch: http://listserv.zib.de/pipermail/scip/2021-February/004213.html - -DUseOrbitope=false %% Not forward lex_chain_lesseq for binary/bool matrices (SCIP only) + -DCumulative=false %% Not forward cumulative with fixed durations/resources (SCIP only) --no-half-reifications %% Turn off halfreification (full reification was until v2.2.3) Some Solver Options and Changed Default Values diff --git a/include/minizinc/MIPdomains.hh b/include/minizinc/MIPdomains.hh index fa36c0b..348715a 100644 --- a/include/minizinc/MIPdomains.hh +++ b/include/minizinc/MIPdomains.hh @@ -22,23 +22,23 @@ #define _CRT_SECURE_NO_WARNINGS #endif -#define MZN_MIPD_assert_soft(c, e) \ +#define MZN_MIPD__assert_soft(c, e) \ do { \ static int nn = 0; \ if (!(c)) \ if (++nn <= 1) std::cerr << e << std::endl; /* NOLINT(bugprone-macro-parentheses) */ \ } while (0) -#define MZN_MIPD_assert_hard(c) MZN_ASSERT_HARD(c) -#define MZN_MIPD_assert_hard_msg(c, e) MZN_ASSERT_HARD_MSG(c, e) -#define MZN_MIPD_FLATTENING_ERROR_IF_NOT(cond, envi, loc, msg) \ - do { \ - if (!(cond)) { \ - std::ostringstream oss; \ - oss << msg; /* NOLINT(bugprone-macro-parentheses) */ \ - throw FlatteningError(envi, loc, oss.str()); \ - } \ +#define MZN_MIPD__assert_hard(c) MZN_ASSERT_HARD(c) +#define MZN_MIPD__assert_hard_msg(c, e) MZN_ASSERT_HARD_MSG(c, e) +#define MZN_MIPD__FLATTENING_ERROR__IF_NOT(cond, envi, loc, msg) \ + do { \ + if (!(cond)) { \ + std::ostringstream oss; \ + oss << msg; /* NOLINT(bugprone-macro-parentheses) */ \ + throw FlatteningError(envi, loc, oss.str()); \ + } \ } while (0) -#define MZN_MIPD_ASSERT_FOR_SAT(cond, envi, loc, msg) \ +#define MZN_MIPD__ASSERT_FOR_SAT(cond, envi, loc, msg) \ do { \ if (!(cond)) { \ std::ostringstream oss; \ diff --git a/include/minizinc/ast.hh b/include/minizinc/ast.hh index 69529db..2fb0a87 100644 --- a/include/minizinc/ast.hh +++ b/include/minizinc/ast.hh @@ -1838,8 +1838,6 @@ public: ASTString set_card; // NOLINT(readability-identifier-naming) ASTString pow; - ASTString mzn_set_in_internal; // NOLINT(readability-identifier-naming) - ASTString introduced_var; // NOLINT(readability-identifier-naming) ASTString anonEnumFromStrings; } ids; diff --git a/include/minizinc/eval_par.hh b/include/minizinc/eval_par.hh index 2bece78..d710e0b 100644 --- a/include/minizinc/eval_par.hh +++ b/include/minizinc/eval_par.hh @@ -87,8 +87,6 @@ class EvalBase { public: /// Evaluate bool expression that may contain variables static bool evalBoolCV(EnvI& env, Expression* e); - /// Flatten expression that may contain variables - static KeepAlive flattenCV(EnvI& env, Expression* e); }; template @@ -124,7 +122,7 @@ void eval_comp_set(EnvI& env, Eval& eval, Comprehension* e, int gen, int id, Int KeepAlive nextin; Expression* gen_in = e->in(gen + 1); if (gen_in->type().isvar() || gen_in->type().cv()) { - gen_in = eval.flattenCV(env, e->in(gen + 1))(); + gen_in = eval.flatten(env, e->in(gen + 1)); } if (gen_in->type().dim() == 0) { GCLock lock; @@ -156,12 +154,8 @@ void eval_comp_array(EnvI& env, Eval& eval, Comprehension* e, int gen, int id, I CallStackItem csi(env, e->decl(gen, id)->id(), i); if (in() == nullptr) { // this is an assignment generator - Expression* asn; - if (e->where(gen)->type().isvar() || e->where(gen)->type().cv()) { - asn = eval.flattenCV(env, e->where(gen))(); - } else { - asn = eval_par(env, e->where(gen)); - } + Expression* asn = e->where(gen)->type().isPar() ? eval_par(env, e->where(gen)) + : eval.flatten(env, e->where(gen)); e->decl(gen, id)->e(asn); e->rehash(); } else { @@ -184,7 +178,7 @@ void eval_comp_array(EnvI& env, Eval& eval, Comprehension* e, int gen, int id, I KeepAlive nextin; Expression* gen_in = e->in(gen + 1); if (gen_in->type().isvar() || gen_in->type().cv()) { - gen_in = eval.flattenCV(env, e->in(gen + 1))(); + gen_in = eval.flatten(env, e->in(gen + 1)); } if (gen_in->type().dim() == 0) { GCLock lock; @@ -269,8 +263,8 @@ std::vector eval_comp(EnvI& env, Eval& eval, Comprehens in = new SetLit(Location(), eval_intset(env, e->in(0))); } } else { - if (e->in(0)->type().isvar() || e->in(0)->type().cv()) { - in = eval_array_lit(env, eval.flattenCV(env, e->in(0))()); + if (e->in(0)->type().isvar()) { + in = eval_array_lit(env, eval.flatten(env, e->in(0))); } else { in = eval_array_lit(env, e->in(0)); } diff --git a/include/minizinc/flatten_internal.hh b/include/minizinc/flatten_internal.hh index 9b804ce..a7c24ee 100644 --- a/include/minizinc/flatten_internal.hh +++ b/include/minizinc/flatten_internal.hh @@ -109,7 +109,6 @@ public: std::vector modifiedVarDecls; std::unordered_set deprecationWarnings; int inRedundantConstraint; - int inSymmetryBreakingConstraint; int inMaybePartial; struct { int reifConstraints; diff --git a/include/minizinc/output.hh b/include/minizinc/output.hh index bfc1541..0ca0ab5 100644 --- a/include/minizinc/output.hh +++ b/include/minizinc/output.hh @@ -36,7 +36,7 @@ void finalise_output(EnvI& e); /// Remove all links to variables in flat model from output model in \a env void cleanup_output(EnvI& env); -ArrayLit* create_json_output(EnvI& env, bool outputObjective, bool includeOutputItem, - bool hasChecker); +ArrayLit* create__json_output(EnvI& env, bool outputObjective, bool includeOutputItem, + bool hasChecker); } // namespace MiniZinc diff --git a/include/minizinc/param_config.hh b/include/minizinc/param_config.hh index 1862654..88cb65b 100644 --- a/include/minizinc/param_config.hh +++ b/include/minizinc/param_config.hh @@ -9,7 +9,8 @@ * 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 once +#ifndef __MINIZINC_PARAM_CONFIG_HH__ +#define __MINIZINC_PARAM_CONFIG_HH__ #include #include @@ -56,3 +57,5 @@ public: const char* what() const throw() override { return "MiniZinc: solver parameter error"; } }; } // namespace MiniZinc + +#endif diff --git a/include/minizinc/parser.hh b/include/minizinc/parser.hh index 9ae078d..6e02614 100644 --- a/include/minizinc/parser.hh +++ b/include/minizinc/parser.hh @@ -75,9 +75,9 @@ struct ParseWorkItem { class ParserState { public: ParserState(const std::string& f, const std::string& b, std::ostream& err0, - const std::vector& includePaths0, std::vector& files0, - std::map& seenModels0, MiniZinc::Model* model0, bool isDatafile0, - bool isFlatZinc0, bool isSTDLib0, bool parseDocComments0) + std::vector& files0, std::map& seenModels0, + MiniZinc::Model* model0, bool isDatafile0, bool isFlatZinc0, bool isSTDLib0, + bool parseDocComments0) : filename(f.c_str()), buf(b.c_str()), pos(0), @@ -85,7 +85,6 @@ public: lineStartPos(0), nTokenNextStart(1), hadNewline(false), - includePaths(includePaths0), files(files0), seenModels(seenModels0), model(model0), @@ -106,7 +105,6 @@ public: int nTokenNextStart; bool hadNewline; - const std::vector& includePaths; std::vector& files; std::map& seenModels; MiniZinc::Model* model; @@ -150,8 +148,6 @@ public: pos += num; return num; } - - std::string canonicalFilename(const std::string& f) const; }; Model* parse(Env& env, const std::vector& filename, diff --git a/include/minizinc/process.hh b/include/minizinc/process.hh index aa58f4a..d3bcc62 100644 --- a/include/minizinc/process.hh +++ b/include/minizinc/process.hh @@ -13,6 +13,7 @@ #include +const auto SolverInstance__ERROR = MiniZinc::SolverInstance::ERROR; // before windows.h #ifdef _WIN32 #define NOMINMAX #include diff --git a/include/minizinc/solns2out.hh b/include/minizinc/solns2out.hh index e3d621d..6f23917 100644 --- a/include/minizinc/solns2out.hh +++ b/include/minizinc/solns2out.hh @@ -76,7 +76,7 @@ public: const char* const searchCompleteMsgDef = "=========="; /// Output values std::string solutionSeparator = solutionSeparatorDef; - std::string solutionComma; + std::string solutionComma = ""; std::string unsatisfiableMsg = unsatisfiableMsgDef; std::string unboundedMsg = unboundedMsgDef; std::string unsatorunbndMsg = unsatorunbndMsgDef; diff --git a/include/minizinc/solver_instance.hh b/include/minizinc/solver_instance.hh index 64ef749..10b69d4 100644 --- a/include/minizinc/solver_instance.hh +++ b/include/minizinc/solver_instance.hh @@ -33,6 +33,6 @@ public: enum StatusReason { SR_OK = -5, SR_TIME, SR_MEMORY, SR_LIMIT, SR_ERROR }; }; -const SolverInstance::Status SolverInstanceError = SolverInstance::ERROR; // just in case... +const SolverInstance::Status SolverInstance__ERROR = SolverInstance::ERROR; // just in case... } // namespace MiniZinc diff --git a/include/minizinc/solvers/MIP/MIP_scip_wrap.hh b/include/minizinc/solvers/MIP/MIP_scip_wrap.hh index 8d72488..0440a4a 100644 --- a/include/minizinc/solvers/MIP/MIP_scip_wrap.hh +++ b/include/minizinc/solvers/MIP/MIP_scip_wrap.hh @@ -21,7 +21,6 @@ #include #ifndef _WIN32 -// NOLINTNEXTLINE(bugprone-reserved-identifier) #define __stdcall #endif @@ -106,25 +105,6 @@ public: SCIP_RETCODE(__stdcall* SCIPcreateConsBasicCumulative) (SCIP* scip, SCIP_CONS** cons, const char* name, int nvars, SCIP_VAR** vars, int* durations, int* demands, int capacity); - - // NOLINTNEXTLINE(readability-identifier-naming) - SCIP_RETCODE(__stdcall* SCIPcreateConsBasicOrbisack) - (SCIP* scip, SCIP_CONS** cons, const char* name, SCIP_VAR** vars1, SCIP_VAR** vars2, int nrows, - SCIP_Bool ispporbisack, SCIP_Bool isparttype, SCIP_Bool ismodelcons); - - // NOLINTNEXTLINE(readability-identifier-naming) - SCIP_RETCODE(__stdcall* SCIPcreateConsBasicOrbitope) - (SCIP* scip, /**< SCIP data structure */ - SCIP_CONS** cons, /**< pointer to hold the created constraint */ - const char* name, /**< name of constraint */ - SCIP_VAR*** vars, /**< matrix of variables on which the symmetry acts */ - SCIP_ORBITOPETYPE orbitopetype, /**< type of orbitope constraint */ - int nspcons, /**< number of set partitioning/packing constraints <=> p */ - int nblocks, /**< number of symmetric variable blocks <=> q */ - SCIP_Bool resolveprop, /**< should propagation be resolved? */ - SCIP_Bool ismodelcons /**< whether the orbitope is a model constraint */ - ); - // NOLINTNEXTLINE(readability-identifier-naming) SCIP_Longint(__stdcall* SCIPgetNSolsFound)(SCIP* scip); // NOLINTNEXTLINE(readability-identifier-naming) @@ -379,13 +359,6 @@ public: void addCumulative(int nnz, int* rmatind, double* d, double* r, double b, const std::string& rowName = "") override; - /// Lex-lesseq binary, currently SCIP only - void addLexLesseq(int nnz, int* rmatind1, int* rmatind2, bool isModelCons, - const std::string& rowName = "") override; - - void addLexChainLesseq(int m, int n, int* rmatind, int nOrbitopeType, bool resolveprop, - bool isModelCons, const std::string& rowName = "") override; - /// Times constraint: var[x]*var[y] == var[z] void addTimes(int x, int y, int z, const std::string& rowName = "") override; diff --git a/include/minizinc/solvers/MIP/MIP_solverinstance.hpp b/include/minizinc/solvers/MIP/MIP_solverinstance.hpp index 2614cbd..d65dce8 100644 --- a/include/minizinc/solvers/MIP/MIP_solverinstance.hpp +++ b/include/minizinc/solvers/MIP/MIP_solverinstance.hpp @@ -544,7 +544,7 @@ void MIPSolverinstance::printStatistics() { }; env.outstream.setf(std::ios::fixed); env.outstream.precision(4); - env.outstream << "%%%mzn-stat: solveTime=" << _mipWrapper->getCPUTime() << std::endl; + env.outstream << "%%%mzn-stat: solveTime=" << _mipWrapper->getWallTimeElapsed() << std::endl; ; env.outstream.copyfmt(oldState); @@ -979,6 +979,8 @@ template void p_cumulative(SolverInstanceBase& si, const Call* call) { auto& gi = dynamic_cast&>(si); + std::unique_ptr pCG(new SECCutGen(gi.getMIPWrapper())); + assert(call->argCount() == 4); std::vector startTimes; @@ -994,42 +996,6 @@ void p_cumulative(SolverInstanceBase& si, const Call* call) { make_constraint_name("p_cumulative_", (gi.getMIPWrapper()->nAddedRows++), call)); } -template -void p_lex_lesseq_binary(SolverInstanceBase& si, const Call* call) { - auto& gi = dynamic_cast&>(si); - - assert(call->argCount() == 3); - - std::vector vec1; - std::vector vec2; - gi.exprToVarArray(call->arg(0), vec1); - gi.exprToVarArray(call->arg(1), vec2); - auto isModelCons = gi.exprToConst(call->arg(2)); - MZN_ASSERT_HARD(vec1.size() == vec2.size()); - - gi.getMIPWrapper()->addLexLesseq( - vec1.size(), vec1.data(), vec2.data(), (bool)isModelCons, - make_constraint_name("p_lex_lesseq__orbisack_", (gi.getMIPWrapper()->nAddedRows++), call)); -} - -template -void p_lex_chain_lesseq_binary(SolverInstanceBase& si, const Call* call) { - auto& gi = dynamic_cast&>(si); - - assert(call->argCount() == 5); - - std::vector vars; - gi.exprToVarArray(call->arg(0), vars); - auto m = gi.exprToConst(call->arg(1)); - auto orbitopeType = gi.exprToConst(call->arg(2)); - auto resolveprop = gi.exprToConst(call->arg(3)); - auto isModelCons = gi.exprToConst(call->arg(4)); - - gi.getMIPWrapper()->addLexChainLesseq( - m, vars.size() / m, vars.data(), orbitopeType, (bool)resolveprop, (bool)isModelCons, - make_constraint_name("p_lex_lesseq__orbisack_", (gi.getMIPWrapper()->nAddedRows++), call)); -} - /// The XBZ cut generator template void p_xbz_cutgen(SolverInstanceBase& si, const Call* call) { @@ -1153,12 +1119,6 @@ void MIPSolverinstance::registerConstraints() { _constraintRegistry.add("fzn_cumulative_fixed_d_r", SCIPConstraints::p_cumulative); - _constraintRegistry.add("fzn_lex_lesseq__orbisack", - SCIPConstraints::p_lex_lesseq_binary); - - _constraintRegistry.add("fzn_lex_chain_lesseq__orbitope", - SCIPConstraints::p_lex_chain_lesseq_binary); - _constraintRegistry.add("bounds_disj", SCIPConstraints::p_bounds_disj); _constraintRegistry.add("fzn_array_float_minimum", SCIPConstraints::p_array_minimum); diff --git a/include/minizinc/solvers/MIP/MIP_wrap.hh b/include/minizinc/solvers/MIP/MIP_wrap.hh index 72e0622..8eae5cb 100644 --- a/include/minizinc/solvers/MIP/MIP_wrap.hh +++ b/include/minizinc/solvers/MIP/MIP_wrap.hh @@ -54,7 +54,7 @@ public: /// Lazy cut. Can cut off otherwise feasible integer solutions. /// Callback should be able to produce previously generated cuts again if needed [Gurobi] static const int MaskConsType_Lazy = 4; - enum Status { OPT, SAT, UNSAT, UNBND, UNSATorUNBND, UNKNOWN, ERROR_STATUS }; + enum Status { OPT, SAT, UNSAT, UNBND, UNSATorUNBND, UNKNOWN, __ERROR }; /// Search strategy for the solver enum SearchType { FIXED_SEARCH = 0, FREE_SEARCH = 1, UNIFORM_SEARCH = 2 }; @@ -102,7 +102,7 @@ public: LinConType sense = LQ; double rhs = 0.0; int mask = 0; // need to know what type of cuts are registered before solve() TODO - std::string rowName; + std::string rowName = ""; void addVar(int i, double c) { rmatind.push_back(i); rmatval.push_back(c); @@ -282,19 +282,6 @@ public: const std::string& rowName = "") { throw std::runtime_error("Cumulative constraints not supported. "); } - - /// Lex-lesseq binary, currently SCIP only - virtual void addLexLesseq(int nnz, int* rmatind1, int* rmatind2, bool isModelCons, - const std::string& rowName = "") { - throw std::runtime_error("MIP: lex_lesseq built-in not supported. "); - } - - /// Lex-chain-lesseq binary, currently SCIP only - virtual void addLexChainLesseq(int m, int n, int* rmatind, int nOrbitopeType, bool resolveprop, - bool isModelCons, const std::string& rowName = "") { - throw std::runtime_error("MIP: lex_chain_lesseq built-in not supported. "); - } - /// 0: model-defined level, 1: free, 2: uniform search virtual int getFreeSearch() { return SearchType::FREE_SEARCH; } /// Return 0 if ignoring searches diff --git a/include/minizinc/solvers/MIP/MIP_xpress_wrap.hh b/include/minizinc/solvers/MIP/MIP_xpress_wrap.hh index a331a6e..25ed629 100644 --- a/include/minizinc/solvers/MIP/MIP_xpress_wrap.hh +++ b/include/minizinc/solvers/MIP/MIP_xpress_wrap.hh @@ -38,15 +38,15 @@ public: // NOLINTNEXTLINE(readability-identifier-naming) int(XPRS_CC* XPRSsetlogfile)(XPRSprob prob, const char* logname); // NOLINTNEXTLINE(readability-identifier-naming) - int(XPRS_CC* XPRSsetintcontrol)(XPRSprob prob, int index, int ivalue); + int(XPRS_CC* XPRSsetintcontrol)(XPRSprob prob, int _index, int _ivalue); // NOLINTNEXTLINE(readability-identifier-naming) - int(XPRS_CC* XPRSsetdblcontrol)(XPRSprob prob, int index, double dvalue); + int(XPRS_CC* XPRSsetdblcontrol)(XPRSprob prob, int _index, double _dvalue); // NOLINTNEXTLINE(readability-identifier-naming) double(XB_CC* XPRBgetsol)(struct Xbvar* var); // NOLINTNEXTLINE(readability-identifier-naming) - int(XPRS_CC* XPRSgetintattrib)(XPRSprob prob, int index, int* ivalue); + int(XPRS_CC* XPRSgetintattrib)(XPRSprob prob, int _index, int* _ivalue); // NOLINTNEXTLINE(readability-identifier-naming) - int(XPRS_CC* XPRSgetdblattrib)(XPRSprob prob, int index, double* dvalue); + int(XPRS_CC* XPRSgetdblattrib)(XPRSprob prob, int _index, double* _dvalue); // NOLINTNEXTLINE(readability-identifier-naming) int(XB_CC* XPRBbegincb)(struct Xbprob* prob, struct xo_prob_struct* optprob); // NOLINTNEXTLINE(readability-identifier-naming) @@ -95,20 +95,20 @@ public: int(XPRS_CC* XPRSgetcontrolinfo)(XPRSprob prob, const char* sCaName, int* iHeaderId, int* iTypeinfo); // NOLINTNEXTLINE(readability-identifier-naming) - int(XPRS_CC* XPRSgetintcontrol)(XPRSprob prob, int index, int* ivalue); + int(XPRS_CC* XPRSgetintcontrol)(XPRSprob prob, int _index, int* _ivalue); // NOLINTNEXTLINE(readability-identifier-naming) - int(XPRS_CC* XPRSgetintcontrol64)(XPRSprob prob, int index, XPRSint64* ivalue); + int(XPRS_CC* XPRSgetintcontrol64)(XPRSprob prob, int _index, XPRSint64* _ivalue); // NOLINTNEXTLINE(readability-identifier-naming) - int(XPRS_CC* XPRSgetdblcontrol)(XPRSprob prob, int index, double* dvalue); + int(XPRS_CC* XPRSgetdblcontrol)(XPRSprob prob, int _index, double* _dvalue); // NOLINTNEXTLINE(readability-identifier-naming) - int(XPRS_CC* XPRSgetstrcontrol)(XPRSprob prob, int index, char* svalue); + int(XPRS_CC* XPRSgetstrcontrol)(XPRSprob prob, int _index, char* _svalue); // NOLINTNEXTLINE(readability-identifier-naming) - int(XPRS_CC* XPRSsetintcontrol64)(XPRSprob prob, int index, XPRSint64 ivalue); + int(XPRS_CC* XPRSsetintcontrol64)(XPRSprob prob, int _index, XPRSint64 _ivalue); // NOLINTNEXTLINE(readability-identifier-naming) - int(XPRS_CC* XPRSgetstringcontrol)(XPRSprob prob, int index, char* svalue, int svaluesize, - int* controlsize); + int(XPRS_CC* XPRSgetstringcontrol)(XPRSprob prob, int _index, char* _svalue, int _svaluesize, + int* _controlsize); // NOLINTNEXTLINE(readability-identifier-naming) - int(XPRS_CC* XPRSsetstrcontrol)(XPRSprob prob, int index, const char* svalue); + int(XPRS_CC* XPRSsetstrcontrol)(XPRSprob prob, int _index, const char* _svalue); private: void loadDll(); @@ -130,8 +130,8 @@ public: int msgLevel = 0; int timeout = 0; int numSolutions = 0; - std::string logFile; - std::string writeModelFile; + std::string logFile = ""; + std::string writeModelFile = ""; std::string writeModelFormat = "lp"; double absGap = 0; double relGap = 0.0001; diff --git a/include/minizinc/utils.hh b/include/minizinc/utils.hh index c32940e..684f798 100644 --- a/include/minizinc/utils.hh +++ b/include/minizinc/utils.hh @@ -41,27 +41,27 @@ inline long long int round_to_longlong(double v) { namespace MiniZinc { -// #define MZN_PRINTATONCE_ -#ifdef MZN_PRINTATONCE_ -#define MZN_PRINT_SRCLOC(e1, e2) \ +// #define __MZN_PRINTATONCE__ +#ifdef __MZN_PRINTATONCE__ +#define __MZN_PRINT_SRCLOC(e1, e2) \ std::cerr << '\n' \ << __FILE__ << ": " << __LINE__ << " (" << __func__ << "): not " << e1 << ": " \ << std::flush; \ std::cerr << e2 << std::endl #else -#define MZN_PRINT_SRCLOC(e1, e2) +#define __MZN_PRINT_SRCLOC(e1, e2) #endif -#define MZN_ASSERT_HARD(c) \ - do { \ - if (!(c)) { \ - MZN_PRINT_SRCLOC(#c, ""); \ - throw InternalError(#c); \ - } \ +#define MZN_ASSERT_HARD(c) \ + do { \ + if (!(c)) { \ + __MZN_PRINT_SRCLOC(#c, ""); \ + throw InternalError(#c); \ + } \ } while (0) #define MZN_ASSERT_HARD_MSG(c, e) \ do { \ if (!(c)) { \ - MZN_PRINT_SRCLOC(#c, e); \ + __MZN_PRINT_SRCLOC(#c, e); \ std::ostringstream oss; \ oss << "not " << #c << ": " << e; /* NOLINT(bugprone-macro-parentheses) */ \ throw MiniZinc::InternalError(oss.str()); \ diff --git a/lib/MIPdomains.cpp b/lib/MIPdomains.cpp index 6be767d..f127ca4 100644 --- a/lib/MIPdomains.cpp +++ b/lib/MIPdomains.cpp @@ -42,20 +42,20 @@ /// TODO use integer division instead of INT_EPS #define INT_EPS 1e-5 // the absolute epsilon for integrality of integer vars. -#define MZN_MIPDOMAINS_PRINTMORESTATS +#define __MZN__MIPDOMAINS__PRINTMORESTATS #define MZN_DBG_CHECK_ITER_CUTOUT -// #define MZN_DBGOUT_MIPDOMAINS -#ifdef MZN_DBGOUT_MIPDOMAINS +// #define __MZN__DBGOUT__MIPDOMAINS__ +#ifdef __MZN__DBGOUT__MIPDOMAINS__ #define DBGOUT_MIPD(s) std::cerr << s << std::endl -#define DBGOUT_MIPD_FLUSH(s) std::cerr << s << std::flush +#define DBGOUT_MIPD__(s) std::cerr << s << std::flush #define DBGOUT_MIPD_SELF(op) op #else #define DBGOUT_MIPD(s) \ do { \ } while (false) -#define DBGOUT_MIPD_FLUSH(s) \ - do { \ +#define DBGOUT_MIPD__(s) \ + do { \ } while (false) #define DBGOUT_MIPD_SELF(op) \ do { \ @@ -64,45 +64,45 @@ namespace MiniZinc { -enum EnumStatIdx_MIPD { - N_POSTs_all, // N all POSTs in the model - N_POSTs_intCmpReif, - N_POSTs_floatCmpReif, // in detail - N_POSTs_intNE, - N_POSTs_floatNE, - N_POSTs_setIn, - N_POSTs_domain, - N_POSTs_setInReif, - N_POSTs_eq_encode, - N_POSTs_intAux, - N_POSTs_floatAux, +enum EnumStatIdx__MIPD { + N_POSTs__all, // N all POSTs in the model + N_POSTs__intCmpReif, + N_POSTs__floatCmpReif, // in detail + N_POSTs__intNE, + N_POSTs__floatNE, + N_POSTs__setIn, + N_POSTs__domain, + N_POSTs__setInReif, + N_POSTs__eq_encode, + N_POSTs__intAux, + N_POSTs__floatAux, // Kind of equality connections between involved variables - N_POSTs_eq2intlineq, - N_POSTs_eq2floatlineq, - N_POSTs_int2float, - N_POSTs_internalvarredef, - N_POSTs_initexpr1id, - N_POSTs_initexpr1linexp, - N_POSTs_initexprN, - N_POSTs_eqNlineq, - N_POSTs_eqNmapsize, + N_POSTs__eq2intlineq, + N_POSTs__eq2floatlineq, + N_POSTs__int2float, + N_POSTs__internalvarredef, + N_POSTs__initexpr1id, + N_POSTs__initexpr1linexp, + N_POSTs__initexprN, + N_POSTs__eqNlineq, + N_POSTs__eqNmapsize, // other - N_POSTs_varsDirect, - N_POSTs_varsInvolved, - N_POSTs_NSubintvMin, - N_POSTs_NSubintvSum, - N_POSTs_NSubintvMax, // as N subintervals - N_POSTs_SubSizeMin, - N_POSTs_SubSizeSum, - N_POSTs_SubSizeMax, // subintv. size - N_POSTs_linCoefMin, - N_POSTs_linCoefMax, - N_POSTs_cliquesWithEqEncode, - N_POSTs_clEEEnforced, - N_POSTs_clEEFound, - N_POSTs_size + N_POSTs__varsDirect, + N_POSTs__varsInvolved, + N_POSTs__NSubintvMin, + N_POSTs__NSubintvSum, + N_POSTs__NSubintvMax, // as N subintervals + N_POSTs__SubSizeMin, + N_POSTs__SubSizeSum, + N_POSTs__SubSizeMax, // subintv. size + N_POSTs__linCoefMin, + N_POSTs__linCoefMax, + N_POSTs__cliquesWithEqEncode, + N_POSTs__clEEEnforced, + N_POSTs__clEEFound, + N_POSTs__size }; -extern std::vector MIPD_stats; +extern std::vector MIPD__stats; enum EnumReifType { RIT_None, RIT_Static, RIT_Reif, RIT_Halfreif }; enum EnumConstrType { CT_None, CT_Comparison, CT_SetIn, CT_Encode }; @@ -134,14 +134,14 @@ struct DCT { FunctionI*& pfi; // double dEps = -1.0; DCT(const char* fn, const std::vector& prm, EnumReifType er, EnumConstrType ec, - EnumCmpType ecmp, EnumVarType ev, FunctionI*& pfi_) + EnumCmpType ecmp, EnumVarType ev, FunctionI*& pfi__) : sFuncName(fn), aParams(prm), nReifType(er), nConstrType(ec), nCmpType(ecmp), nVarType(ev), - pfi(pfi_) {} + pfi(pfi__) {} }; template @@ -266,7 +266,7 @@ typedef LinEqHelper, std::vector > LinEq; // double rhs; // }; -std::vector MIPD_stats(N_POSTs_size); +std::vector MIPD__stats(N_POSTs__size); template static std::vector make_vec(T t1, T t2) { @@ -299,8 +299,8 @@ public: const double dMaxNValueDensity = 3.0; // Maximal ratio cardInt() / size() of a domain // to enforce ee bool doMIPdomains() { - MIPD_stats[N_POSTs_NSubintvMin] = 1e100; - MIPD_stats[N_POSTs_SubSizeMin] = 1e100; + MIPD__stats[N_POSTs__NSubintvMin] = 1e100; + MIPD__stats[N_POSTs__SubSizeMin] = 1e100; if (!registerLinearConstraintDecls()) { return true; @@ -325,7 +325,7 @@ public: private: Env* _env = nullptr; Env* getEnv() { - MZN_MIPD_assert_hard(_env); + MZN_MIPD__assert_hard(_env); return _env; } @@ -354,7 +354,7 @@ private: // NOLINTNEXTLINE(readability-identifier-naming) std::vector t_VIVF = make_vec(Type::varint(), Type::varfloat()); - // double float_lt_EPS_coef_ = 1e-5; + // double float_lt_EPS_coef__ = 1e-5; bool registerLinearConstraintDecls() { EnvI& env = getEnv()->envi(); @@ -362,7 +362,7 @@ private: int_lin_eq = env.model->matchFn(env, constants().ids.int_.lin_eq, int_lin_eq_t, false); DBGOUT_MIPD(" int_lin_eq = " << int_lin_eq); - // MZN_MIPD_assert_hard(fi); + // MZN_MIPD__assert_hard(fi); // int_lin_eq = (fi && fi->e()) ? fi : NULL; int_lin_le = env.model->matchFn(env, constants().ids.int_.lin_le, int_lin_eq_t, false); float_lin_eq = env.model->matchFn(env, constants().ids.float_.lin_eq, float_lin_eq_t, false); @@ -385,7 +385,7 @@ private: // new Call(Location(),"mzn_float_lt_EPS_coef__", std::vector()); // call_EPS_for_LT->type(Type::parfloat()); // call_EPS_for_LT->decl(env.model->matchFn(getEnv()->envi(), call_EPS_for_LT)); - // float_lt_EPS_coef_ = eval_float(getEnv()->envi(), call_EPS_for_LT); + // float_lt_EPS_coef__ = eval_float(getEnv()->envi(), call_EPS_for_LT); // } } // bool matchAndMarkFunction(); @@ -431,9 +431,9 @@ private: // std::vector t_intarray(1); // t_intarray[0] = Type::parint(-1); - typedef std::unordered_map M_POSTCallTypes; - M_POSTCallTypes _mCallTypes; // actually declared in the input - std::vector _aCT; // all possible + typedef std::unordered_map M__POSTCallTypes; + M__POSTCallTypes _mCallTypes; // actually declared in the input + std::vector _aCT; // all possible // Fails: // DomainCallType a = { NULL, t_VII, RIT_Halfreif, CT_Comparison, CMPT_EQ, VT_Float }; @@ -458,37 +458,37 @@ private: std::vector _vVarDescr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* int_le_reif_POST = nullptr; + FunctionI* int_le_reif__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* int_ge_reif_POST = nullptr; + FunctionI* int_ge_reif__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* int_eq_reif_POST = nullptr; + FunctionI* int_eq_reif__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* int_ne_POST = nullptr; + FunctionI* int_ne__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* float_le_reif_POST = nullptr; + FunctionI* float_le_reif__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* float_ge_reif_POST = nullptr; + FunctionI* float_ge_reif__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* aux_float_lt_zero_iff_1_POST = nullptr; + FunctionI* aux_float_lt_zero_iff_1__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* float_eq_reif_POST = nullptr; + FunctionI* float_eq_reif__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* float_ne_POST = nullptr; + FunctionI* float_ne__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* aux_float_eq_zero_if_1_POST = nullptr; + FunctionI* aux_float_eq_zero_if_1__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* aux_int_le_zero_if_1_POST = nullptr; + FunctionI* aux_int_le_zero_if_1__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* aux_float_le_zero_if_1_POST = nullptr; + FunctionI* aux_float_le_zero_if_1__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* aux_float_lt_zero_if_1_POST = nullptr; + FunctionI* aux_float_lt_zero_if_1__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* equality_encoding_POST = nullptr; + FunctionI* equality_encoding__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* set_in_POST = nullptr; + FunctionI* set_in__POST = nullptr; // NOLINTNEXTLINE(readability-identifier-naming) - FunctionI* set_in_reif_POST = nullptr; + FunctionI* set_in_reif__POST = nullptr; bool registerPOSTConstraintDecls() { EnvI& env = getEnv()->envi(); @@ -496,40 +496,41 @@ private: _aCT.clear(); _aCT.emplace_back("int_le_reif__POST", t_VIIVI, RIT_Reif, CT_Comparison, CMPT_LE, VT_Int, - int_le_reif_POST); + int_le_reif__POST); _aCT.emplace_back("int_ge_reif__POST", t_VIIVI, RIT_Reif, CT_Comparison, CMPT_GE, VT_Int, - int_ge_reif_POST); + int_ge_reif__POST); _aCT.emplace_back("int_eq_reif__POST", t_VIIVI, RIT_Reif, CT_Comparison, CMPT_EQ, VT_Int, - int_eq_reif_POST); + int_eq_reif__POST); _aCT.emplace_back("int_ne__POST", t_VII, RIT_Static, CT_Comparison, CMPT_NE, VT_Int, - int_ne_POST); + int_ne__POST); _aCT.emplace_back("float_le_reif__POST", t_VFFVIF, RIT_Reif, CT_Comparison, CMPT_LE, VT_Float, - float_le_reif_POST); + float_le_reif__POST); _aCT.emplace_back("float_ge_reif__POST", t_VFFVIF, RIT_Reif, CT_Comparison, CMPT_GE, VT_Float, - float_ge_reif_POST); + float_ge_reif__POST); _aCT.emplace_back("aux_float_lt_zero_iff_1__POST", t_VFVIF, RIT_Reif, CT_Comparison, CMPT_LT, - VT_Float, aux_float_lt_zero_iff_1_POST); + VT_Float, aux_float_lt_zero_iff_1__POST); _aCT.emplace_back("float_eq_reif__POST", t_VFFVIF, RIT_Reif, CT_Comparison, CMPT_EQ, VT_Float, - float_eq_reif_POST); + float_eq_reif__POST); _aCT.emplace_back("float_ne__POST", t_VFFF, RIT_Static, CT_Comparison, CMPT_NE, VT_Float, - float_ne_POST); + float_ne__POST); _aCT.emplace_back("aux_float_eq_zero_if_1__POST", t_VFVIVF, RIT_Halfreif, CT_Comparison, - CMPT_EQ_0, VT_Float, aux_float_eq_zero_if_1_POST); + CMPT_EQ_0, VT_Float, aux_float_eq_zero_if_1__POST); _aCT.emplace_back("aux_int_le_zero_if_1__POST", t_VIVI, RIT_Halfreif, CT_Comparison, CMPT_LE_0, - VT_Int, aux_int_le_zero_if_1_POST); + VT_Int, aux_int_le_zero_if_1__POST); _aCT.emplace_back("aux_float_le_zero_if_1__POST", t_VFVIVF, RIT_Halfreif, CT_Comparison, - CMPT_LE_0, VT_Float, aux_float_le_zero_if_1_POST); + CMPT_LE_0, VT_Float, aux_float_le_zero_if_1__POST); _aCT.emplace_back("aux_float_lt_zero_if_1__POST", t_VFVIVFF, RIT_Halfreif, CT_Comparison, - CMPT_LT_0, VT_Float, aux_float_lt_zero_if_1_POST); + CMPT_LT_0, VT_Float, aux_float_lt_zero_if_1__POST); _aCT.emplace_back("equality_encoding__POST", t_VIAVI, RIT_Static, CT_Encode, CMPT_None, VT_Int, - equality_encoding_POST); - _aCT.emplace_back("set_in__POST", t_VISI, RIT_Static, CT_SetIn, CMPT_None, VT_Int, set_in_POST); + equality_encoding__POST); + _aCT.emplace_back("set_in__POST", t_VISI, RIT_Static, CT_SetIn, CMPT_None, VT_Int, + set_in__POST); _aCT.emplace_back("set_in_reif__POST", t_VISIVI, RIT_Reif, CT_SetIn, CMPT_None, VT_Int, - set_in_reif_POST); - /// Registering all declared & compatible _POST constraints + set_in_reif__POST); + /// Registering all declared & compatible __POST constraints /// (First, cleanup FunctionIs' payload: -- ! doing now) for (int i = 0; i < _aCT.size(); ++i) { FunctionI* fi = env.model->matchFn(env, ASTString(_aCT[i].sFuncName), _aCT[i].aParams, false); @@ -547,7 +548,7 @@ private: return true; } - /// Registering all _POST calls' domain-constrained variables + /// Registering all __POST calls' domain-constrained variables void registerPOSTVariables() { EnvI& env = getEnv()->envi(); GCLock lock; @@ -576,13 +577,13 @@ private: checkInitExpr(vd0); } } else { - DBGOUT_MIPD_FLUSH(" (already touched)"); + DBGOUT_MIPD__(" (already touched)"); } - ++MIPD_stats[N_POSTs_domain]; - ++MIPD_stats[N_POSTs_all]; + ++MIPD__stats[N_POSTs__domain]; + ++MIPD__stats[N_POSTs__all]; } } - // Iterate thru original _POST constraints to mark constrained vars: + // Iterate thru original __POST constraints to mark constrained vars: for (ConstraintIterator ic = mFlat.constraints().begin(); ic != mFlat.constraints().end(); ++ic) { if (ic->removed()) { @@ -593,20 +594,19 @@ private: if (ipct != _mCallTypes.end()) { // No ! here because might be deleted immediately in later versions. // ic->remove(); // mark removed at once - MZN_MIPD_assert_hard(c->argCount() > 1); - ++MIPD_stats[N_POSTs_all]; + MZN_MIPD__assert_hard(c->argCount() > 1); + ++MIPD__stats[N_POSTs__all]; VarDecl* vd0 = expr2VarDecl(c->arg(0)); if (nullptr == vd0) { - DBGOUT_MIPD_FLUSH(" Call " << *c - << ": 1st arg not a VarDecl, removing if eq_encoding..."); + DBGOUT_MIPD__(" Call " << *c << ": 1st arg not a VarDecl, removing if eq_encoding..."); /// Only allow literals as main argument for equality_encoding - if (equality_encoding_POST == - ipct->first) { // was MZN_MIPD_assert_hard before MZN 2017 + if (equality_encoding__POST == + ipct->first) { // was MZN_MIPD__assert_hard before MZN 2017 ic->remove(); } continue; // ignore this call } - DBGOUT_MIPD_FLUSH(" Call " << c->id().str() << " uses variable " << vd0->id()->str()); + DBGOUT_MIPD__(" Call " << c->id().str() << " uses variable " << vd0->id()->str()); if (vd0->payload() == -1) { // ! yet visited vd0->payload(static_cast(_vVarDescr.size())); _vVarDescr.emplace_back(vd0, vd0->type().isint()); // can use /prmTypes/ as well @@ -615,11 +615,11 @@ private: checkInitExpr(vd0); } } else { - DBGOUT_MIPD_FLUSH(" (already touched)"); + DBGOUT_MIPD__(" (already touched)"); } DBGOUT_MIPD(""); - if (equality_encoding_POST == c->decl()) { - MZN_MIPD_assert_hard(!_vVarDescr[vd0->payload()].pEqEncoding); + if (equality_encoding__POST == c->decl()) { + MZN_MIPD__assert_hard(!_vVarDescr[vd0->payload()].pEqEncoding); _vVarDescr[vd0->payload()].pEqEncoding = &*ic; DBGOUT_MIPD(" Variable " << vd0->id()->str() << " has eq_encode."); } // + if has aux_ constraints? @@ -629,7 +629,7 @@ private: } } } - MIPD_stats[N_POSTs_varsDirect] = static_cast(_vVarDescr.size()); + MIPD__stats[N_POSTs__varsDirect] = static_cast(_vVarDescr.size()); } // Should only be called on a newly added variable @@ -639,18 +639,18 @@ private: /// The bool param requires RHS to be POST-touched // Guido: can! be recursive in FZN bool checkInitExpr(VarDecl* vd, bool fCheckArg = false) { - MZN_MIPD_assert_hard(vd->e()); + MZN_MIPD__assert_hard(vd->e()); if (!vd->type().isint() && !vd->type().isfloat()) { return false; } if (!fCheckArg) { - MZN_MIPD_assert_hard(vd->payload() >= 0); + MZN_MIPD__assert_hard(vd->payload() >= 0); } if (Id* id = vd->e()->dynamicCast()) { // const int f1 = ( vd->payload()>=0 ); // const int f2 = ( id->decl()->payload()>=0 ); if (!fCheckArg || (id->decl()->payload() >= 0)) { - DBGOUT_MIPD_FLUSH(" Checking init expr "); + DBGOUT_MIPD__(" Checking init expr "); DBGOUT_MIPD_SELF(debugprint(vd)); LinEq2Vars led; // FAILS: @@ -659,7 +659,7 @@ private: led.coefs = {{1.0, -1.0}}; led.rhs = 0.0; put2VarsConnection(led, false); - ++MIPD_stats[N_POSTs_initexpr1id]; + ++MIPD__stats[N_POSTs__initexpr1id]; if (id->decl()->e() != nullptr) { // no initexpr for initexpr FAILS on cc-base.mzn checkInitExpr(id->decl()); } @@ -669,11 +669,11 @@ private: if (lin_exp_int == c->decl() || lin_exp_float == c->decl()) { // std::cerr << " !E call " << std::flush; // debugprint(c); - MZN_MIPD_assert_hard(c->argCount() == 3); + MZN_MIPD__assert_hard(c->argCount() == 3); // ArrayLit* al = c->args()[1]->dynamicCast(); auto* al = follow_id(c->arg(1))->cast(); - MZN_MIPD_assert_hard(al); - MZN_MIPD_assert_hard(al->size() >= 1); + MZN_MIPD__assert_hard(al); + MZN_MIPD__assert_hard(al->size() >= 1); if (al->size() == 1) { // 1-term scalar product in the rhs LinEq2Vars led; led.vd = {{vd, expr2VarDecl((*al)[0])}}; @@ -684,14 +684,14 @@ private: // if ( _sCallLinEq2.end() != _sCallLinEq2.find(c) ) // continue; // _sCallLinEq2.insert(c); // memorize this call - DBGOUT_MIPD_FLUSH(" REG 1-LINEXP "); + DBGOUT_MIPD__(" REG 1-LINEXP "); DBGOUT_MIPD_SELF(debugprint(vd)); std::array coef0; expr2Array(c->arg(0), coef0); led.coefs = {{-1.0, coef0[0]}}; led.rhs = -expr2Const(c->arg(2)); // MINUS put2VarsConnection(led, false); - ++MIPD_stats[N_POSTs_initexpr1linexp]; + ++MIPD__stats[N_POSTs__initexpr1linexp]; if (led.vd[1]->e() != nullptr) { // no initexpr for initexpr FAILS TODO checkInitExpr(led.vd[1]); } @@ -726,7 +726,7 @@ private: propagateImplViews(fChanges); } while (fChanges); - MIPD_stats[N_POSTs_varsInvolved] = static_cast(_vVarDescr.size()); + MIPD__stats[N_POSTs__varsInvolved] = static_cast(_vVarDescr.size()); } void propagateViews(bool& fChanges) { @@ -764,9 +764,9 @@ private: if (fIntLinEq || fFloatLinEq) { // std::cerr << " !E call " << std::flush; // debugprint(c); - MZN_MIPD_assert_hard(c->argCount() == 3); + MZN_MIPD__assert_hard(c->argCount() == 3); auto* al = follow_id(c->arg(1))->cast(); - MZN_MIPD_assert_hard(al); + MZN_MIPD__assert_hard(al); if (al->size() == 2) { // 2-term eqn LinEq2Vars led; expr2DeclArray(c->arg(1), led.vd); @@ -781,10 +781,10 @@ private: DBGOUT_MIPD_SELF(debugprint(c)); led.rhs = expr2Const(c->arg(2)); expr2Array(c->arg(0), led.coefs); - MZN_MIPD_assert_hard(2 == led.coefs.size()); + MZN_MIPD__assert_hard(2 == led.coefs.size()); fChanges = true; put2VarsConnection(led); - ++MIPD_stats[fIntLinEq ? N_POSTs_eq2intlineq : N_POSTs_eq2floatlineq]; + ++MIPD__stats[fIntLinEq ? N_POSTs__eq2intlineq : N_POSTs__eq2floatlineq]; } } } else if (al->size() == 1) { @@ -804,8 +804,8 @@ private: DBGOUT_MIPD(" REG N-call "); DBGOUT_MIPD_SELF(debugprint(c)); Call* pC = eVD->dynamicCast(); - MZN_MIPD_assert_hard(pC); - MZN_MIPD_assert_hard(pC->argCount()); + MZN_MIPD__assert_hard(pC); + MZN_MIPD__assert_hard(pC->argCount()); // Checking all but adding only touched defined vars? Seems too long. VarDecl* vd = expr2VarDecl(pC->arg(0)); if ((vd != nullptr) && vd->payload() >= 0) { // only if touched @@ -822,7 +822,7 @@ private: if (int2float == c->decl() || constants().varRedef == c->decl()) { // std::cerr << " !E call " << std::flush; // debugprint(c); - MZN_MIPD_assert_hard(c->argCount() == 2); + MZN_MIPD__assert_hard(c->argCount() == 2); LinEq2Vars led; // led.vd.resize(2); led.vd[0] = expr2VarDecl(c->arg(0)); @@ -839,7 +839,7 @@ private: led.coefs = {{1.0, -1.0}}; fChanges = true; put2VarsConnection(led); - ++MIPD_stats[int2float == c->decl() ? N_POSTs_int2float : N_POSTs_internalvarredef]; + ++MIPD__stats[int2float == c->decl() ? N_POSTs__int2float : N_POSTs__internalvarredef]; } } } @@ -865,10 +865,10 @@ private: // _lin_eq: a^T x == b bool findOrAddDefining(Expression* exp, Call* pC) { Id* pId = exp->dynamicCast(); - MZN_MIPD_assert_hard(pId); + MZN_MIPD__assert_hard(pId); VarDecl* vd = pId->decl(); - MZN_MIPD_assert_hard(vd); - MZN_MIPD_assert_hard(pC->argCount() == 3); + MZN_MIPD__assert_hard(vd); + MZN_MIPD__assert_hard(pC->argCount() == 3); TLinExpLin rhsLin; NViewData nVRest; @@ -879,11 +879,11 @@ private: expr2DeclArray(pC->arg(1), vars); std::vector coefs; expr2Array(pC->arg(0), coefs); - MZN_MIPD_assert_hard(vars.size() == coefs.size()); + MZN_MIPD__assert_hard(vars.size() == coefs.size()); int nVD = 0; for (int i = 0; i < vars.size(); ++i) { - // MZN_MIPD_assert_hard( 0.0!=std::fabs + // MZN_MIPD__assert_hard( 0.0!=std::fabs if (vd == vars[i]) { // when int/float_lin_eq :: defines_var(vd) "Recursive definition of " << *vd nVRest.coef0 = -coefs[i]; @@ -893,12 +893,12 @@ private: rhsLin.push_back(std::make_pair(vars[i], coefs[i])); } } - MZN_MIPD_assert_hard(1 >= nVD); + MZN_MIPD__assert_hard(1 >= nVD); std::sort(rhsLin.begin(), rhsLin.end()); // Divide the equation by the 1st coef const double coef1 = rhsLin.begin()->second; - MZN_MIPD_assert_hard(0.0 != std::fabs(coef1)); + MZN_MIPD__assert_hard(0.0 != std::fabs(coef1)); nVRest.coef0 /= coef1; nVRest.rhs /= coef1; for (auto& rhsL : rhsLin) { @@ -913,7 +913,7 @@ private: leq.coefs = {{nVRest.coef0, -it->second.coef0}}; // +, - leq.rhs = nVRest.rhs - it->second.rhs; put2VarsConnection(leq, false); - ++MIPD_stats[nVD != 0 ? N_POSTs_eqNlineq : N_POSTs_initexprN]; + ++MIPD__stats[nVD != 0 ? N_POSTs__eqNlineq : N_POSTs__initexprN]; return true; } if (vd->payload() >= 0) { // only touched @@ -948,16 +948,16 @@ private: /// register a 2-variable lin eq /// add it to the var clique, joining the participants' cliques if needed void put2VarsConnection(LinEq2Vars& led, bool fCheckinitExpr = true) { - MZN_MIPD_assert_hard(led.coefs.size() == led.vd.size()); - MZN_MIPD_assert_hard(led.vd.size() == 2); - DBGOUT_MIPD_FLUSH(" Register 2-var connection: " << led); + MZN_MIPD__assert_hard(led.coefs.size() == led.vd.size()); + MZN_MIPD__assert_hard(led.vd.size() == 2); + DBGOUT_MIPD__(" Register 2-var connection: " << led); /// Check it's not same 2 vars if (led.vd[0] == led.vd[1]) { - MZN_MIPD_assert_soft( + MZN_MIPD__assert_soft( 0, "MIPD: STRANGE: registering var connection to itself: " << led << ", skipping"); - MZN_MIPD_ASSERT_FOR_SAT(fabs(led.coefs[0] + led.coefs[1]) < 1e-6, // TODO param - getEnv()->envi(), led.vd[0]->loc(), - "Var connection to itself seems to indicate UNSAT: " << led); + MZN_MIPD__ASSERT_FOR_SAT(fabs(led.coefs[0] + led.coefs[1]) < 1e-6, // TODO param + getEnv()->envi(), led.vd[0]->loc(), + "Var connection to itself seems to indicate UNSAT: " << led); return; } // register if new variables @@ -975,7 +975,7 @@ private: if (nMaybeClq >= 0) { nCliqueAvailable = nMaybeClq; } - // MZN_MIPD_assert_hard( nCliqueAvailable>=0 ); + // MZN_MIPD__assert_hard( nCliqueAvailable>=0 ); // fHaveClq[i] = true; } } @@ -991,7 +991,7 @@ private: int& nMaybeClq = _vVarDescr[vd->payload()].nClique; if (nMaybeClq >= 0 && nMaybeClq != nCliqueAvailable) { TClique& clqOld = _aCliques[nMaybeClq]; - MZN_MIPD_assert_hard(clqOld.size()); + MZN_MIPD__assert_hard(clqOld.size()); for (auto& eq2 : clqOld) { for (auto* vd : eq2.vd) { // point all the variables to the new clique _vVarDescr[vd->payload()].nClique = nCliqueAvailable; @@ -1028,20 +1028,21 @@ private: if (this->end() != it1) { auto it2 = it1->second.find(*(begV + 1)); if (it1->second.end() != it2) { - MZN_MIPD_assert_hard(std::fabs(it2->second.first - A) < - 1e-6 * std::max(std::fabs(it2->second.first), std::fabs(A))); - MZN_MIPD_assert_hard(std::fabs(it2->second.second - B) < - 1e-6 * std::max(std::fabs(it2->second.second), std::fabs(B)) + - 1e-6); - MZN_MIPD_assert_hard(std::fabs(A) != 0.0); - MZN_MIPD_assert_soft(!fVerbose || std::fabs(A) > 1e-12, - " Very small coef: " << (*begV)->id()->str() << " = " << A << " * " - << (*(begV + 1))->id()->str() << " + " << B); + MZN_MIPD__assert_hard(std::fabs(it2->second.first - A) < + 1e-6 * std::max(std::fabs(it2->second.first), std::fabs(A))); + MZN_MIPD__assert_hard(std::fabs(it2->second.second - B) < + 1e-6 * std::max(std::fabs(it2->second.second), std::fabs(B)) + + 1e-6); + MZN_MIPD__assert_hard(std::fabs(A) != 0.0); + MZN_MIPD__assert_soft(!fVerbose || std::fabs(A) > 1e-12, + " Very small coef: " << (*begV)->id()->str() << " = " << A + << " * " << (*(begV + 1))->id()->str() + << " + " << B); if (fReportRepeat) { - MZN_MIPD_assert_soft(!fVerbose, "LinEqGraph: eqn between " - << (*begV)->id()->str() << " && " - << (*(begV + 1))->id()->str() - << " is repeated. "); + MZN_MIPD__assert_soft(!fVerbose, "LinEqGraph: eqn between " + << (*begV)->id()->str() << " && " + << (*(begV + 1))->id()->str() + << " is repeated. "); } return true; } @@ -1063,9 +1064,9 @@ private: template void addArc(ICoef begC, IVarDecl begV, double rhs) { - MZN_MIPD_assert_soft(!fVerbose || std::fabs(*begC) >= 1e-10, - " Vars " << (*begV)->id()->str() << " to " - << (*(begV + 1))->id()->str() << ": coef=" << (*begC)); + MZN_MIPD__assert_soft(!fVerbose || std::fabs(*begC) >= 1e-10, + " Vars " << (*begV)->id()->str() << " to " + << (*(begV + 1))->id()->str() << ": coef=" << (*begC)); // Transform Ax+By=C into x = -B/Ay+C/A const double negBA = -(*(begC + 1)) / (*begC); const double CA = rhs / (*begC); @@ -1085,14 +1086,14 @@ private: } /// Propagate linear relations from the given variable void propagate(iterator itStart, TMapVars& mWhereStore) { - MZN_MIPD_assert_hard(this->end() != itStart); + MZN_MIPD__assert_hard(this->end() != itStart); TMatrixVars mTemp; mTemp[itStart->first] = itStart->second; // init with existing DBGOUT_MIPD("Propagation started from " << itStart->first->id()->str() << " having " << itStart->second.size() << " connections"); propagate2(itStart, itStart, std::make_pair(1.0, 0.0), mTemp); mWhereStore = mTemp.begin()->second; - MZN_MIPD_assert_hard_msg( + MZN_MIPD__assert_hard_msg( mWhereStore.size() == this->size() - 1, "Variable " << (*(mTemp.begin()->first)) << " should be connected to all others in the clique, but " @@ -1121,7 +1122,7 @@ private: } if (fDive) { auto itDST = this->find(itDst->first); - MZN_MIPD_assert_hard(this->end() != itDST); + MZN_MIPD__assert_hard(this->end() != itDST); propagate2(itSrc, itDST, std::make_pair(A1A2, A1B2plusB1), mWhereStore); } } @@ -1131,7 +1132,7 @@ private: TCliqueSorter(MIPD* pm, int iv) : _mipd(*pm), _iVarStart(iv) {} void doRelate() { - MZN_MIPD_assert_hard(_mipd._vVarDescr[_iVarStart].nClique >= 0); + MZN_MIPD__assert_hard(_mipd._vVarDescr[_iVarStart].nClique >= 0); const TClique& clq = _mipd._aCliques[_mipd._vVarDescr[_iVarStart].nClique]; for (const auto& eq2 : clq) { leg.addEdge(eq2); @@ -1189,7 +1190,7 @@ private: cls.mRef1[cls.varRef1] = std::make_pair(1.0, 0.0); int iVarRef1 = cls.varRef1->payload(); - MZN_MIPD_assert_hard(nClique == mipd._vVarDescr[iVarRef1].nClique); + MZN_MIPD__assert_hard(nClique == mipd._vVarDescr[iVarRef1].nClique); cls.fRef1HasEqEncode = (mipd._vVarDescr[iVarRef1].pEqEncoding != nullptr); // First, construct the domain decomposition in any case @@ -1202,18 +1203,18 @@ private: DBGOUT_MIPD("Clique " << nClique << ": main ref var " << cls.varRef1->id()->str() << ", domain dec: " << sDomain); - MZN_MIPD_ASSERT_FOR_SAT(!sDomain.empty(), mipd.getEnv()->envi(), cls.varRef1->loc(), - "clique " << nClique << ": main ref var " << *cls.varRef1->id() - << ", domain decomposition seems empty: " << sDomain); + MZN_MIPD__ASSERT_FOR_SAT(!sDomain.empty(), mipd.getEnv()->envi(), cls.varRef1->loc(), + "clique " << nClique << ": main ref var " << *cls.varRef1->id() + << ", domain decomposition seems empty: " << sDomain); - MZN_MIPD_FLATTENING_ERROR_IF_NOT(sDomain.checkFiniteBounds(), mipd.getEnv()->envi(), - cls.varRef1->loc(), - "variable " << *cls.varRef1->id() - << " needs finite bounds for linearisation." - " Or, use indicator constraints. " - << "Current domain is " << sDomain); + MZN_MIPD__FLATTENING_ERROR__IF_NOT(sDomain.checkFiniteBounds(), mipd.getEnv()->envi(), + cls.varRef1->loc(), + "variable " << *cls.varRef1->id() + << " needs finite bounds for linearisation." + " Or, use indicator constraints. " + << "Current domain is " << sDomain); - MZN_MIPD_assert_hard(sDomain.checkDisjunctStrict()); + MZN_MIPD__assert_hard(sDomain.checkDisjunctStrict()); makeRangeDomains(); @@ -1230,25 +1231,25 @@ private: implementPOSTs(); // Statistics - if (sDomain.size() < MIPD_stats[N_POSTs_NSubintvMin]) { - MIPD_stats[N_POSTs_NSubintvMin] = static_cast(sDomain.size()); + if (sDomain.size() < MIPD__stats[N_POSTs__NSubintvMin]) { + MIPD__stats[N_POSTs__NSubintvMin] = static_cast(sDomain.size()); } - MIPD_stats[N_POSTs_NSubintvSum] += sDomain.size(); - if (sDomain.size() > MIPD_stats[N_POSTs_NSubintvMax]) { - MIPD_stats[N_POSTs_NSubintvMax] = static_cast(sDomain.size()); + MIPD__stats[N_POSTs__NSubintvSum] += sDomain.size(); + if (sDomain.size() > MIPD__stats[N_POSTs__NSubintvMax]) { + MIPD__stats[N_POSTs__NSubintvMax] = static_cast(sDomain.size()); } for (const auto& intv : sDomain) { const auto nSubSize = intv.right - intv.left; - if (nSubSize < MIPD_stats[N_POSTs_SubSizeMin]) { - MIPD_stats[N_POSTs_SubSizeMin] = nSubSize; + if (nSubSize < MIPD__stats[N_POSTs__SubSizeMin]) { + MIPD__stats[N_POSTs__SubSizeMin] = nSubSize; } - MIPD_stats[N_POSTs_SubSizeSum] += nSubSize; - if (nSubSize > MIPD_stats[N_POSTs_SubSizeMax]) { - MIPD_stats[N_POSTs_SubSizeMax] = nSubSize; + MIPD__stats[N_POSTs__SubSizeSum] += nSubSize; + if (nSubSize > MIPD__stats[N_POSTs__SubSizeMax]) { + MIPD__stats[N_POSTs__SubSizeMax] = nSubSize; } } if (cls.fRef1HasEqEncode) { - ++MIPD_stats[N_POSTs_cliquesWithEqEncode]; + ++MIPD__stats[N_POSTs__cliquesWithEqEncode]; } } @@ -1256,7 +1257,7 @@ private: /// Deltas should be scaled but to a minimum of the target's discr /// COmparison sense changes on negated vars void projectVariableConstr(VarDecl* vd, std::pair eq1) { - DBGOUT_MIPD_FLUSH(" MIPD: projecting variable "); + DBGOUT_MIPD__(" MIPD: projecting variable "); DBGOUT_MIPD_SELF(debugprint(vd)); // Always check if domain becomes empty? TODO const double A = eq1.first; // vd = A*arg + B. conversion @@ -1276,10 +1277,10 @@ private: lb = bnds.left; ub = bnds.right; } else { - MZN_MIPD_FLATTENING_ERROR_IF_NOT(0, mipd.getEnv()->envi(), cls.varRef1->loc(), - "Variable " << vd->id()->str() << " of type " - << vd->type().toString(mipd._env->envi()) - << " has a domain."); + MZN_MIPD__FLATTENING_ERROR__IF_NOT(0, mipd.getEnv()->envi(), cls.varRef1->loc(), + "Variable " << vd->id()->str() << " of type " + << vd->type().toString(mipd._env->envi()) + << " has a domain."); } // /// Deleting var domain: // vd->ti()->domain( NULL ); @@ -1294,14 +1295,14 @@ private: auto& aCalls = mipd._vVarDescr[vd->payload()].aCalls; for (Item* pItem : aCalls) { auto* pCI = pItem->dynamicCast(); - MZN_MIPD_assert_hard(pCI != nullptr); + MZN_MIPD__assert_hard(pCI != nullptr); Call* pCall = pCI->e()->dynamicCast(); - MZN_MIPD_assert_hard(pCall != nullptr); - DBGOUT_MIPD_FLUSH("PROPAG CALL "); + MZN_MIPD__assert_hard(pCall != nullptr); + DBGOUT_MIPD__("PROPAG CALL "); DBGOUT_MIPD_SELF(debugprint(pCall)); // check the bounds for bool in reifs? TODO auto ipct = mipd._mCallTypes.find(pCall->decl()); - MZN_MIPD_assert_hard(mipd._mCallTypes.end() != ipct); + MZN_MIPD__assert_hard(mipd._mCallTypes.end() != ipct); const DCT& dct = *ipct->second; int nCmpType_ADAPTED = dct.nCmpType; if (A < 0.0) { // negative factor @@ -1315,15 +1316,15 @@ private: convertIntSet(pCall->arg(1), SS, cls.varRef1, A, B); if (RIT_Static == dct.nReifType) { sDomain.intersect(SS); - ++MIPD_stats[N_POSTs_setIn]; + ++MIPD__stats[N_POSTs__setIn]; } else { sDomain.cutDeltas(SS, std::max(1.0, std::fabs(A))); // deltas to scale - ++MIPD_stats[N_POSTs_setInReif]; + ++MIPD__stats[N_POSTs__setInReif]; } } break; case CT_Comparison: if (RIT_Reif == dct.nReifType) { - const double rhs = (mipd.aux_float_lt_zero_iff_1_POST == pCall->decl()) + const double rhs = (mipd.aux_float_lt_zero_iff_1__POST == pCall->decl()) ? B /* + A*0.0, relating to 0 */ // The 2nd argument is constant: : A * MIPD::expr2Const(pCall->arg(1)) + B; @@ -1352,12 +1353,13 @@ private: } break; default: - MZN_MIPD_assert_hard_msg(0, " No other reified cmp type "); + MZN_MIPD__assert_hard_msg(0, " No other reified cmp type "); } - ++MIPD_stats[(vd->ti()->type().isint()) ? N_POSTs_intCmpReif : N_POSTs_floatCmpReif]; + ++MIPD__stats[(vd->ti()->type().isint()) ? N_POSTs__intCmpReif + : N_POSTs__floatCmpReif]; } else if (RIT_Static == dct.nReifType) { // _ne, later maybe static ineq TODO - MZN_MIPD_assert_hard(CMPT_NE == dct.nCmpType); + MZN_MIPD__assert_hard(CMPT_NE == dct.nCmpType); const double rhs = A * MIPD::expr2Const(pCall->arg(1)) + B; const double rhsRnd = rndIfInt(cls.varRef1, rhs); bool fSkipNE = (cls.varRef1->type().isint() && std::fabs(rhs - rhsRnd) > INT_EPS); @@ -1365,11 +1367,11 @@ private: const double delta = computeDelta(cls.varRef1, vd, bnds, A, pCall, 2); sDomain.cutOut({rhsRnd - delta, rhsRnd + delta}); } - ++MIPD_stats[(vd->ti()->type().isint()) ? N_POSTs_intNE : N_POSTs_floatNE]; + ++MIPD__stats[(vd->ti()->type().isint()) ? N_POSTs__intNE : N_POSTs__floatNE]; } else { // aux_ relate to 0.0 // But we don't modify domain splitting for them currently - ++MIPD_stats[(vd->ti()->type().isint()) ? N_POSTs_intAux : N_POSTs_floatAux]; - MZN_MIPD_assert_hard(RIT_Halfreif == dct.nReifType); + ++MIPD__stats[(vd->ti()->type().isint()) ? N_POSTs__intAux : N_POSTs__floatAux]; + MZN_MIPD__assert_hard(RIT_Halfreif == dct.nReifType); // const double rhs = B; // + A*0 // const double delta = vd->type().isint() ? 1.0 : 1e-5; // // TODO : eps @@ -1377,10 +1379,10 @@ private: break; case CT_Encode: // See if any further constraints here? TODO - ++MIPD_stats[N_POSTs_eq_encode]; + ++MIPD__stats[N_POSTs__eq_encode]; break; default: - MZN_MIPD_assert_hard_msg(0, "Unknown constraint type"); + MZN_MIPD__assert_hard_msg(0, "Unknown constraint type"); } } DBGOUT_MIPD(" Clique domain after proj of " << A << " * " << vd->id()->str() << " + " << B @@ -1412,7 +1414,7 @@ private: double lb0 = (bnds.left - iRef1.second.second) / iRef1.second.first; double ub0 = (bnds.right - iRef1.second.second) / iRef1.second.first; if (lb0 > ub0) { - MZN_MIPD_assert_hard(iRef1.second.first < 0.0); + MZN_MIPD__assert_hard(iRef1.second.first < 0.0); std::swap(lb0, ub0); } if (vd->type().isint()) { @@ -1433,10 +1435,10 @@ private: const long long iMin = mipd.expr2ExprArray( mipd._vVarDescr[cls.varRef1->payload()].pEqEncoding->e()->dynamicCast()->arg(1), pp); - MZN_MIPD_assert_hard(pp.size() >= bnds.right - bnds.left + 1); - MZN_MIPD_assert_hard(iMin <= bnds.left); + MZN_MIPD__assert_hard(pp.size() >= bnds.right - bnds.left + 1); + MZN_MIPD__assert_hard(iMin <= bnds.left); long long vEE = iMin; - DBGOUT_MIPD_FLUSH( + DBGOUT_MIPD__( " SYNC EQ_ENCODE( " << (*cls.varRef1) << ", bitflags: " << *(mipd._vVarDescr[cls.varRef1->payload()].pEqEncoding->e()->dynamicCast()->arg( @@ -1449,7 +1451,7 @@ private: } if (pp[vEE - iMin]->isa()) { if (pp[vEE - iMin]->dynamicCast()->decl()->type().isvar()) { - DBGOUT_MIPD_FLUSH(vEE << ", "); + DBGOUT_MIPD__(vEE << ", "); setVarDomain(pp[vEE - iMin]->dynamicCast()->decl(), 0.0, 0.0); } } @@ -1459,7 +1461,7 @@ private: for (; vEE < static_cast(iMin + pp.size()); ++vEE) { if (pp[vEE - iMin]->isa()) { if (pp[vEE - iMin]->dynamicCast()->decl()->type().isvar()) { - DBGOUT_MIPD_FLUSH(vEE << ", "); + DBGOUT_MIPD__(vEE << ", "); setVarDomain(pp[vEE - iMin]->dynamicCast()->decl(), 0.0, 0.0); } } @@ -1480,7 +1482,7 @@ private: if (sDomain.maxInterval() <= mipd.nMaxIntv2Bits || sDomain.cardInt() <= mipd.dMaxNValueDensity * sDomain.size()) { sDomain.split2Bits(); - ++MIPD_stats[N_POSTs_clEEEnforced]; + ++MIPD__stats[N_POSTs__clEEEnforced]; } } } @@ -1490,14 +1492,14 @@ private: void createDomainFlags() { std::vector vVars(sDomain.size()); // flags for each subinterval std::vector vIntvLB(sDomain.size() + 1); - std::vector vIntvUB_(sDomain.size() + 1); + std::vector vIntvUB__(sDomain.size() + 1); int i = 0; double dMaxIntv = -1.0; for (const auto& intv : sDomain) { intv.varFlag = addIntVar(0.0, 1.0); vVars[i] = intv.varFlag->id(); vIntvLB[i] = intv.left; - vIntvUB_[i] = -intv.right; + vIntvUB__[i] = -intv.right; dMaxIntv = std::max(dMaxIntv, intv.right - intv.left); ++i; } @@ -1509,11 +1511,11 @@ private: vIntvLB[i] = -1.0; // var1 >= sum(LBi*flagi) /// STRICT equality encoding if small intervals if (dMaxIntv > 1e-6) { // EPS = param? TODO - vIntvUB_[i] = 1.0; // var1 <= sum(UBi*flagi) + vIntvUB__[i] = 1.0; // var1 <= sum(UBi*flagi) addLinConstr(vIntvLB, vVars, CMPT_LE, 0.0); - addLinConstr(vIntvUB_, vVars, CMPT_LE, 0.0); + addLinConstr(vIntvUB__, vVars, CMPT_LE, 0.0); } else { - ++MIPD_stats[N_POSTs_clEEFound]; + ++MIPD__stats[N_POSTs__clEEFound]; addLinConstr(vIntvLB, vVars, CMPT_EQ, 0.0); } } @@ -1522,7 +1524,7 @@ private: void implementPOSTs() { auto bnds = sDomain.getBounds(); for (auto& iRef1 : cls.mRef1) { - // DBGOUT_MIPD_FLUSH( " MIPD: implementing constraints of variable " ); + // DBGOUT_MIPD__( " MIPD: implementing constraints of variable " ); // DBGOUT_MIPD_SELF( debugprint(vd) ); VarDecl* vd = iRef1.first; auto eq1 = iRef1.second; @@ -1532,14 +1534,14 @@ private: auto& aCalls = mipd._vVarDescr[vd->payload()].aCalls; for (Item* pItem : aCalls) { auto* pCI = pItem->dynamicCast(); - MZN_MIPD_assert_hard(pCI); + MZN_MIPD__assert_hard(pCI); Call* pCall = pCI->e()->dynamicCast(); - MZN_MIPD_assert_hard(pCall); - DBGOUT_MIPD_FLUSH("IMPL CALL "); + MZN_MIPD__assert_hard(pCall); + DBGOUT_MIPD__("IMPL CALL "); DBGOUT_MIPD_SELF(debugprint(pCall)); // check the bounds for bool in reifs? TODO auto ipct = mipd._mCallTypes.find(pCall->decl()); - MZN_MIPD_assert_hard(mipd._mCallTypes.end() != ipct); + MZN_MIPD__assert_hard(mipd._mCallTypes.end() != ipct); const DCT& dct = *ipct->second; int nCmpType_ADAPTED = dct.nCmpType; if (A < 0.0) { // negative factor @@ -1557,7 +1559,7 @@ private: break; case CT_Comparison: if (RIT_Reif == dct.nReifType) { - const double rhs = (mipd.aux_float_lt_zero_iff_1_POST == pCall->decl()) + const double rhs = (mipd.aux_float_lt_zero_iff_1__POST == pCall->decl()) ? B /* + A*0.0, relating to 0 */ // The 2nd argument is constant: : A * MIPD::expr2Const(pCall->arg(1)) + B; @@ -1588,16 +1590,16 @@ private: } } else if (RIT_Static == dct.nReifType) { // !hing here for NE - MZN_MIPD_assert_hard(CMPT_NE == nCmpType_ADAPTED); + MZN_MIPD__assert_hard(CMPT_NE == nCmpType_ADAPTED); } else { // aux_ relate to 0.0 // But we don't modify domain splitting for them currently - MZN_MIPD_assert_hard(RIT_Halfreif == dct.nReifType); + MZN_MIPD__assert_hard(RIT_Halfreif == dct.nReifType); double rhs = B; // + A*0 const double rhsUp = rndUpIfInt(cls.varRef1, rhs); const double rhsDown = rndDownIfInt(cls.varRef1, rhs); const double rhsRnd = rndIfInt(cls.varRef1, rhs); double delta = 0.0; - if (mipd.aux_float_lt_zero_if_1_POST == pCall->decl()) { // only float && lt + if (mipd.aux_float_lt_zero_if_1__POST == pCall->decl()) { // only float && lt delta = computeDelta(cls.varRef1, vd, bnds, A, pCall, 3); } if (nCmpType_ADAPTED < 0) { @@ -1645,7 +1647,7 @@ private: fUseDD = !fInner; } break; default: - MZN_MIPD_assert_hard_msg(0, "Unknown halfreif cmp type"); + MZN_MIPD__assert_hard_msg(0, "Unknown halfreif cmp type"); } } if (fUseDD) { // use sDomain @@ -1666,7 +1668,7 @@ private: cls.varRef1->ti()->type().isint() ? 1 : 2; // need the type of the variable to be constr - MZN_MIPD_assert_hard(static_cast(nIdxInd) < pCall->argCount()); + MZN_MIPD__assert_hard(static_cast(nIdxInd) < pCall->argCount()); Expression* pInd = pCall->arg(nIdxInd); if (fLE && rhs < bnds.right) { if (rhs >= bnds.left) { @@ -1694,7 +1696,7 @@ private: // See if any further constraints here? TODO break; default: - MZN_MIPD_assert_hard_msg(0, "Unknown constraint type"); + MZN_MIPD__assert_hard_msg(0, "Unknown constraint type"); } pItem->remove(); // removing the call } @@ -1707,19 +1709,19 @@ private: /// sets varFlag = || <= sum( intv.varFlag : SS ) void relateReifFlag(Expression* expFlag, const SetOfIntvReal& SS, EnumReifType nRT = RIT_Reif) { - MZN_MIPD_assert_hard(RIT_Reif == nRT || RIT_Halfreif == nRT); - // MZN_MIPD_assert_hard( sDomain.size()>=2 ); + MZN_MIPD__assert_hard(RIT_Reif == nRT || RIT_Halfreif == nRT); + // MZN_MIPD__assert_hard( sDomain.size()>=2 ); VarDecl* varFlag = MIPD::expr2VarDecl(expFlag); std::vector vIntvFlags; if (cls.fRef1HasEqEncode) { // use eq_encoding - MZN_MIPD_assert_hard(varFlag->type().isint()); + MZN_MIPD__assert_hard(varFlag->type().isint()); std::vector pp; auto bnds = sDomain.getBounds(); const long long iMin = mipd.expr2ExprArray( mipd._vVarDescr[cls.varRef1->payload()].pEqEncoding->e()->dynamicCast()->arg(1), pp); - MZN_MIPD_assert_hard(pp.size() >= bnds.right - bnds.left + 1); - MZN_MIPD_assert_hard(iMin <= bnds.left); + MZN_MIPD__assert_hard(pp.size() >= bnds.right - bnds.left + 1); + MZN_MIPD__assert_hard(iMin <= bnds.left); for (const auto& intv : SS) { for (long long vv = (long long)std::max(double(iMin), ceil(intv.left)); vv <= (long long)std::min(double(iMin) + pp.size() - 1, floor(intv.right)); ++vv) { @@ -1727,7 +1729,7 @@ private: } } } else { - MZN_MIPD_assert_hard(varFlag->type().isint()); + MZN_MIPD__assert_hard(varFlag->type().isint()); for (const auto& intv : SS) { auto it1 = sDomain.lower_bound(intv.left); auto it2 = sDomain.upper_bound(intv.right); @@ -1735,19 +1737,19 @@ private: // Check that we are looking ! into a subinterval: if (sDomain.begin() != it11) { --it11; - MZN_MIPD_assert_hard(it11->right < intv.left); + MZN_MIPD__assert_hard(it11->right < intv.left); } auto it12 = it2; if (sDomain.begin() != it12) { --it12; - MZN_MIPD_assert_hard_msg(it12->right <= intv.right, - " relateReifFlag for " << intv << " in " << sDomain); + MZN_MIPD__assert_hard_msg(it12->right <= intv.right, + " relateReifFlag for " << intv << " in " << sDomain); } for (it12 = it1; it12 != it2; ++it12) { if (it12->varFlag != nullptr) { vIntvFlags.push_back(it12->varFlag->id()); } else { - MZN_MIPD_assert_hard(1 == sDomain.size()); + MZN_MIPD__assert_hard(1 == sDomain.size()); vIntvFlags.push_back(IntLit::a(1)); // just a constant then } } @@ -1782,7 +1784,7 @@ private: // nti->domain(newDom); vd->ti()->domain(newDom); } else { - MZN_MIPD_assert_hard_msg(0, "Unknown var type "); + MZN_MIPD__assert_hard_msg(0, "Unknown var type "); } } @@ -1802,29 +1804,29 @@ private: void addLinConstr(std::vector& coefs, std::vector& vars, EnumCmpType nCmpType, double rhs) { std::vector args(3); - MZN_MIPD_assert_hard(vars.size() >= 2); + MZN_MIPD__assert_hard(vars.size() >= 2); for (auto* v : vars) { - MZN_MIPD_assert_hard(&v); + MZN_MIPD__assert_hard(&v); // throw std::string("addLinConstr: &var=NULL"); - MZN_MIPD_assert_hard_msg(v->isa() || v->isa() || v->isa(), - " expression at " << (&v) << " eid = " << v->eid() - << " while E_INTLIT=" << Expression::E_INTLIT); + MZN_MIPD__assert_hard_msg(v->isa() || v->isa() || v->isa(), + " expression at " << (&v) << " eid = " << v->eid() + << " while E_INTLIT=" << Expression::E_INTLIT); // throw std::string("addLinConstr: only id's as variables allowed"); } - MZN_MIPD_assert_hard(coefs.size() == vars.size()); - MZN_MIPD_assert_hard(CMPT_EQ == nCmpType || CMPT_LE == nCmpType); + MZN_MIPD__assert_hard(coefs.size() == vars.size()); + MZN_MIPD__assert_hard(CMPT_EQ == nCmpType || CMPT_LE == nCmpType); DBGOUT_MIPD_SELF( // LinEq leq; leq.coefs=coefs; leq.vd=vars; leq.rhs=rhs; - DBGOUT_MIPD_FLUSH(" ADDING " << (CMPT_EQ == nCmpType ? "LIN_EQ" : "LIN_LE") << ": [ "); + DBGOUT_MIPD__(" ADDING " << (CMPT_EQ == nCmpType ? "LIN_EQ" : "LIN_LE") << ": [ "); for (auto c - : coefs) DBGOUT_MIPD_FLUSH(c << ','); - DBGOUT_MIPD_FLUSH(" ] * [ "); for (auto v - : vars) { - MZN_MIPD_assert_hard(!v->isa()); - if (v->isa()) DBGOUT_MIPD_FLUSH(v->dynamicCast()->str() << ','); + : coefs) DBGOUT_MIPD__(c << ','); + DBGOUT_MIPD__(" ] * [ "); for (auto v + : vars) { + MZN_MIPD__assert_hard(!v->isa()); + if (v->isa()) DBGOUT_MIPD__(v->dynamicCast()->str() << ','); // else if ( v->isa() ) - // MZN_MIPD_assert_hard ("addLinConstr: only id's as variables allowed"); + // MZN_MIPD__assert_hard ("addLinConstr: only id's as variables allowed"); else - DBGOUT_MIPD_FLUSH(mipd.expr2Const(v) << ','); + DBGOUT_MIPD__(mipd.expr2Const(v) << ','); } DBGOUT_MIPD(" ] " << (CMPT_EQ == nCmpType ? "== " : "<= ") << rhs);); std::vector nc_c; std::vector nx; @@ -1837,7 +1839,7 @@ private: } auto sName = constants().ids.float_.lin_eq; // "int_lin_eq"; FunctionI* fDecl = mipd.float_lin_eq; - if (fFloat) { // MZN_MIPD_assert_hard all vars of same type TODO + if (fFloat) { // MZN_MIPD__assert_hard all vars of same type TODO for (int i = 0; i < vars.size(); ++i) { if (fabs(coefs[i]) > 1e-8) /// Only add terms with non-0 coefs. TODO Eps=param { @@ -1888,7 +1890,7 @@ private: } } if (mipd.getEnv()->envi().cseMapEnd() != mipd.getEnv()->envi().cseMapFind(args[0])) { - DBGOUT_MIPD_FLUSH(" Found expr "); + DBGOUT_MIPD__(" Found expr "); DBGOUT_MIPD_SELF(debugprint(args[0])); } auto* nc = new Call(Location().introduce(), ASTString(sName), args); @@ -1899,7 +1901,7 @@ private: /// domain / reif set of one variable into that for a!her void convertIntSet(Expression* e, SetOfIntvReal& s, VarDecl* varTarget, double A, double B) { - MZN_MIPD_assert_hard(A != 0.0); + MZN_MIPD__assert_hard(A != 0.0); if (e->type().isIntSet()) { IntSetVal* S = eval_intset(mipd.getEnv()->envi(), e); IntSetRanges domr(S); @@ -1949,11 +1951,11 @@ private: }; // class DomainDecomp /// Vars without explicit clique still need a decomposition. - /// Have !iced all _POSTs, set_in's && eq_encode's to it BEFORE + /// Have !iced all __POSTs, set_in's && eq_encode's to it BEFORE /// In each clique, relate all vars to one chosen /// Find all "smallest rel. factor" variables, integer && with eq_encode if avail /// Re-relate all vars to it - /// Refer all _POSTs && dom() to it + /// Refer all __POSTs && dom() to it /// build domain decomposition /// Implement all domain constraints, incl. possible corresp, of eq_encode's /// @@ -1975,7 +1977,7 @@ private: _vVarDescr[iVar].fDomainConstrProcessed = 1U; } } - // Clean up _POSTs: + // Clean up __POSTs: for (auto& vVar : _vVarDescr) { for (auto* pCallI : vVar.aCalls) { pCallI->remove(); @@ -1991,17 +1993,17 @@ private: // The requirement to have actual variable objects // might be a limitation if more optimizations are done before... // Might need to flexibilize this TODO - // MZN_MIPD_assert_hard_msg( ! arg->dynamicCast(), + // MZN_MIPD__assert_hard_msg( ! arg->dynamicCast(), // "Expression " << *arg << " is an IntLit!" ); - // MZN_MIPD_assert_hard( ! arg->dynamicCast() ); - // MZN_MIPD_assert_hard( ! arg->dynamicCast() ); + // MZN_MIPD__assert_hard( ! arg->dynamicCast() ); + // MZN_MIPD__assert_hard( ! arg->dynamicCast() ); Id* id = arg->dynamicCast(); - // MZN_MIPD_assert_hard(id); + // MZN_MIPD__assert_hard(id); if (nullptr == id) { return nullptr; // the call using this should be ignored? } VarDecl* vd = id->decl(); - MZN_MIPD_assert_hard(vd); + MZN_MIPD__assert_hard(vd); return vd; } @@ -2037,8 +2039,8 @@ private: if (auto* bl = arg->dynamicCast()) { return static_cast(bl->v()); } - MZN_MIPD_assert_hard_msg(0, "unexpected expression instead of an int/float/bool literal: eid=" - << arg->eid() << " while E_INTLIT=" << Expression::E_INTLIT); + MZN_MIPD__assert_hard_msg(0, "unexpected expression instead of an int/float/bool literal: eid=" + << arg->eid() << " while E_INTLIT=" << Expression::E_INTLIT); return 0.0; } @@ -2050,7 +2052,7 @@ private: template void checkOrResize(std::array& cnt, size_t sz) { - MZN_MIPD_assert_hard(cnt.size() == sz); + MZN_MIPD__assert_hard(cnt.size() == sz); } template @@ -2058,7 +2060,7 @@ private: ArrayLit* al = eval_array_lit(getEnv()->envi(), arg); // if ( typeid(typename Array::pointer) == typeid(typename Array::iterator) ) // fixed // array - // MZN_MIPD_assert_hard( vals.size() == al->v().size() ); + // MZN_MIPD__assert_hard( vals.size() == al->v().size() ); // else // vals.resize( al->v().size() ); checkOrResize(vals, al->size()); @@ -2086,32 +2088,32 @@ private: } // os << "N cliques " << _aCliques.size() << " total, " // << nc << " final" << std::endl; - MZN_MIPD_assert_hard(nc); - MIPD_stats[N_POSTs_eqNmapsize] = static_cast(_mNViews.size()); - double nSubintvAve = MIPD_stats[N_POSTs_NSubintvSum] / nc; - MZN_MIPD_assert_hard(MIPD_stats[N_POSTs_NSubintvSum]); - double dSubSizeAve = MIPD_stats[N_POSTs_SubSizeSum] / MIPD_stats[N_POSTs_NSubintvSum]; - os << MIPD_stats[N_POSTs_all] + MZN_MIPD__assert_hard(nc); + MIPD__stats[N_POSTs__eqNmapsize] = static_cast(_mNViews.size()); + double nSubintvAve = MIPD__stats[N_POSTs__NSubintvSum] / nc; + MZN_MIPD__assert_hard(MIPD__stats[N_POSTs__NSubintvSum]); + double dSubSizeAve = MIPD__stats[N_POSTs__SubSizeSum] / MIPD__stats[N_POSTs__NSubintvSum]; + os << MIPD__stats[N_POSTs__all] << " POSTs" -#ifdef MZN_MIPDOMAINS_PRINTMORESTATS +#ifdef __MZN__MIPDOMAINS__PRINTMORESTATS " [ "; - MZN_MIPDOMAINS_PRINTMORESTATS - for (int i = N_POSTs_intCmpReif; i <= N_POSTs_floatAux; ++i) { - os << MIPD_stats[i] << ','; + for (int i = N_POSTs__intCmpReif; i <= N_POSTs__floatAux; ++i) { + os << MIPD__stats[i] << ','; } os << " ], LINEQ [ "; - for (int i = N_POSTs_eq2intlineq; i <= N_POSTs_eqNmapsize; ++i) { - os << MIPD_stats[i] << ','; + for (int i = N_POSTs__eq2intlineq; i <= N_POSTs__eqNmapsize; ++i) { + os << MIPD__stats[i] << ','; } os << " ]" #endif ", " - << MIPD_stats[N_POSTs_varsDirect] << " / " << MIPD_stats[N_POSTs_varsInvolved] << " vars, " - << nc << " cliques, " << MIPD_stats[N_POSTs_NSubintvMin] << " / " << nSubintvAve << " / " - << MIPD_stats[N_POSTs_NSubintvMax] << " NSubIntv m/a/m, " << MIPD_stats[N_POSTs_SubSizeMin] - << " / " << dSubSizeAve << " / " << MIPD_stats[N_POSTs_SubSizeMax] << " SubIntvSize m/a/m, " - << MIPD_stats[N_POSTs_cliquesWithEqEncode] << "+" << MIPD_stats[N_POSTs_clEEEnforced] << "(" - << MIPD_stats[N_POSTs_clEEFound] << ")" + << MIPD__stats[N_POSTs__varsDirect] << " / " << MIPD__stats[N_POSTs__varsInvolved] + << " vars, " << nc << " cliques, " << MIPD__stats[N_POSTs__NSubintvMin] << " / " + << nSubintvAve << " / " << MIPD__stats[N_POSTs__NSubintvMax] << " NSubIntv m/a/m, " + << MIPD__stats[N_POSTs__SubSizeMin] << " / " << dSubSizeAve << " / " + << MIPD__stats[N_POSTs__SubSizeMax] << " SubIntvSize m/a/m, " + << MIPD__stats[N_POSTs__cliquesWithEqEncode] << "+" << MIPD__stats[N_POSTs__clEEEnforced] + << "(" << MIPD__stats[N_POSTs__clEEFound] << ")" << " clq eq_encoded "; // << std::flush if (TCliqueSorter::LinEqGraph::dCoefMax > 1.0) { @@ -2156,7 +2158,7 @@ void SetOfIntervals::cutDeltas(const SetOfIntervals& s2, N1 delta) { } template void SetOfIntervals::cutOut(const Interval& intv) { - DBGOUT_MIPD_FLUSH("Cutting " << intv << " from " << (*this)); + DBGOUT_MIPD__("Cutting " << intv << " from " << (*this)); if (this->empty()) { return; } @@ -2167,23 +2169,23 @@ void SetOfIntervals::cutOut(const Interval& intv) { if (this->begin() != it1) { --it1; const N it1l = it1->left; - MZN_MIPD_assert_hard(it1l <= intv.left); + MZN_MIPD__assert_hard(it1l <= intv.left); if (it1->right > intv.left) { // split it it2Del1 = split(it1, intv.left).second; // it1->right = intv.left; READ-ONLY // this->erase(it1); // it1 = this->end(); // auto iR = this->insert( Interval( it1l, intv.left ) ); - // MZN_MIPD_assert_hard( iR.second ); + // MZN_MIPD__assert_hard( iR.second ); } } - DBGOUT_MIPD_FLUSH("; after split 1: " << (*this)); + DBGOUT_MIPD__("; after split 1: " << (*this)); // Processing the right end: auto it2 = this->lower_bound(Interval(intv.right, intv.right + 1)); auto it2Del2 = it2; if (this->begin() != it2) { --it2; - MZN_MIPD_assert_hard(it2->left < intv.right); + MZN_MIPD__assert_hard(it2->left < intv.right); const N it2r = it2->right; if ((Interval::infPlus() == intv.right) ? (it2r > intv.right) : (it2r >= intv.right)) { // >=: split it @@ -2197,19 +2199,19 @@ void SetOfIntervals::cutOut(const Interval& intv) { } } } - DBGOUT_MIPD_FLUSH("; after split 2: " << (*this)); - DBGOUT_MIPD_FLUSH("; cutting out: " << SetOfIntervals(it2Del1, it2Del2)); + DBGOUT_MIPD__("; after split 2: " << (*this)); + DBGOUT_MIPD__("; cutting out: " << SetOfIntervals(it2Del1, it2Del2)); #ifdef MZN_DBG_CHECK_ITER_CUTOUT { auto it = this->begin(); int nO = 0; do { if (it == it2Del1) { - MZN_MIPD_assert_hard(!nO); + MZN_MIPD__assert_hard(!nO); ++nO; } if (it == it2Del2) { - MZN_MIPD_assert_hard(1 == nO); + MZN_MIPD__assert_hard(1 == nO); ++nO; } if (this->end() == it) { @@ -2217,7 +2219,7 @@ void SetOfIntervals::cutOut(const Interval& intv) { } ++it; } while (true); - MZN_MIPD_assert_hard(2 == nO); + MZN_MIPD__assert_hard(2 == nO); } #endif this->erase(it2Del1, it2Del2); @@ -2225,8 +2227,8 @@ void SetOfIntervals::cutOut(const Interval& intv) { } template typename SetOfIntervals::SplitResult SetOfIntervals::split(iterator& it, N pos) { - MZN_MIPD_assert_hard(pos >= it->left); - MZN_MIPD_assert_hard(pos <= it->right); + MZN_MIPD__assert_hard(pos >= it->left); + MZN_MIPD__assert_hard(pos <= it->right); Interval intvOld = *it; this->erase(it); auto it_01 = this->insert(Interval(intvOld.left, pos)); diff --git a/lib/ast.cpp b/lib/ast.cpp index 8d8c9e1..e3cbde9 100644 --- a/lib/ast.cpp +++ b/lib/ast.cpp @@ -1592,7 +1592,6 @@ Constants::Constants() { ids.set_subset = ASTString("set_subset"); ids.set_card = ASTString("set_card"); ids.pow = ASTString("pow"); - ids.mzn_set_in_internal = ASTString("mzn_set_in_internal"); ids.introduced_var = ASTString("__INTRODUCED"); ids.anonEnumFromStrings = ASTString("anon_enum"); @@ -1832,7 +1831,6 @@ void Constants::mark(MINIZINC_GC_STAT_ARGS) { ids.set_subset.mark(); ids.set_card.mark(); ids.pow.mark(); - ids.mzn_set_in_internal.mark(); ids.assert.mark(); ids.mzn_deprecate.mark(); diff --git a/lib/builtins.cpp b/lib/builtins.cpp index 51ccc6d..d1003ed 100644 --- a/lib/builtins.cpp +++ b/lib/builtins.cpp @@ -1619,10 +1619,6 @@ std::string b_logstream(EnvI& env, Call* call) { return env.logstream.str(); } bool b_in_redundant_constraint(EnvI& env, Call* /*call*/) { return env.inRedundantConstraint > 0; } -bool b_in_symmetry_breaking_constraint(EnvI& env, Call* /*call*/) { - return env.inSymmetryBreakingConstraint > 0; -} - Expression* b_set2array(EnvI& env, Call* call) { assert(call->argCount() == 1); GCLock lock; @@ -1789,7 +1785,7 @@ std::string b_show_json(EnvI& env, Call* call) { } Expression* b_output_json(EnvI& env, Call* call) { - return create_json_output(env, false, false, false); + return create__json_output(env, false, false, false); } Expression* b_output_json_parameters(EnvI& env, Call* call) { std::vector outputVars; @@ -3181,10 +3177,6 @@ void register_builtins(Env& e) { rb(env, m, ASTString("mzn_in_redundant_constraint"), std::vector(), b_in_redundant_constraint); } - { - rb(env, m, ASTString("mzn_in_symmetry_breaking_constraint"), std::vector(), - b_in_symmetry_breaking_constraint); - } { std::vector t_length(1); t_length[0] = Type::optvartop(-1); diff --git a/lib/cached/md5_cached.cmake b/lib/cached/md5_cached.cmake index 1c5cfb0..1903c4b 100644 --- a/lib/cached/md5_cached.cmake +++ b/lib/cached/md5_cached.cmake @@ -1,4 +1,4 @@ set(lexer_lxx_md5_cached "6346180a9a94e9f5218239f10ce67a32") -set(parser_yxx_md5_cached "95616f87b6ecbe14f80175ec8369e696") +set(parser_yxx_md5_cached "dca3042b18c4db1f1e625d1d46bdb3d1") set(regex_lexer_lxx_md5_cached "8906a52bfa0c5ae26354cb272348e656") set(regex_parser_yxx_md5_cached "68ec070becef5e161c3b97d085b0810e") \ No newline at end of file diff --git a/lib/cached/minizinc/parser.tab.hh b/lib/cached/minizinc/parser.tab.hh index 3a5bda6..4cfe146 100644 --- a/lib/cached/minizinc/parser.tab.hh +++ b/lib/cached/minizinc/parser.tab.hh @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.6.4. */ /* Bison interface for Yacc-like parsers in C @@ -35,8 +35,8 @@ especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ -#ifndef YY_MZN_YY_USERS_TACK_PROGRAMMING_MINIZINC_LIBMZN_BUILD_XCODE_INCLUDE_MINIZINC_PARSER_TAB_HH_INCLUDED -# define YY_MZN_YY_USERS_TACK_PROGRAMMING_MINIZINC_LIBMZN_BUILD_XCODE_INCLUDE_MINIZINC_PARSER_TAB_HH_INCLUDED +#ifndef YY_MZN_YY_USERS_TACK_PROGRAMMING_MINIZINC_LIBMZN_DEVELOP_BUILD_INCLUDE_MINIZINC_PARSER_TAB_HH_INCLUDED +# define YY_MZN_YY_USERS_TACK_PROGRAMMING_MINIZINC_LIBMZN_DEVELOP_BUILD_INCLUDE_MINIZINC_PARSER_TAB_HH_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -234,4 +234,4 @@ struct YYLTYPE int mzn_yyparse (void *parm); -#endif /* !YY_MZN_YY_USERS_TACK_PROGRAMMING_MINIZINC_LIBMZN_BUILD_XCODE_INCLUDE_MINIZINC_PARSER_TAB_HH_INCLUDED */ +#endif /* !YY_MZN_YY_USERS_TACK_PROGRAMMING_MINIZINC_LIBMZN_DEVELOP_BUILD_INCLUDE_MINIZINC_PARSER_TAB_HH_INCLUDED */ diff --git a/lib/cached/parser.tab.cpp b/lib/cached/parser.tab.cpp index eb2f84d..dd637c5 100644 --- a/lib/cached/parser.tab.cpp +++ b/lib/cached/parser.tab.cpp @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.6.4. */ /* Bison implementation for Yacc-like parsers in C @@ -45,11 +45,11 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ -/* Identify Bison output, and Bison version. */ -#define YYBISON 30704 +/* Identify Bison output. */ +#define YYBISON 1 -/* Bison version string. */ -#define YYBISON_VERSION "3.7.4" +/* Bison version. */ +#define YYBISON_VERSION "3.6.4" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -730,7 +730,6 @@ union yyalloc /* YYNSTATES -- Number of states. */ #define YYNSTATES 588 -/* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 387 @@ -2856,7 +2855,7 @@ yydestruct (const char *yymsg, int yyparse (void *parm) { -/* Lookahead token kind. */ +/* The lookahead symbol. */ int yychar; @@ -2875,37 +2874,42 @@ static YYLTYPE yyloc_default YYLTYPE yylloc = yyloc_default; /* Number of syntax errors so far. */ - int yynerrs = 0; + int yynerrs; - yy_state_fast_t yystate = 0; + yy_state_fast_t yystate; /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus = 0; + int yyerrstatus; - /* Refer to the stacks through separate pointers, to allow yyoverflow + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + 'yyls': related to locations. + + Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* Their size. */ - YYPTRDIFF_T yystacksize = YYINITDEPTH; + YYPTRDIFF_T yystacksize; - /* The state stack: array, bottom, top. */ + /* The state stack. */ yy_state_t yyssa[YYINITDEPTH]; - yy_state_t *yyss = yyssa; - yy_state_t *yyssp = yyss; + yy_state_t *yyss; + yy_state_t *yyssp; - /* The semantic value stack: array, bottom, top. */ + /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp = yyvs; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; - /* The location stack: array, bottom, top. */ + /* The location stack. */ YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp = yyls; + YYLTYPE *yyls; + YYLTYPE *yylsp; int yyn; /* The return value of yyparse. */ int yyresult; - /* Lookahead symbol kind. */ + /* Lookahead token as an internal (translated) token number. */ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the action routines. */ @@ -2926,6 +2930,16 @@ YYLTYPE yylloc = yyloc_default; Keep to zero when no symbol should be popped. */ int yylen = 0; + yynerrs = 0; + yystate = 0; + yyerrstatus = 0; + + yystacksize = YYINITDEPTH; + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yylsp = yyls = yylsa; + + YYDPRINTF ((stderr, "Starting parse\n")); yychar = YYEMPTY; /* Cause a token to be read. */ @@ -3144,7 +3158,7 @@ yyreduce: YY_REDUCE_PRINT (yyn); switch (yyn) { - case 5: /* item_list_head: item */ + case 5: { ParserState* pp = static_cast(parm); if ((yyvsp[0].item)) { @@ -3155,7 +3169,7 @@ yyreduce: } break; - case 6: /* item_list_head: doc_file_comments item */ + case 6: { ParserState* pp = static_cast(parm); if ((yyvsp[0].item)) { @@ -3166,7 +3180,7 @@ yyreduce: } break; - case 7: /* item_list_head: item_list_head ';' item */ + case 7: { ParserState* pp = static_cast(parm); if ((yyvsp[0].item)) { @@ -3177,7 +3191,7 @@ yyreduce: } break; - case 8: /* item_list_head: item_list_head ';' doc_file_comments item */ + case 8: { ParserState* pp = static_cast(parm); if ((yyvsp[0].item)) { @@ -3188,11 +3202,11 @@ yyreduce: } break; - case 9: /* item_list_head: item error_item_start */ + case 9: { yyerror(&(yylsp[0]), parm, "unexpected item, expecting ';' or end of file"); YYERROR; } break; - case 11: /* doc_file_comments: "file-level documentation comment" */ + case 11: { ParserState* pp = static_cast(parm); if (pp->parseDocComments && (yyvsp[0].sValue)) { @@ -3202,7 +3216,7 @@ yyreduce: } break; - case 12: /* doc_file_comments: doc_file_comments "file-level documentation comment" */ + case 12: { ParserState* pp = static_cast(parm); if (pp->parseDocComments && (yyvsp[0].sValue)) { @@ -3212,7 +3226,7 @@ yyreduce: } break; - case 15: /* item: "documentation comment" item_tail */ + case 15: { (yyval.item) = (yyvsp[0].item); ParserState* pp = static_cast(parm); if (FunctionI* fi = Item::dynamicCast((yyval.item))) { @@ -3230,58 +3244,58 @@ yyreduce: } break; - case 16: /* item: item_tail */ + case 16: { (yyval.item) = (yyvsp[0].item); } break; - case 17: /* item_tail: include_item */ + case 17: { (yyval.item)=notInDatafile(&(yyloc),parm,"include") ? (yyvsp[0].item) : nullptr; } break; - case 18: /* item_tail: vardecl_item */ + case 18: { (yyval.item)=notInDatafile(&(yyloc),parm,"variable declaration") ? (yyvsp[0].item) : nullptr; } break; - case 20: /* item_tail: constraint_item */ + case 20: { (yyval.item)=notInDatafile(&(yyloc),parm,"constraint") ? (yyvsp[0].item) : nullptr; } break; - case 21: /* item_tail: solve_item */ + case 21: { (yyval.item)=notInDatafile(&(yyloc),parm,"solve") ? (yyvsp[0].item) : nullptr; } break; - case 22: /* item_tail: output_item */ + case 22: { (yyval.item)=notInDatafile(&(yyloc),parm,"output") ? (yyvsp[0].item) : nullptr; } break; - case 23: /* item_tail: predicate_item */ + case 23: { (yyval.item)=notInDatafile(&(yyloc),parm,"predicate") ? (yyvsp[0].item) : nullptr; } break; - case 24: /* item_tail: function_item */ + case 24: { (yyval.item)=notInDatafile(&(yyloc),parm,"predicate") ? (yyvsp[0].item) : nullptr; } break; - case 25: /* item_tail: annotation_item */ + case 25: { (yyval.item)=notInDatafile(&(yyloc),parm,"annotation") ? (yyvsp[0].item) : nullptr; } break; - case 35: /* include_item: "include" "string literal" */ + case 35: { ParserState* pp = static_cast(parm); - string canonicalName=pp->canonicalFilename((yyvsp[0].sValue)); - map::iterator ret = pp->seenModels.find(canonicalName); + map::iterator ret = pp->seenModels.find((yyvsp[0].sValue)); IncludeI* ii = new IncludeI((yyloc),ASTString((yyvsp[0].sValue))); (yyval.item) = ii; if (ret == pp->seenModels.end()) { Model* im = new Model; im->setParent(pp->model); - im->setFilename(canonicalName); + im->setFilename((yyvsp[0].sValue)); string fpath = FileUtils::dir_name(pp->filename); + string fbase = FileUtils::base_name(pp->filename); if (fpath=="") fpath="./"; - pp->files.emplace_back(im, ii, fpath, canonicalName, pp->isSTDLib); + pp->files.emplace_back(im, ii, fpath, (yyvsp[0].sValue), pp->isSTDLib); ii->m(im); - pp->seenModels.insert(pair(canonicalName,im)); + pp->seenModels.insert(pair((yyvsp[0].sValue),im)); } else { ii->m(ret->second, false); } @@ -3289,7 +3303,7 @@ yyreduce: } break; - case 36: /* vardecl_item: ti_expr_and_id annotations */ + case 36: { if ((yyvsp[-1].vardeclexpr) && (yyvsp[0].expressions1d)) (yyvsp[-1].vardeclexpr)->addAnnotations(*(yyvsp[0].expressions1d)); if ((yyvsp[-1].vardeclexpr)) (yyval.item) = new VarDeclI((yyloc),(yyvsp[-1].vardeclexpr)); @@ -3297,7 +3311,7 @@ yyreduce: } break; - case 37: /* vardecl_item: ti_expr_and_id annotations "=" expr */ + case 37: { if ((yyvsp[-3].vardeclexpr)) (yyvsp[-3].vardeclexpr)->e((yyvsp[0].expression)); if ((yyvsp[-3].vardeclexpr) && (yyvsp[-2].expressions1d)) (yyvsp[-3].vardeclexpr)->addAnnotations(*(yyvsp[-2].expressions1d)); if ((yyvsp[-3].vardeclexpr)) @@ -3306,7 +3320,7 @@ yyreduce: } break; - case 38: /* vardecl_item: "enum" "identifier" annotations */ + case 38: { TypeInst* ti = new TypeInst((yyloc),Type::parsetint()); ti->setIsEnum(true); @@ -3318,7 +3332,7 @@ yyreduce: } break; - case 39: /* vardecl_item: "enum" "identifier" annotations "=" enum_init */ + case 39: { if ((yyvsp[0].expressions1d)) { TypeInst* ti = new TypeInst((yyloc),Type::parsetint()); @@ -3338,7 +3352,7 @@ yyreduce: } break; - case 40: /* vardecl_item: "enum" "identifier" annotations "=" "[" string_lit_list "]" */ + case 40: { TypeInst* ti = new TypeInst((yyloc),Type::parsetint()); ti->setIsEnum(true); @@ -3354,13 +3368,13 @@ yyreduce: } break; - case 41: /* enum_init: enum_construct */ + case 41: { (yyval.expressions1d) = new std::vector({(yyvsp[0].expression)}); } break; - case 42: /* enum_init: enum_init "++" enum_construct */ + case 42: { (yyval.expressions1d) = (yyvsp[-2].expressions1d); if ((yyval.expressions1d)) { @@ -3369,14 +3383,14 @@ yyreduce: } break; - case 43: /* enum_construct: '{' enum_id_list '}' */ + case 43: { (yyval.expression) = new SetLit((yyloc), *(yyvsp[-1].expressions1d)); delete (yyvsp[-1].expressions1d); } break; - case 44: /* enum_construct: "identifier" '(' expr ')' */ + case 44: { vector args({(yyvsp[-1].expression)}); (yyval.expression) = new Call((yyloc), ASTString((yyvsp[-3].sValue)), args); @@ -3384,80 +3398,80 @@ yyreduce: } break; - case 45: /* string_lit_list: %empty */ + case 45: { (yyval.expressions1d) = new std::vector(); } break; - case 46: /* string_lit_list: "string literal" */ + case 46: { (yyval.expressions1d) = new std::vector(); (yyval.expressions1d)->push_back(new StringLit((yyloc), (yyvsp[0].sValue))); free((yyvsp[0].sValue)); } break; - case 47: /* string_lit_list: string_lit_list ',' "string literal" */ + case 47: { (yyval.expressions1d) = (yyvsp[-2].expressions1d); if ((yyval.expressions1d)) (yyval.expressions1d)->push_back(new StringLit((yyloc), (yyvsp[0].sValue))); free((yyvsp[0].sValue)); } break; - case 48: /* enum_id_list: %empty */ + case 48: { (yyval.expressions1d) = new std::vector(); } break; - case 49: /* enum_id_list: "identifier" */ + case 49: { (yyval.expressions1d) = new std::vector(); (yyval.expressions1d)->push_back(new Id((yyloc),(yyvsp[0].sValue),nullptr)); free((yyvsp[0].sValue)); } break; - case 50: /* enum_id_list: enum_id_list ',' "identifier" */ + case 50: { (yyval.expressions1d) = (yyvsp[-2].expressions1d); if ((yyval.expressions1d)) (yyval.expressions1d)->push_back(new Id((yyloc),(yyvsp[0].sValue),nullptr)); free((yyvsp[0].sValue)); } break; - case 51: /* assign_item: "identifier" "=" expr */ + case 51: { (yyval.item) = new AssignI((yyloc),(yyvsp[-2].sValue),(yyvsp[0].expression)); free((yyvsp[-2].sValue)); } break; - case 52: /* constraint_item: "constraint" expr */ + case 52: { (yyval.item) = new ConstraintI((yyloc),(yyvsp[0].expression));} break; - case 53: /* constraint_item: "constraint" "::" string_expr expr */ + case 53: { (yyval.item) = new ConstraintI((yyloc),(yyvsp[0].expression)); if ((yyvsp[0].expression) && (yyvsp[-1].expression)) (yyval.item)->cast()->e()->ann().add(new Call((yylsp[-2]), ASTString("mzn_constraint_name"), {(yyvsp[-1].expression)})); } break; - case 54: /* solve_item: "solve" annotations "satisfy" */ + case 54: { (yyval.item) = SolveI::sat((yyloc)); if ((yyval.item) && (yyvsp[-1].expressions1d)) (yyval.item)->cast()->ann().add(*(yyvsp[-1].expressions1d)); delete (yyvsp[-1].expressions1d); } break; - case 55: /* solve_item: "solve" annotations "minimize" expr */ + case 55: { (yyval.item) = SolveI::min((yyloc),(yyvsp[0].expression)); if ((yyval.item) && (yyvsp[-2].expressions1d)) (yyval.item)->cast()->ann().add(*(yyvsp[-2].expressions1d)); delete (yyvsp[-2].expressions1d); } break; - case 56: /* solve_item: "solve" annotations "maximize" expr */ + case 56: { (yyval.item) = SolveI::max((yyloc),(yyvsp[0].expression)); if ((yyval.item) && (yyvsp[-2].expressions1d)) (yyval.item)->cast()->ann().add(*(yyvsp[-2].expressions1d)); delete (yyvsp[-2].expressions1d); } break; - case 57: /* output_item: "output" expr */ + case 57: { (yyval.item) = new OutputI((yyloc),(yyvsp[0].expression));} break; - case 58: /* predicate_item: "predicate" "identifier" params annotations operation_item_tail */ + case 58: { ParserState* pp = static_cast(parm); if ((yyvsp[-2].vardeclexprs)) (yyval.item) = new FunctionI((yyloc),(yyvsp[-3].sValue),new TypeInst((yyloc), @@ -3469,7 +3483,7 @@ yyreduce: } break; - case 59: /* predicate_item: "test" "identifier" params annotations operation_item_tail */ + case 59: { ParserState* pp = static_cast(parm); if ((yyvsp[-2].vardeclexprs)) (yyval.item) = new FunctionI((yyloc),(yyvsp[-3].sValue),new TypeInst((yyloc), @@ -3481,7 +3495,7 @@ yyreduce: } break; - case 60: /* predicate_item: "predicate" "identifier" "^-1" params annotations operation_item_tail */ + case 60: { if ((yyvsp[-2].vardeclexprs)) (yyval.item) = new FunctionI((yyloc),std::string((yyvsp[-4].sValue))+"⁻¹",new TypeInst((yyloc), Type::varbool()),*(yyvsp[-2].vardeclexprs),(yyvsp[0].expression)); if ((yyval.item) && (yyvsp[-1].expressions1d)) (yyval.item)->cast()->ann().add(*(yyvsp[-1].expressions1d)); @@ -3491,7 +3505,7 @@ yyreduce: } break; - case 61: /* predicate_item: "test" "identifier" "^-1" params annotations operation_item_tail */ + case 61: { if ((yyvsp[-2].vardeclexprs)) (yyval.item) = new FunctionI((yyloc),std::string((yyvsp[-4].sValue))+"⁻¹",new TypeInst((yyloc), Type::parbool()),*(yyvsp[-2].vardeclexprs),(yyvsp[0].expression)); if ((yyval.item) && (yyvsp[-1].expressions1d)) (yyval.item)->cast()->ann().add(*(yyvsp[-1].expressions1d)); @@ -3501,7 +3515,7 @@ yyreduce: } break; - case 62: /* function_item: "function" ti_expr ':' id_or_quoted_op params annotations operation_item_tail */ + case 62: { ParserState* pp = static_cast(parm); if ((yyvsp[-2].vardeclexprs)) (yyval.item) = new FunctionI((yyloc),(yyvsp[-3].sValue),(yyvsp[-5].tiexpr),*(yyvsp[-2].vardeclexprs),(yyvsp[0].expression),pp->isSTDLib); @@ -3512,7 +3526,7 @@ yyreduce: } break; - case 63: /* function_item: ti_expr ':' "identifier" '(' params_list ')' annotations operation_item_tail */ + case 63: { ParserState* pp = static_cast(parm); if ((yyvsp[-3].vardeclexprs)) (yyval.item) = new FunctionI((yyloc),(yyvsp[-5].sValue),(yyvsp[-7].tiexpr),*(yyvsp[-3].vardeclexprs),(yyvsp[0].expression),pp->isSTDLib); @@ -3523,7 +3537,7 @@ yyreduce: } break; - case 64: /* annotation_item: "annotation" "identifier" params */ + case 64: { ParserState* pp = static_cast(parm); TypeInst* ti=new TypeInst((yylsp[-2]),Type::ann()); @@ -3538,7 +3552,7 @@ yyreduce: } break; - case 65: /* annotation_item: "annotation" "identifier" params "=" expr */ + case 65: { ParserState* pp = static_cast(parm); TypeInst* ti=new TypeInst((yylsp[-4]),Type::ann()); @@ -3547,55 +3561,55 @@ yyreduce: } break; - case 66: /* operation_item_tail: %empty */ + case 66: { (yyval.expression)=nullptr; } break; - case 67: /* operation_item_tail: "=" expr */ + case 67: { (yyval.expression)=(yyvsp[0].expression); } break; - case 68: /* params: %empty */ + case 68: { (yyval.vardeclexprs)=new vector(); } break; - case 69: /* params: '(' params_list ')' */ + case 69: { (yyval.vardeclexprs)=(yyvsp[-1].vardeclexprs); } break; - case 70: /* params: '(' error ')' */ + case 70: { (yyval.vardeclexprs)=new vector(); } break; - case 71: /* params_list: %empty */ + case 71: { (yyval.vardeclexprs)=new vector(); } break; - case 72: /* params_list: params_list_head comma_or_none */ + case 72: { (yyval.vardeclexprs)=(yyvsp[-1].vardeclexprs); } break; - case 73: /* params_list_head: ti_expr_and_id_or_anon */ + case 73: { (yyval.vardeclexprs)=new vector(); if ((yyvsp[0].vardeclexpr)) (yyvsp[0].vardeclexpr)->toplevel(false); if ((yyvsp[0].vardeclexpr)) (yyval.vardeclexprs)->push_back((yyvsp[0].vardeclexpr)); } break; - case 74: /* params_list_head: params_list_head ',' ti_expr_and_id_or_anon */ + case 74: { (yyval.vardeclexprs)=(yyvsp[-2].vardeclexprs); if ((yyvsp[0].vardeclexpr)) (yyvsp[0].vardeclexpr)->toplevel(false); if ((yyvsp[-2].vardeclexprs) && (yyvsp[0].vardeclexpr)) (yyvsp[-2].vardeclexprs)->push_back((yyvsp[0].vardeclexpr)); } break; - case 77: /* ti_expr_and_id_or_anon: ti_expr_and_id */ + case 77: { (yyval.vardeclexpr)=(yyvsp[0].vardeclexpr); } break; - case 78: /* ti_expr_and_id_or_anon: ti_expr */ + case 78: { if ((yyvsp[0].tiexpr)) (yyval.vardeclexpr)=new VarDecl((yyloc), (yyvsp[0].tiexpr), ""); } break; - case 79: /* ti_expr_and_id: ti_expr ':' "identifier" */ + case 79: { if ((yyvsp[-2].tiexpr) && (yyvsp[0].sValue)) { Id* ident = new Id((yylsp[0]), (yyvsp[0].sValue), nullptr); (yyval.vardeclexpr) = new VarDecl((yyloc), (yyvsp[-2].tiexpr), ident); @@ -3604,19 +3618,19 @@ yyreduce: } break; - case 80: /* ti_expr_list: ti_expr_list_head comma_or_none */ + case 80: { (yyval.tiexprs)=(yyvsp[-1].tiexprs); } break; - case 81: /* ti_expr_list_head: ti_expr */ + case 81: { (yyval.tiexprs)=new vector(); (yyval.tiexprs)->push_back((yyvsp[0].tiexpr)); } break; - case 82: /* ti_expr_list_head: ti_expr_list_head ',' ti_expr */ + case 82: { (yyval.tiexprs)=(yyvsp[-2].tiexprs); if ((yyvsp[-2].tiexprs) && (yyvsp[0].tiexpr)) (yyvsp[-2].tiexprs)->push_back((yyvsp[0].tiexpr)); } break; - case 84: /* ti_expr: "array" "[" ti_expr_list "]" "of" base_ti_expr */ + case 84: { (yyval.tiexpr) = (yyvsp[0].tiexpr); if ((yyval.tiexpr) && (yyvsp[-3].tiexprs)) (yyval.tiexpr)->setRanges(*(yyvsp[-3].tiexprs)); @@ -3624,7 +3638,7 @@ yyreduce: } break; - case 85: /* ti_expr: "list" "of" base_ti_expr */ + case 85: { (yyval.tiexpr) = (yyvsp[0].tiexpr); std::vector ti(1); @@ -3633,12 +3647,12 @@ yyreduce: } break; - case 86: /* base_ti_expr: base_ti_expr_tail */ + case 86: { (yyval.tiexpr) = (yyvsp[0].tiexpr); } break; - case 87: /* base_ti_expr: "opt" base_ti_expr_tail */ + case 87: { (yyval.tiexpr) = (yyvsp[0].tiexpr); if ((yyval.tiexpr)) { Type tt = (yyval.tiexpr)->type(); @@ -3648,7 +3662,7 @@ yyreduce: } break; - case 88: /* base_ti_expr: "par" opt_opt base_ti_expr_tail */ + case 88: { (yyval.tiexpr) = (yyvsp[0].tiexpr); if ((yyval.tiexpr) && (yyvsp[-1].bValue)) { Type tt = (yyval.tiexpr)->type(); @@ -3658,7 +3672,7 @@ yyreduce: } break; - case 89: /* base_ti_expr: "var" opt_opt base_ti_expr_tail */ + case 89: { (yyval.tiexpr) = (yyvsp[0].tiexpr); if ((yyval.tiexpr)) { Type tt = (yyval.tiexpr)->type(); @@ -3669,7 +3683,7 @@ yyreduce: } break; - case 90: /* base_ti_expr: "set" "of" base_ti_expr_tail */ + case 90: { (yyval.tiexpr) = (yyvsp[0].tiexpr); if ((yyval.tiexpr)) { Type tt = (yyval.tiexpr)->type(); @@ -3679,7 +3693,7 @@ yyreduce: } break; - case 91: /* base_ti_expr: "opt" "set" "of" base_ti_expr_tail */ + case 91: { (yyval.tiexpr) = (yyvsp[0].tiexpr); if ((yyval.tiexpr)) { Type tt = (yyval.tiexpr)->type(); @@ -3690,7 +3704,7 @@ yyreduce: } break; - case 92: /* base_ti_expr: "par" opt_opt "set" "of" base_ti_expr_tail */ + case 92: { (yyval.tiexpr) = (yyvsp[0].tiexpr); if ((yyval.tiexpr)) { Type tt = (yyval.tiexpr)->type(); @@ -3701,7 +3715,7 @@ yyreduce: } break; - case 93: /* base_ti_expr: "var" opt_opt "set" "of" base_ti_expr_tail */ + case 93: { (yyval.tiexpr) = (yyvsp[0].tiexpr); if ((yyval.tiexpr)) { Type tt = (yyval.tiexpr)->type(); @@ -3713,69 +3727,69 @@ yyreduce: } break; - case 94: /* opt_opt: %empty */ + case 94: { (yyval.bValue) = false; } break; - case 95: /* opt_opt: "opt" */ + case 95: { (yyval.bValue) = true; } break; - case 96: /* base_ti_expr_tail: "int" */ + case 96: { (yyval.tiexpr) = new TypeInst((yyloc),Type::parint()); } break; - case 97: /* base_ti_expr_tail: "bool" */ + case 97: { (yyval.tiexpr) = new TypeInst((yyloc),Type::parbool()); } break; - case 98: /* base_ti_expr_tail: "float" */ + case 98: { (yyval.tiexpr) = new TypeInst((yyloc),Type::parfloat()); } break; - case 99: /* base_ti_expr_tail: "string" */ + case 99: { (yyval.tiexpr) = new TypeInst((yyloc),Type::parstring()); } break; - case 100: /* base_ti_expr_tail: "ann" */ + case 100: { (yyval.tiexpr) = new TypeInst((yyloc),Type::ann()); } break; - case 101: /* base_ti_expr_tail: set_expr */ + case 101: { if ((yyvsp[0].expression)) (yyval.tiexpr) = new TypeInst((yyloc),Type(),(yyvsp[0].expression)); } break; - case 102: /* base_ti_expr_tail: "type-inst identifier" */ + case 102: { (yyval.tiexpr) = new TypeInst((yyloc),Type::top(), new TIId((yyloc), (yyvsp[0].sValue))); free((yyvsp[0].sValue)); } break; - case 103: /* base_ti_expr_tail: "type-inst enum identifier" */ + case 103: { (yyval.tiexpr) = new TypeInst((yyloc),Type::parint(), new TIId((yyloc), (yyvsp[0].sValue))); free((yyvsp[0].sValue)); } break; - case 105: /* array_access_expr_list_head: array_access_expr */ + case 105: { (yyval.expressions1d)=new std::vector; (yyval.expressions1d)->push_back((yyvsp[0].expression)); } break; - case 106: /* array_access_expr_list_head: array_access_expr_list_head ',' array_access_expr */ + case 106: { (yyval.expressions1d)=(yyvsp[-2].expressions1d); if ((yyval.expressions1d) && (yyvsp[0].expression)) (yyval.expressions1d)->push_back((yyvsp[0].expression)); } break; - case 107: /* array_access_expr: expr */ + case 107: { (yyval.expression) = (yyvsp[0].expression); } break; - case 108: /* array_access_expr: ".." */ + case 108: { (yyval.expression)=new SetLit((yyloc), IntSetVal::a(-IntVal::infinity(),IntVal::infinity())); } break; - case 109: /* array_access_expr: ".." expr */ + case 109: { if ((yyvsp[0].expression)==nullptr) { (yyval.expression) = nullptr; } else if ((yyvsp[0].expression)->isa()) { @@ -3786,7 +3800,7 @@ yyreduce: } break; - case 110: /* array_access_expr: expr ".." */ + case 110: { if ((yyvsp[-1].expression)==nullptr) { (yyval.expression) = nullptr; } else if ((yyvsp[-1].expression)->isa()) { @@ -3797,31 +3811,31 @@ yyreduce: } break; - case 112: /* expr_list_head: expr */ + case 112: { (yyval.expressions1d)=new std::vector; (yyval.expressions1d)->push_back((yyvsp[0].expression)); } break; - case 113: /* expr_list_head: expr_list_head ',' expr */ + case 113: { (yyval.expressions1d)=(yyvsp[-2].expressions1d); if ((yyval.expressions1d) && (yyvsp[0].expression)) (yyval.expressions1d)->push_back((yyvsp[0].expression)); } break; - case 115: /* set_expr: set_expr "::" annotation_expr */ + case 115: { if ((yyvsp[-2].expression) && (yyvsp[0].expression)) (yyvsp[-2].expression)->addAnnotation((yyvsp[0].expression)); (yyval.expression)=(yyvsp[-2].expression); } break; - case 116: /* set_expr: set_expr "union" set_expr */ + case 116: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_UNION, (yyvsp[0].expression)); } break; - case 117: /* set_expr: set_expr "diff" set_expr */ + case 117: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_DIFF, (yyvsp[0].expression)); } break; - case 118: /* set_expr: set_expr "symdiff" set_expr */ + case 118: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_SYMDIFF, (yyvsp[0].expression)); } break; - case 119: /* set_expr: set_expr ".." set_expr */ + case 119: { if ((yyvsp[-2].expression)==nullptr || (yyvsp[0].expression)==nullptr) { (yyval.expression) = nullptr; } else if ((yyvsp[-2].expression)->isa() && (yyvsp[0].expression)->isa()) { @@ -3832,7 +3846,7 @@ yyreduce: } break; - case 120: /* set_expr: "'..'" '(' expr ',' expr ')' */ + case 120: { if ((yyvsp[-3].expression)==nullptr || (yyvsp[-1].expression)==nullptr) { (yyval.expression) = nullptr; } else if ((yyvsp[-3].expression)->isa() && (yyvsp[-1].expression)->isa()) { @@ -3843,71 +3857,71 @@ yyreduce: } break; - case 121: /* set_expr: set_expr "intersect" set_expr */ + case 121: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_INTERSECT, (yyvsp[0].expression)); } break; - case 122: /* set_expr: set_expr "++" set_expr */ + case 122: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_PLUSPLUS, (yyvsp[0].expression)); } break; - case 123: /* set_expr: set_expr "+" set_expr */ + case 123: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_PLUS, (yyvsp[0].expression)); } break; - case 124: /* set_expr: set_expr "-" set_expr */ + case 124: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_MINUS, (yyvsp[0].expression)); } break; - case 125: /* set_expr: set_expr "*" set_expr */ + case 125: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_MULT, (yyvsp[0].expression)); } break; - case 126: /* set_expr: set_expr "/" set_expr */ + case 126: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_DIV, (yyvsp[0].expression)); } break; - case 127: /* set_expr: set_expr "div" set_expr */ + case 127: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_IDIV, (yyvsp[0].expression)); } break; - case 128: /* set_expr: set_expr "mod" set_expr */ + case 128: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_MOD, (yyvsp[0].expression)); } break; - case 129: /* set_expr: set_expr "^" set_expr */ + case 129: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_POW, (yyvsp[0].expression)); } break; - case 130: /* set_expr: set_expr "~+" set_expr */ + case 130: { vector args; args.push_back((yyvsp[-2].expression)); args.push_back((yyvsp[0].expression)); (yyval.expression)=new Call((yyloc), ASTString("~+"), args); } break; - case 131: /* set_expr: set_expr "~-" set_expr */ + case 131: { vector args; args.push_back((yyvsp[-2].expression)); args.push_back((yyvsp[0].expression)); (yyval.expression)=new Call((yyloc), ASTString("~-"), args); } break; - case 132: /* set_expr: set_expr "~*" set_expr */ + case 132: { vector args; args.push_back((yyvsp[-2].expression)); args.push_back((yyvsp[0].expression)); (yyval.expression)=new Call((yyloc), ASTString("~*"), args); } break; - case 133: /* set_expr: set_expr "~=" set_expr */ + case 133: { vector args; args.push_back((yyvsp[-2].expression)); args.push_back((yyvsp[0].expression)); (yyval.expression)=new Call((yyloc), ASTString("~="), args); } break; - case 134: /* set_expr: set_expr "quoted identifier" set_expr */ + case 134: { vector args; args.push_back((yyvsp[-2].expression)); args.push_back((yyvsp[0].expression)); (yyval.expression)=new Call((yyloc), (yyvsp[-1].sValue), args); @@ -3915,11 +3929,11 @@ yyreduce: } break; - case 135: /* set_expr: "+" set_expr */ + case 135: { (yyval.expression)=new UnOp((yyloc), UOT_PLUS, (yyvsp[0].expression)); } break; - case 136: /* set_expr: "-" set_expr */ + case 136: { if ((yyvsp[0].expression) && (yyvsp[0].expression)->isa()) { (yyval.expression) = IntLit::a(-(yyvsp[0].expression)->cast()->v()); } else if ((yyvsp[0].expression) && (yyvsp[0].expression)->isa()) { @@ -3930,83 +3944,83 @@ yyreduce: } break; - case 138: /* expr: expr "::" annotation_expr */ + case 138: { if ((yyvsp[-2].expression) && (yyvsp[0].expression)) (yyvsp[-2].expression)->addAnnotation((yyvsp[0].expression)); (yyval.expression)=(yyvsp[-2].expression); } break; - case 139: /* expr: expr "<->" expr */ + case 139: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_EQUIV, (yyvsp[0].expression)); } break; - case 140: /* expr: expr "->" expr */ + case 140: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_IMPL, (yyvsp[0].expression)); } break; - case 141: /* expr: expr "<-" expr */ + case 141: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_RIMPL, (yyvsp[0].expression)); } break; - case 142: /* expr: expr "\\/" expr */ + case 142: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_OR, (yyvsp[0].expression)); } break; - case 143: /* expr: expr "xor" expr */ + case 143: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_XOR, (yyvsp[0].expression)); } break; - case 144: /* expr: expr "/\\" expr */ + case 144: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_AND, (yyvsp[0].expression)); } break; - case 145: /* expr: expr "<" expr */ + case 145: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_LE, (yyvsp[0].expression)); } break; - case 146: /* expr: expr ">" expr */ + case 146: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_GR, (yyvsp[0].expression)); } break; - case 147: /* expr: expr "<=" expr */ + case 147: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_LQ, (yyvsp[0].expression)); } break; - case 148: /* expr: expr ">=" expr */ + case 148: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_GQ, (yyvsp[0].expression)); } break; - case 149: /* expr: expr "=" expr */ + case 149: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_EQ, (yyvsp[0].expression)); } break; - case 150: /* expr: expr "!=" expr */ + case 150: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_NQ, (yyvsp[0].expression)); } break; - case 151: /* expr: expr "in" expr */ + case 151: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_IN, (yyvsp[0].expression)); } break; - case 152: /* expr: expr "subset" expr */ + case 152: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_SUBSET, (yyvsp[0].expression)); } break; - case 153: /* expr: expr "superset" expr */ + case 153: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_SUPERSET, (yyvsp[0].expression)); } break; - case 154: /* expr: expr "union" expr */ + case 154: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_UNION, (yyvsp[0].expression)); } break; - case 155: /* expr: expr "diff" expr */ + case 155: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_DIFF, (yyvsp[0].expression)); } break; - case 156: /* expr: expr "symdiff" expr */ + case 156: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_SYMDIFF, (yyvsp[0].expression)); } break; - case 157: /* expr: expr ".." expr */ + case 157: { if ((yyvsp[-2].expression)==nullptr || (yyvsp[0].expression)==nullptr) { (yyval.expression) = nullptr; } else if ((yyvsp[-2].expression)->isa() && (yyvsp[0].expression)->isa()) { @@ -4017,7 +4031,7 @@ yyreduce: } break; - case 158: /* expr: "'..'" '(' expr ',' expr ')' */ + case 158: { if ((yyvsp[-3].expression)==nullptr || (yyvsp[-1].expression)==nullptr) { (yyval.expression) = nullptr; } else if ((yyvsp[-3].expression)->isa() && (yyvsp[-1].expression)->isa()) { @@ -4028,71 +4042,71 @@ yyreduce: } break; - case 159: /* expr: expr "intersect" expr */ + case 159: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_INTERSECT, (yyvsp[0].expression)); } break; - case 160: /* expr: expr "++" expr */ + case 160: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_PLUSPLUS, (yyvsp[0].expression)); } break; - case 161: /* expr: expr "+" expr */ + case 161: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_PLUS, (yyvsp[0].expression)); } break; - case 162: /* expr: expr "-" expr */ + case 162: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_MINUS, (yyvsp[0].expression)); } break; - case 163: /* expr: expr "*" expr */ + case 163: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_MULT, (yyvsp[0].expression)); } break; - case 164: /* expr: expr "/" expr */ + case 164: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_DIV, (yyvsp[0].expression)); } break; - case 165: /* expr: expr "div" expr */ + case 165: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_IDIV, (yyvsp[0].expression)); } break; - case 166: /* expr: expr "mod" expr */ + case 166: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_MOD, (yyvsp[0].expression)); } break; - case 167: /* expr: expr "^" expr */ + case 167: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_POW, (yyvsp[0].expression)); } break; - case 168: /* expr: expr "~+" expr */ + case 168: { vector args; args.push_back((yyvsp[-2].expression)); args.push_back((yyvsp[0].expression)); (yyval.expression)=new Call((yyloc), ASTString("~+"), args); } break; - case 169: /* expr: expr "~-" expr */ + case 169: { vector args; args.push_back((yyvsp[-2].expression)); args.push_back((yyvsp[0].expression)); (yyval.expression)=new Call((yyloc), ASTString("~-"), args); } break; - case 170: /* expr: expr "~*" expr */ + case 170: { vector args; args.push_back((yyvsp[-2].expression)); args.push_back((yyvsp[0].expression)); (yyval.expression)=new Call((yyloc), ASTString("~*"), args); } break; - case 171: /* expr: expr "~=" expr */ + case 171: { vector args; args.push_back((yyvsp[-2].expression)); args.push_back((yyvsp[0].expression)); (yyval.expression)=new Call((yyloc), ASTString("~="), args); } break; - case 172: /* expr: expr "quoted identifier" expr */ + case 172: { vector args; args.push_back((yyvsp[-2].expression)); args.push_back((yyvsp[0].expression)); (yyval.expression)=new Call((yyloc), (yyvsp[-1].sValue), args); @@ -4100,11 +4114,11 @@ yyreduce: } break; - case 173: /* expr: "not" expr */ + case 173: { (yyval.expression)=new UnOp((yyloc), UOT_NOT, (yyvsp[0].expression)); } break; - case 174: /* expr: "+" expr */ + case 174: { if (((yyvsp[0].expression) && (yyvsp[0].expression)->isa()) || ((yyvsp[0].expression) && (yyvsp[0].expression)->isa())) { (yyval.expression) = (yyvsp[0].expression); } else { @@ -4113,7 +4127,7 @@ yyreduce: } break; - case 175: /* expr: "-" expr */ + case 175: { if ((yyvsp[0].expression) && (yyvsp[0].expression)->isa()) { (yyval.expression) = IntLit::a(-(yyvsp[0].expression)->cast()->v()); } else if ((yyvsp[0].expression) && (yyvsp[0].expression)->isa()) { @@ -4124,218 +4138,218 @@ yyreduce: } break; - case 176: /* expr_atom_head: expr_atom_head_nonstring */ + case 176: { (yyval.expression)=(yyvsp[0].expression); } break; - case 177: /* expr_atom_head: string_expr */ + case 177: { (yyval.expression)=(yyvsp[0].expression); } break; - case 178: /* expr_atom_head_nonstring: '(' expr ')' */ + case 178: { (yyval.expression)=(yyvsp[-1].expression); } break; - case 179: /* expr_atom_head_nonstring: '(' expr ')' array_access_tail */ + case 179: { if ((yyvsp[0].expressions2d)) (yyval.expression)=createArrayAccess((yyloc), (yyvsp[-2].expression), *(yyvsp[0].expressions2d)); delete (yyvsp[0].expressions2d); } break; - case 180: /* expr_atom_head_nonstring: '(' expr ')' "^-1" */ + case 180: { (yyval.expression)=new BinOp((yyloc), (yyvsp[-2].expression), BOT_POW, IntLit::a(-1)); } break; - case 181: /* expr_atom_head_nonstring: '(' expr ')' array_access_tail "^-1" */ + case 181: { if ((yyvsp[-1].expressions2d)) (yyval.expression)=new BinOp((yyloc),createArrayAccess((yyloc), (yyvsp[-3].expression), *(yyvsp[-1].expressions2d)), BOT_POW, IntLit::a(-1)); delete (yyvsp[-1].expressions2d); } break; - case 182: /* expr_atom_head_nonstring: "identifier" */ + case 182: { (yyval.expression)=new Id((yyloc), (yyvsp[0].sValue), nullptr); free((yyvsp[0].sValue)); } break; - case 183: /* expr_atom_head_nonstring: "identifier" array_access_tail */ + case 183: { if ((yyvsp[0].expressions2d)) (yyval.expression)=createArrayAccess((yyloc), new Id((yylsp[-1]),(yyvsp[-1].sValue),nullptr), *(yyvsp[0].expressions2d)); free((yyvsp[-1].sValue)); delete (yyvsp[0].expressions2d); } break; - case 184: /* expr_atom_head_nonstring: "identifier" "^-1" */ + case 184: { (yyval.expression)=new BinOp((yyloc),new Id((yyloc), (yyvsp[-1].sValue), nullptr), BOT_POW, IntLit::a(-1)); free((yyvsp[-1].sValue)); } break; - case 185: /* expr_atom_head_nonstring: "identifier" array_access_tail "^-1" */ + case 185: { if ((yyvsp[-1].expressions2d)) (yyval.expression)=new BinOp((yyloc),createArrayAccess((yyloc), new Id((yylsp[-2]),(yyvsp[-2].sValue),nullptr), *(yyvsp[-1].expressions2d)), BOT_POW, IntLit::a(-1)); free((yyvsp[-2].sValue)); delete (yyvsp[-1].expressions2d); } break; - case 186: /* expr_atom_head_nonstring: "_" */ + case 186: { (yyval.expression)=new AnonVar((yyloc)); } break; - case 187: /* expr_atom_head_nonstring: "_" array_access_tail */ + case 187: { if ((yyvsp[0].expressions2d)) (yyval.expression)=createArrayAccess((yyloc), new AnonVar((yyloc)), *(yyvsp[0].expressions2d)); delete (yyvsp[0].expressions2d); } break; - case 188: /* expr_atom_head_nonstring: "_" "^-1" */ + case 188: { (yyval.expression)=new BinOp((yyloc),new AnonVar((yyloc)), BOT_POW, IntLit::a(-1)); } break; - case 189: /* expr_atom_head_nonstring: "_" array_access_tail "^-1" */ + case 189: { if ((yyvsp[-1].expressions2d)) (yyval.expression)=new BinOp((yyloc),createArrayAccess((yyloc), new AnonVar((yyloc)), *(yyvsp[-1].expressions2d)), BOT_POW, IntLit::a(-1)); delete (yyvsp[-1].expressions2d); } break; - case 190: /* expr_atom_head_nonstring: "bool literal" */ + case 190: { (yyval.expression)=constants().boollit(((yyvsp[0].iValue)!=0)); } break; - case 191: /* expr_atom_head_nonstring: "bool literal" "^-1" */ + case 191: { (yyval.expression)=new BinOp((yyloc),constants().boollit(((yyvsp[-1].iValue)!=0)), BOT_POW, IntLit::a(-1)); } break; - case 192: /* expr_atom_head_nonstring: "integer literal" */ + case 192: { (yyval.expression)=IntLit::a((yyvsp[0].iValue)); } break; - case 193: /* expr_atom_head_nonstring: "integer literal" "^-1" */ + case 193: { (yyval.expression)=new BinOp((yyloc),IntLit::a((yyvsp[-1].iValue)), BOT_POW, IntLit::a(-1)); } break; - case 194: /* expr_atom_head_nonstring: "infinity" */ + case 194: { (yyval.expression)=IntLit::a(IntVal::infinity()); } break; - case 195: /* expr_atom_head_nonstring: "infinity" "^-1" */ + case 195: { (yyval.expression)=new BinOp((yyloc),IntLit::a(IntVal::infinity()), BOT_POW, IntLit::a(-1)); } break; - case 196: /* expr_atom_head_nonstring: "float literal" */ + case 196: { (yyval.expression)=FloatLit::a((yyvsp[0].dValue)); } break; - case 197: /* expr_atom_head_nonstring: "float literal" "^-1" */ + case 197: { (yyval.expression)=new BinOp((yyloc),FloatLit::a((yyvsp[-1].dValue)), BOT_POW, IntLit::a(-1)); } break; - case 198: /* expr_atom_head_nonstring: "<>" */ + case 198: { (yyval.expression)=constants().absent; } break; - case 199: /* expr_atom_head_nonstring: "<>" "^-1" */ + case 199: { (yyval.expression)=constants().absent; } break; - case 201: /* expr_atom_head_nonstring: set_literal array_access_tail */ + case 201: { if ((yyvsp[0].expressions2d)) (yyval.expression)=createArrayAccess((yyloc), (yyvsp[-1].expression), *(yyvsp[0].expressions2d)); delete (yyvsp[0].expressions2d); } break; - case 202: /* expr_atom_head_nonstring: set_literal "^-1" */ + case 202: { (yyval.expression) = new BinOp((yyloc),(yyvsp[-1].expression), BOT_POW, IntLit::a(-1)); } break; - case 203: /* expr_atom_head_nonstring: set_literal array_access_tail "^-1" */ + case 203: { if ((yyvsp[-1].expressions2d)) (yyval.expression)=new BinOp((yyloc),createArrayAccess((yyloc), (yyvsp[-2].expression), *(yyvsp[-1].expressions2d)), BOT_POW, IntLit::a(-1)); delete (yyvsp[-1].expressions2d); } break; - case 205: /* expr_atom_head_nonstring: set_comp array_access_tail */ + case 205: { if ((yyvsp[0].expressions2d)) (yyval.expression)=createArrayAccess((yyloc), (yyvsp[-1].expression), *(yyvsp[0].expressions2d)); delete (yyvsp[0].expressions2d); } break; - case 206: /* expr_atom_head_nonstring: set_comp "^-1" */ + case 206: { (yyval.expression) = new BinOp((yyloc),(yyvsp[-1].expression), BOT_POW, IntLit::a(-1)); } break; - case 207: /* expr_atom_head_nonstring: set_comp array_access_tail "^-1" */ + case 207: { if ((yyvsp[-1].expressions2d)) (yyval.expression)=new BinOp((yyloc),createArrayAccess((yyloc), (yyvsp[-2].expression), *(yyvsp[-1].expressions2d)), BOT_POW, IntLit::a(-1)); delete (yyvsp[-1].expressions2d); } break; - case 209: /* expr_atom_head_nonstring: simple_array_literal array_access_tail */ + case 209: { if ((yyvsp[0].expressions2d)) (yyval.expression)=createArrayAccess((yyloc), (yyvsp[-1].expression), *(yyvsp[0].expressions2d)); delete (yyvsp[0].expressions2d); } break; - case 210: /* expr_atom_head_nonstring: simple_array_literal "^-1" */ + case 210: { (yyval.expression) = new BinOp((yyloc),(yyvsp[-1].expression), BOT_POW, IntLit::a(-1)); } break; - case 211: /* expr_atom_head_nonstring: simple_array_literal array_access_tail "^-1" */ + case 211: { if ((yyvsp[-1].expressions2d)) (yyval.expression)=new BinOp((yyloc),createArrayAccess((yyloc), (yyvsp[-2].expression), *(yyvsp[-1].expressions2d)), BOT_POW, IntLit::a(-1)); delete (yyvsp[-1].expressions2d); } break; - case 213: /* expr_atom_head_nonstring: simple_array_literal_2d array_access_tail */ + case 213: { if ((yyvsp[0].expressions2d)) (yyval.expression)=createArrayAccess((yyloc), (yyvsp[-1].expression), *(yyvsp[0].expressions2d)); delete (yyvsp[0].expressions2d); } break; - case 214: /* expr_atom_head_nonstring: simple_array_literal_2d "^-1" */ + case 214: { (yyval.expression) = new BinOp((yyloc),(yyvsp[-1].expression), BOT_POW, IntLit::a(-1)); } break; - case 215: /* expr_atom_head_nonstring: simple_array_literal_2d array_access_tail "^-1" */ + case 215: { if ((yyvsp[-1].expressions2d)) (yyval.expression)=new BinOp((yyloc),createArrayAccess((yyloc), (yyvsp[-2].expression), *(yyvsp[-1].expressions2d)), BOT_POW, IntLit::a(-1)); delete (yyvsp[-1].expressions2d); } break; - case 217: /* expr_atom_head_nonstring: simple_array_comp array_access_tail */ + case 217: { if ((yyvsp[0].expressions2d)) (yyval.expression)=createArrayAccess((yyloc), (yyvsp[-1].expression), *(yyvsp[0].expressions2d)); delete (yyvsp[0].expressions2d); } break; - case 218: /* expr_atom_head_nonstring: simple_array_comp "^-1" */ + case 218: { (yyval.expression) = new BinOp((yyloc),(yyvsp[-1].expression), BOT_POW, IntLit::a(-1)); } break; - case 219: /* expr_atom_head_nonstring: simple_array_comp array_access_tail "^-1" */ + case 219: { if ((yyvsp[-1].expressions2d)) (yyval.expression)=new BinOp((yyloc),createArrayAccess((yyloc), (yyvsp[-2].expression), *(yyvsp[-1].expressions2d)), BOT_POW, IntLit::a(-1)); delete (yyvsp[-1].expressions2d); } break; - case 221: /* expr_atom_head_nonstring: if_then_else_expr array_access_tail */ + case 221: { if ((yyvsp[0].expressions2d)) (yyval.expression)=createArrayAccess((yyloc), (yyvsp[-1].expression), *(yyvsp[0].expressions2d)); delete (yyvsp[0].expressions2d); } break; - case 222: /* expr_atom_head_nonstring: if_then_else_expr "^-1" */ + case 222: { (yyval.expression) = new BinOp((yyloc),(yyvsp[-1].expression), BOT_POW, IntLit::a(-1)); } break; - case 223: /* expr_atom_head_nonstring: if_then_else_expr array_access_tail "^-1" */ + case 223: { if ((yyvsp[-1].expressions2d)) (yyval.expression)=new BinOp((yyloc),createArrayAccess((yyloc), (yyvsp[-2].expression), *(yyvsp[-1].expressions2d)), BOT_POW, IntLit::a(-1)); delete (yyvsp[-1].expressions2d); } break; - case 226: /* expr_atom_head_nonstring: call_expr array_access_tail */ + case 226: { if ((yyvsp[0].expressions2d)) (yyval.expression)=createArrayAccess((yyloc), (yyvsp[-1].expression), *(yyvsp[0].expressions2d)); delete (yyvsp[0].expressions2d); } break; - case 228: /* expr_atom_head_nonstring: call_expr array_access_tail "^-1" */ + case 228: { if ((yyvsp[-1].expressions2d)) (yyval.expression)=createArrayAccess((yyloc), (yyvsp[-2].expression), *(yyvsp[-1].expressions2d)); delete (yyvsp[-1].expressions2d); } break; - case 229: /* string_expr: "string literal" */ + case 229: { (yyval.expression)=new StringLit((yyloc), (yyvsp[0].sValue)); free((yyvsp[0].sValue)); } break; - case 230: /* string_expr: "interpolated string start" string_quote_rest */ + case 230: { (yyval.expression)=new BinOp((yyloc), new StringLit((yyloc), (yyvsp[-1].sValue)), BOT_PLUSPLUS, (yyvsp[0].expression)); free((yyvsp[-1].sValue)); } break; - case 231: /* string_quote_rest: expr_list_head "interpolated string end" */ + case 231: { if ((yyvsp[-1].expressions1d)) (yyval.expression)=new BinOp((yyloc), new Call((yyloc), ASTString("format"), *(yyvsp[-1].expressions1d)), BOT_PLUSPLUS, new StringLit((yyloc),(yyvsp[0].sValue))); free((yyvsp[0].sValue)); delete (yyvsp[-1].expressions1d); } break; - case 232: /* string_quote_rest: expr_list_head "interpolated string middle" string_quote_rest */ + case 232: { if ((yyvsp[-2].expressions1d)) (yyval.expression)=new BinOp((yyloc), new Call((yyloc), ASTString("format"), *(yyvsp[-2].expressions1d)), BOT_PLUSPLUS, new BinOp((yyloc), new StringLit((yyloc),(yyvsp[-1].sValue)), BOT_PLUSPLUS, (yyvsp[0].expression))); free((yyvsp[-1].sValue)); @@ -4343,7 +4357,7 @@ yyreduce: } break; - case 233: /* array_access_tail: "[" array_access_expr_list "]" */ + case 233: { (yyval.expressions2d)=new std::vector >(); if ((yyvsp[-1].expressions1d)) { (yyval.expressions2d)->push_back(*(yyvsp[-1].expressions1d)); @@ -4352,7 +4366,7 @@ yyreduce: } break; - case 234: /* array_access_tail: array_access_tail "[" array_access_expr_list "]" */ + case 234: { (yyval.expressions2d)=(yyvsp[-3].expressions2d); if ((yyval.expressions2d) && (yyvsp[-1].expressions1d)) { (yyval.expressions2d)->push_back(*(yyvsp[-1].expressions1d)); @@ -4361,34 +4375,34 @@ yyreduce: } break; - case 235: /* set_literal: '{' '}' */ + case 235: { (yyval.expression) = new SetLit((yyloc), std::vector()); } break; - case 236: /* set_literal: '{' expr_list '}' */ + case 236: { if ((yyvsp[-1].expressions1d)) (yyval.expression) = new SetLit((yyloc), *(yyvsp[-1].expressions1d)); delete (yyvsp[-1].expressions1d); } break; - case 237: /* set_comp: '{' expr '|' comp_tail '}' */ + case 237: { if ((yyvsp[-1].generatorsPointer)) (yyval.expression) = new Comprehension((yyloc), (yyvsp[-3].expression), *(yyvsp[-1].generatorsPointer), true); delete (yyvsp[-1].generatorsPointer); } break; - case 238: /* comp_tail: generator_list */ + case 238: { if ((yyvsp[0].generators)) (yyval.generatorsPointer)=new Generators; (yyval.generatorsPointer)->g = *(yyvsp[0].generators); delete (yyvsp[0].generators); } break; - case 240: /* generator_list_head: generator */ + case 240: { (yyval.generators)=new std::vector; if ((yyvsp[0].generator)) (yyval.generators)->push_back(*(yyvsp[0].generator)); delete (yyvsp[0].generator); } break; - case 241: /* generator_list_head: generator_eq */ + case 241: { (yyval.generators)=new std::vector; if ((yyvsp[0].generator)) (yyval.generators)->push_back(*(yyvsp[0].generator)); delete (yyvsp[0].generator); } break; - case 242: /* generator_list_head: generator_eq "where" expr */ + case 242: { (yyval.generators)=new std::vector; if ((yyvsp[-2].generator)) (yyval.generators)->push_back(*(yyvsp[-2].generator)); if ((yyvsp[-2].generator) && (yyvsp[0].expression)) (yyval.generators)->push_back(Generator((yyval.generators)->size(),(yyvsp[0].expression))); @@ -4396,15 +4410,15 @@ yyreduce: } break; - case 243: /* generator_list_head: generator_list_head ',' generator */ + case 243: { (yyval.generators)=(yyvsp[-2].generators); if ((yyval.generators) && (yyvsp[0].generator)) (yyval.generators)->push_back(*(yyvsp[0].generator)); delete (yyvsp[0].generator); } break; - case 244: /* generator_list_head: generator_list_head ',' generator_eq */ + case 244: { (yyval.generators)=(yyvsp[-2].generators); if ((yyval.generators) && (yyvsp[0].generator)) (yyval.generators)->push_back(*(yyvsp[0].generator)); delete (yyvsp[0].generator); } break; - case 245: /* generator_list_head: generator_list_head ',' generator_eq "where" expr */ + case 245: { (yyval.generators)=(yyvsp[-4].generators); if ((yyval.generators) && (yyvsp[-2].generator)) (yyval.generators)->push_back(*(yyvsp[-2].generator)); if ((yyval.generators) && (yyvsp[-2].generator) && (yyvsp[0].expression)) (yyval.generators)->push_back(Generator((yyval.generators)->size(),(yyvsp[0].expression))); @@ -4412,39 +4426,39 @@ yyreduce: } break; - case 246: /* generator: id_list "in" expr */ + case 246: { if ((yyvsp[-2].strings) && (yyvsp[0].expression)) (yyval.generator)=new Generator(*(yyvsp[-2].strings),(yyvsp[0].expression),nullptr); else (yyval.generator)=nullptr; delete (yyvsp[-2].strings); } break; - case 247: /* generator: id_list "in" expr "where" expr */ + case 247: { if ((yyvsp[-4].strings) && (yyvsp[-2].expression)) (yyval.generator)=new Generator(*(yyvsp[-4].strings),(yyvsp[-2].expression),(yyvsp[0].expression)); else (yyval.generator)=nullptr; delete (yyvsp[-4].strings); } break; - case 248: /* generator_eq: "identifier" "=" expr */ + case 248: { if ((yyvsp[0].expression)) (yyval.generator)=new Generator({(yyvsp[-2].sValue)},nullptr,(yyvsp[0].expression)); else (yyval.generator)=nullptr; free((yyvsp[-2].sValue)); } break; - case 250: /* id_list_head: "identifier" */ + case 250: { (yyval.strings)=new std::vector; (yyval.strings)->push_back((yyvsp[0].sValue)); free((yyvsp[0].sValue)); } break; - case 251: /* id_list_head: id_list_head ',' "identifier" */ + case 251: { (yyval.strings)=(yyvsp[-2].strings); if ((yyval.strings) && (yyvsp[0].sValue)) (yyval.strings)->push_back((yyvsp[0].sValue)); free((yyvsp[0].sValue)); } break; - case 252: /* simple_array_literal: "[" "]" */ + case 252: { (yyval.expression)=new ArrayLit((yyloc), std::vector()); } break; - case 253: /* simple_array_literal: "[" expr_list "]" */ + case 253: { if ((yyvsp[-1].expressions1d)) (yyval.expression)=new ArrayLit((yyloc), *(yyvsp[-1].expressions1d)); delete (yyvsp[-1].expressions1d); } break; - case 254: /* simple_array_literal_2d: "[|" "|]" */ + case 254: { (yyval.expression)=new ArrayLit((yyloc), std::vector >()); } break; - case 255: /* simple_array_literal_2d: "[|" simple_array_literal_2d_list "|]" */ + case 255: { if ((yyvsp[-1].expressions2d)) { (yyval.expression)=new ArrayLit((yyloc), *(yyvsp[-1].expressions2d)); for (unsigned int i=1; i<(yyvsp[-1].expressions2d)->size(); i++) @@ -4457,7 +4471,7 @@ yyreduce: } break; - case 256: /* simple_array_literal_2d: "[|" simple_array_literal_2d_list '|' "|]" */ + case 256: { if ((yyvsp[-2].expressions2d)) { (yyval.expression)=new ArrayLit((yyloc), *(yyvsp[-2].expressions2d)); for (unsigned int i=1; i<(yyvsp[-2].expressions2d)->size(); i++) @@ -4470,7 +4484,7 @@ yyreduce: } break; - case 257: /* simple_array_literal_2d: "[|" simple_array_literal_3d_list "|]" */ + case 257: { if ((yyvsp[-1].expressions3d)) { std::vector > dims(3); @@ -4510,43 +4524,43 @@ yyreduce: } break; - case 258: /* simple_array_literal_3d_list: '|' '|' */ + case 258: { (yyval.expressions3d)=new std::vector > >; } break; - case 259: /* simple_array_literal_3d_list: '|' simple_array_literal_2d_list '|' */ + case 259: { (yyval.expressions3d)=new std::vector > >; if ((yyvsp[-1].expressions2d)) (yyval.expressions3d)->push_back(*(yyvsp[-1].expressions2d)); delete (yyvsp[-1].expressions2d); } break; - case 260: /* simple_array_literal_3d_list: simple_array_literal_3d_list ',' '|' simple_array_literal_2d_list '|' */ + case 260: { (yyval.expressions3d)=(yyvsp[-4].expressions3d); if ((yyval.expressions3d) && (yyvsp[-1].expressions2d)) (yyval.expressions3d)->push_back(*(yyvsp[-1].expressions2d)); delete (yyvsp[-1].expressions2d); } break; - case 261: /* simple_array_literal_2d_list: expr_list */ + case 261: { (yyval.expressions2d)=new std::vector >; if ((yyvsp[0].expressions1d)) (yyval.expressions2d)->push_back(*(yyvsp[0].expressions1d)); delete (yyvsp[0].expressions1d); } break; - case 262: /* simple_array_literal_2d_list: simple_array_literal_2d_list '|' expr_list */ + case 262: { (yyval.expressions2d)=(yyvsp[-2].expressions2d); if ((yyval.expressions2d) && (yyvsp[0].expressions1d)) (yyval.expressions2d)->push_back(*(yyvsp[0].expressions1d)); delete (yyvsp[0].expressions1d); } break; - case 263: /* simple_array_comp: "[" expr '|' comp_tail "]" */ + case 263: { if ((yyvsp[-1].generatorsPointer)) (yyval.expression)=new Comprehension((yyloc), (yyvsp[-3].expression), *(yyvsp[-1].generatorsPointer), false); delete (yyvsp[-1].generatorsPointer); } break; - case 264: /* if_then_else_expr: "if" expr "then" expr "endif" */ + case 264: { std::vector iexps; iexps.push_back((yyvsp[-3].expression)); @@ -4555,7 +4569,7 @@ yyreduce: } break; - case 265: /* if_then_else_expr: "if" expr "then" expr elseif_list "else" expr "endif" */ + case 265: { std::vector iexps; iexps.push_back((yyvsp[-6].expression)); @@ -4571,127 +4585,127 @@ yyreduce: } break; - case 266: /* elseif_list: %empty */ + case 266: { (yyval.expressions1d)=new std::vector; } break; - case 267: /* elseif_list: elseif_list "elseif" expr "then" expr */ + case 267: { (yyval.expressions1d)=(yyvsp[-4].expressions1d); if ((yyval.expressions1d) && (yyvsp[-2].expression) && (yyvsp[0].expression)) { (yyval.expressions1d)->push_back((yyvsp[-2].expression)); (yyval.expressions1d)->push_back((yyvsp[0].expression)); } } break; - case 268: /* quoted_op: "'<->'" */ + case 268: { (yyval.iValue)=BOT_EQUIV; } break; - case 269: /* quoted_op: "'->'" */ + case 269: { (yyval.iValue)=BOT_IMPL; } break; - case 270: /* quoted_op: "'<-'" */ + case 270: { (yyval.iValue)=BOT_RIMPL; } break; - case 271: /* quoted_op: "'\\/'" */ + case 271: { (yyval.iValue)=BOT_OR; } break; - case 272: /* quoted_op: "'xor'" */ + case 272: { (yyval.iValue)=BOT_XOR; } break; - case 273: /* quoted_op: "'/\\'" */ + case 273: { (yyval.iValue)=BOT_AND; } break; - case 274: /* quoted_op: "'<'" */ + case 274: { (yyval.iValue)=BOT_LE; } break; - case 275: /* quoted_op: "'>'" */ + case 275: { (yyval.iValue)=BOT_GR; } break; - case 276: /* quoted_op: "'<='" */ + case 276: { (yyval.iValue)=BOT_LQ; } break; - case 277: /* quoted_op: "'>='" */ + case 277: { (yyval.iValue)=BOT_GQ; } break; - case 278: /* quoted_op: "'='" */ + case 278: { (yyval.iValue)=BOT_EQ; } break; - case 279: /* quoted_op: "'!='" */ + case 279: { (yyval.iValue)=BOT_NQ; } break; - case 280: /* quoted_op: "'in'" */ + case 280: { (yyval.iValue)=BOT_IN; } break; - case 281: /* quoted_op: "'subset'" */ + case 281: { (yyval.iValue)=BOT_SUBSET; } break; - case 282: /* quoted_op: "'superset'" */ + case 282: { (yyval.iValue)=BOT_SUPERSET; } break; - case 283: /* quoted_op: "'union'" */ + case 283: { (yyval.iValue)=BOT_UNION; } break; - case 284: /* quoted_op: "'diff'" */ + case 284: { (yyval.iValue)=BOT_DIFF; } break; - case 285: /* quoted_op: "'symdiff'" */ + case 285: { (yyval.iValue)=BOT_SYMDIFF; } break; - case 286: /* quoted_op: "'+'" */ + case 286: { (yyval.iValue)=BOT_PLUS; } break; - case 287: /* quoted_op: "'-'" */ + case 287: { (yyval.iValue)=BOT_MINUS; } break; - case 288: /* quoted_op: "'*'" */ + case 288: { (yyval.iValue)=BOT_MULT; } break; - case 289: /* quoted_op: "'^'" */ + case 289: { (yyval.iValue)=BOT_POW; } break; - case 290: /* quoted_op: "'/'" */ + case 290: { (yyval.iValue)=BOT_DIV; } break; - case 291: /* quoted_op: "'div'" */ + case 291: { (yyval.iValue)=BOT_IDIV; } break; - case 292: /* quoted_op: "'mod'" */ + case 292: { (yyval.iValue)=BOT_MOD; } break; - case 293: /* quoted_op: "'intersect'" */ + case 293: { (yyval.iValue)=BOT_INTERSECT; } break; - case 294: /* quoted_op: "'++'" */ + case 294: { (yyval.iValue)=BOT_PLUSPLUS; } break; - case 295: /* quoted_op: "'not'" */ + case 295: { (yyval.iValue)=-1; } break; - case 296: /* quoted_op_call: quoted_op '(' expr ',' expr ')' */ + case 296: { if ((yyvsp[-5].iValue)==-1) { (yyval.expression)=nullptr; yyerror(&(yylsp[-3]), parm, "syntax error, unary operator with two arguments"); @@ -4701,7 +4715,7 @@ yyreduce: } break; - case 297: /* quoted_op_call: quoted_op '(' expr ')' */ + case 297: { int uot=-1; switch ((yyvsp[-3].iValue)) { case -1: @@ -4733,15 +4747,15 @@ yyreduce: } break; - case 298: /* call_expr: "identifier" '(' ')' */ + case 298: { (yyval.expression)=new Call((yyloc), (yyvsp[-2].sValue), std::vector()); free((yyvsp[-2].sValue)); } break; - case 299: /* call_expr: "identifier" "^-1" '(' ')' */ + case 299: { (yyval.expression)=new Call((yyloc), std::string((yyvsp[-3].sValue))+"⁻¹", std::vector()); free((yyvsp[-3].sValue)); } break; - case 301: /* call_expr: "identifier" '(' comp_or_expr ')' */ + case 301: { if ((yyvsp[-1].expressionPairs)!=nullptr) { bool hadWhere = false; @@ -4763,7 +4777,7 @@ yyreduce: } break; - case 302: /* call_expr: "identifier" '(' comp_or_expr ')' '(' expr ')' */ + case 302: { vector gens; vector ids; @@ -4819,7 +4833,7 @@ yyreduce: } break; - case 303: /* call_expr: "identifier" "^-1" '(' comp_or_expr ')' */ + case 303: { if ((yyvsp[-1].expressionPairs)!=nullptr) { bool hadWhere = false; @@ -4841,7 +4855,7 @@ yyreduce: } break; - case 304: /* call_expr: "identifier" "^-1" '(' comp_or_expr ')' '(' expr ')' */ + case 304: { vector gens; vector ids; @@ -4897,7 +4911,7 @@ yyreduce: } break; - case 306: /* comp_or_expr_head: expr */ + case 306: { (yyval.expressionPairs)=new vector >; if ((yyvsp[0].expression)) { (yyval.expressionPairs)->push_back(pair((yyvsp[0].expression),nullptr)); @@ -4905,7 +4919,7 @@ yyreduce: } break; - case 307: /* comp_or_expr_head: expr "where" expr */ + case 307: { (yyval.expressionPairs)=new vector >; if ((yyvsp[-2].expression) && (yyvsp[0].expression)) { (yyval.expressionPairs)->push_back(pair((yyvsp[-2].expression),(yyvsp[0].expression))); @@ -4913,15 +4927,15 @@ yyreduce: } break; - case 308: /* comp_or_expr_head: comp_or_expr_head ',' expr */ + case 308: { (yyval.expressionPairs)=(yyvsp[-2].expressionPairs); if ((yyval.expressionPairs) && (yyvsp[0].expression)) (yyval.expressionPairs)->push_back(pair((yyvsp[0].expression),nullptr)); } break; - case 309: /* comp_or_expr_head: comp_or_expr_head ',' expr "where" expr */ + case 309: { (yyval.expressionPairs)=(yyvsp[-4].expressionPairs); if ((yyval.expressionPairs) && (yyvsp[-2].expression) && (yyvsp[0].expression)) (yyval.expressionPairs)->push_back(pair((yyvsp[-2].expression),(yyvsp[0].expression))); } break; - case 310: /* let_expr: "let" '{' let_vardecl_item_list '}' "in" expr */ + case 310: { if ((yyvsp[-3].expressions1d) && (yyvsp[0].expression)) { (yyval.expression)=new Let((yyloc), *(yyvsp[-3].expressions1d), (yyvsp[0].expression)); delete (yyvsp[-3].expressions1d); } else { @@ -4930,7 +4944,7 @@ yyreduce: } break; - case 311: /* let_expr: "let" '{' let_vardecl_item_list comma_or_semi '}' "in" expr */ + case 311: { if ((yyvsp[-4].expressions1d) && (yyvsp[0].expression)) { (yyval.expression)=new Let((yyloc), *(yyvsp[-4].expressions1d), (yyvsp[0].expression)); delete (yyvsp[-4].expressions1d); } else { @@ -4939,11 +4953,11 @@ yyreduce: } break; - case 312: /* let_vardecl_item_list: let_vardecl_item */ + case 312: { (yyval.expressions1d)=new vector; (yyval.expressions1d)->push_back((yyvsp[0].vardeclexpr)); } break; - case 313: /* let_vardecl_item_list: constraint_item */ + case 313: { (yyval.expressions1d)=new vector; if ((yyvsp[0].item)) { ConstraintI* ce = (yyvsp[0].item)->cast(); @@ -4953,11 +4967,11 @@ yyreduce: } break; - case 314: /* let_vardecl_item_list: let_vardecl_item_list comma_or_semi let_vardecl_item */ + case 314: { (yyval.expressions1d)=(yyvsp[-2].expressions1d); if ((yyval.expressions1d) && (yyvsp[0].vardeclexpr)) (yyval.expressions1d)->push_back((yyvsp[0].vardeclexpr)); } break; - case 315: /* let_vardecl_item_list: let_vardecl_item_list comma_or_semi constraint_item */ + case 315: { (yyval.expressions1d)=(yyvsp[-2].expressions1d); if ((yyval.expressions1d) && (yyvsp[0].item)) { ConstraintI* ce = (yyvsp[0].item)->cast(); @@ -4967,7 +4981,7 @@ yyreduce: } break; - case 318: /* let_vardecl_item: ti_expr_and_id annotations */ + case 318: { (yyval.vardeclexpr) = (yyvsp[-1].vardeclexpr); if ((yyval.vardeclexpr)) (yyval.vardeclexpr)->toplevel(false); if ((yyval.vardeclexpr) && (yyvsp[0].expressions1d)) (yyval.vardeclexpr)->addAnnotations(*(yyvsp[0].expressions1d)); @@ -4975,7 +4989,7 @@ yyreduce: } break; - case 319: /* let_vardecl_item: ti_expr_and_id annotations "=" expr */ + case 319: { if ((yyvsp[-3].vardeclexpr)) (yyvsp[-3].vardeclexpr)->e((yyvsp[0].expression)); (yyval.vardeclexpr) = (yyvsp[-3].vardeclexpr); if ((yyval.vardeclexpr)) (yyval.vardeclexpr)->loc((yyloc)); @@ -4985,149 +4999,149 @@ yyreduce: } break; - case 320: /* annotations: %empty */ + case 320: { (yyval.expressions1d)=nullptr; } break; - case 322: /* annotation_expr: expr_atom_head_nonstring */ + case 322: { (yyval.expression) = (yyvsp[0].expression); } break; - case 323: /* annotation_expr: string_expr */ + case 323: { (yyval.expression) = new Call((yylsp[0]), ASTString("mzn_expression_name"), {(yyvsp[0].expression)}); } break; - case 324: /* ne_annotations: "::" annotation_expr */ + case 324: { (yyval.expressions1d)=new std::vector(1); (*(yyval.expressions1d))[0] = (yyvsp[0].expression); } break; - case 325: /* ne_annotations: ne_annotations "::" annotation_expr */ + case 325: { (yyval.expressions1d)=(yyvsp[-2].expressions1d); if ((yyval.expressions1d)) (yyval.expressions1d)->push_back((yyvsp[0].expression)); } break; - case 326: /* id_or_quoted_op: "identifier" */ + case 326: { (yyval.sValue)=(yyvsp[0].sValue); } break; - case 327: /* id_or_quoted_op: "identifier" "^-1" */ + case 327: { (yyval.sValue)=strdup((std::string((yyvsp[-1].sValue))+"⁻¹").c_str()); } break; - case 328: /* id_or_quoted_op: "'<->'" */ + case 328: { (yyval.sValue)=strdup("'<->'"); } break; - case 329: /* id_or_quoted_op: "'->'" */ + case 329: { (yyval.sValue)=strdup("'->'"); } break; - case 330: /* id_or_quoted_op: "'<-'" */ + case 330: { (yyval.sValue)=strdup("'<-'"); } break; - case 331: /* id_or_quoted_op: "'\\/'" */ + case 331: { (yyval.sValue)=strdup("'\\/'"); } break; - case 332: /* id_or_quoted_op: "'xor'" */ + case 332: { (yyval.sValue)=strdup("'xor'"); } break; - case 333: /* id_or_quoted_op: "'/\\'" */ + case 333: { (yyval.sValue)=strdup("'/\\'"); } break; - case 334: /* id_or_quoted_op: "'<'" */ + case 334: { (yyval.sValue)=strdup("'<'"); } break; - case 335: /* id_or_quoted_op: "'>'" */ + case 335: { (yyval.sValue)=strdup("'>'"); } break; - case 336: /* id_or_quoted_op: "'<='" */ + case 336: { (yyval.sValue)=strdup("'<='"); } break; - case 337: /* id_or_quoted_op: "'>='" */ + case 337: { (yyval.sValue)=strdup("'>='"); } break; - case 338: /* id_or_quoted_op: "'='" */ + case 338: { (yyval.sValue)=strdup("'='"); } break; - case 339: /* id_or_quoted_op: "'!='" */ + case 339: { (yyval.sValue)=strdup("'!='"); } break; - case 340: /* id_or_quoted_op: "'in'" */ + case 340: { (yyval.sValue)=strdup("'in'"); } break; - case 341: /* id_or_quoted_op: "'subset'" */ + case 341: { (yyval.sValue)=strdup("'subset'"); } break; - case 342: /* id_or_quoted_op: "'superset'" */ + case 342: { (yyval.sValue)=strdup("'superset'"); } break; - case 343: /* id_or_quoted_op: "'union'" */ + case 343: { (yyval.sValue)=strdup("'union'"); } break; - case 344: /* id_or_quoted_op: "'diff'" */ + case 344: { (yyval.sValue)=strdup("'diff'"); } break; - case 345: /* id_or_quoted_op: "'symdiff'" */ + case 345: { (yyval.sValue)=strdup("'symdiff'"); } break; - case 346: /* id_or_quoted_op: "'..'" */ + case 346: { (yyval.sValue)=strdup("'..'"); } break; - case 347: /* id_or_quoted_op: "'+'" */ + case 347: { (yyval.sValue)=strdup("'+'"); } break; - case 348: /* id_or_quoted_op: "'-'" */ + case 348: { (yyval.sValue)=strdup("'-'"); } break; - case 349: /* id_or_quoted_op: "'*'" */ + case 349: { (yyval.sValue)=strdup("'*'"); } break; - case 350: /* id_or_quoted_op: "'^'" */ + case 350: { (yyval.sValue)=strdup("'^'"); } break; - case 351: /* id_or_quoted_op: "'/'" */ + case 351: { (yyval.sValue)=strdup("'/'"); } break; - case 352: /* id_or_quoted_op: "'div'" */ + case 352: { (yyval.sValue)=strdup("'div'"); } break; - case 353: /* id_or_quoted_op: "'mod'" */ + case 353: { (yyval.sValue)=strdup("'mod'"); } break; - case 354: /* id_or_quoted_op: "'intersect'" */ + case 354: { (yyval.sValue)=strdup("'intersect'"); } break; - case 355: /* id_or_quoted_op: "'not'" */ + case 355: { (yyval.sValue)=strdup("'not'"); } break; - case 356: /* id_or_quoted_op: "'++'" */ + case 356: { (yyval.sValue)=strdup("'++'"); } break; @@ -5326,13 +5340,13 @@ yyabortlab: yyexhaustedlab: yyerror (&yylloc, parm, YY_("memory exhausted")); yyresult = 2; - goto yyreturn; + /* Fall through. */ #endif -/*-------------------------------------------------------. -| yyreturn -- parsing is finished, clean up and return. | -`-------------------------------------------------------*/ +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { diff --git a/lib/chain_compressor.cpp b/lib/chain_compressor.cpp index 77932e5..9e0c87c 100644 --- a/lib/chain_compressor.cpp +++ b/lib/chain_compressor.cpp @@ -64,10 +64,8 @@ bool ImpCompressor::trackItem(Item* i) { auto* positive = c->arg(0)->cast(); auto* negative = c->arg(1)->cast(); if (positive->length() == 1 && negative->length() == 1) { - auto* var = (*negative)[0]->dynamicCast(); - if (var != nullptr) { - storeItem(var->decl(), i); - } + auto* var = (*negative)[0]->cast(); + storeItem(var->decl(), i); return true; } } else if (c->id() == "mzn_reverse_map_var") { @@ -77,11 +75,9 @@ bool ImpCompressor::trackItem(Item* i) { return true; // pred_imp(..., b); i.e. b -> pred(...) } else if (c->id().endsWith("_imp")) { - auto* control = c->arg(c->argCount() - 1)->dynamicCast(); - if (control != nullptr) { - assert(control->type().isvarbool()); - storeItem(control->decl(), i); - } + auto* control = c->arg(c->argCount() - 1)->cast(); + assert(control->type().isvarbool()); + storeItem(control->decl(), i); return true; } } @@ -125,42 +121,40 @@ void ImpCompressor::compress() { auto* c = ci->e()->cast(); if (c->id() == constants().ids.clause) { auto* positive = c->arg(0)->cast(); - auto* var = (*positive)[0]->dynamicCast(); - if (var != nullptr) { - bool output_var = var->decl()->ann().contains(constants().ann.output_var); - auto usages = _env.varOccurrences.usages(var->decl()); - output_var = output_var || usages.second; - int occurrences = usages.first; - unsigned long lhs_occurences = count(var->decl()); + auto* var = (*positive)[0]->cast(); + bool output_var = var->decl()->ann().contains(constants().ann.output_var); + auto usages = _env.varOccurrences.usages(var->decl()); + output_var = output_var || usages.second; + int occurrences = usages.first; + unsigned long lhs_occurences = count(var->decl()); - // Compress if: - // - There is one occurrence on the RHS of a clause and the others are on the LHS of a - // clause - // - There is one occurrence on the RHS of a clause, that Id is a reified forall that has - // no other occurrences - // - There is one occurrence on the RHS of a clause, that Id is a reification in a - // positive context, and all other occurrences are on the LHS of a clause - bool compress = !output_var && lhs_occurences > 0; - if ((var->decl()->e() != nullptr) && (var->decl()->e()->dynamicCast() != nullptr)) { - auto* call = var->decl()->e()->cast(); - if (call->id() == constants().ids.forall) { - compress = compress && (occurrences == 1 && lhs_occurences == 1); - } else { - compress = compress && (occurrences == lhs_occurences); - } + // Compress if: + // - There is one occurrence on the RHS of a clause and the others are on the LHS of a + // clause + // - There is one occurrence on the RHS of a clause, that Id is a reified forall that has no + // other occurrences + // - There is one occurrence on the RHS of a clause, that Id is a reification in a positive + // context, and all other occurrences are on the LHS of a clause + bool compress = !output_var && lhs_occurences > 0; + if ((var->decl()->e() != nullptr) && (var->decl()->e()->dynamicCast() != nullptr)) { + auto* call = var->decl()->e()->cast(); + if (call->id() == constants().ids.forall) { + compress = compress && (occurrences == 1 && lhs_occurences == 1); } else { - compress = compress && (occurrences == lhs_occurences + 1); + compress = compress && (occurrences == lhs_occurences); } - if (compress) { - rhs = var->decl(); - auto* negative = c->arg(1)->cast(); - lhs = (*negative)[0]->isa() ? (*negative)[0]->cast()->decl() : nullptr; - if (lhs == rhs) { - continue; - } - } - // TODO: Detect equivalences for output variables. + } else { + compress = compress && (occurrences == lhs_occurences + 1); } + if (compress) { + rhs = var->decl(); + auto* negative = c->arg(1)->cast(); + lhs = (*negative)[0]->cast()->decl(); + if (lhs == rhs) { + continue; + } + } + // TODO: Detect equivalences for output variables. } } @@ -195,9 +189,8 @@ bool ImpCompressor::compressItem(Item* i, VarDecl* newLHS) { // Given (x -> y) /\ (y -> z), produce x -> z if (c->id() == constants().ids.clause) { auto* positive = c->arg(0)->cast(); - VarDecl* positiveDecl = - (*positive)[0]->isa() ? (*positive)[0]->cast()->decl() : nullptr; - if (positiveDecl != newLHS) { + auto* rhs = (*positive)[0]->cast(); + if (rhs->decl() != newLHS) { ConstraintI* nci = constructClause(positive, newLHS->id()); _boolConstraints.push_back(addItem(nci)); } @@ -219,9 +212,9 @@ bool ImpCompressor::compressItem(Item* i, VarDecl* newLHS) { if (c->id() == constants().ids.forall) { auto* exprs = c->arg(0)->cast(); for (int j = 0; j < exprs->size(); ++j) { - VarDecl* rhsDecl = (*exprs)[j]->isa() ? (*exprs)[j]->cast()->decl() : nullptr; - if (rhsDecl != newLHS) { - ConstraintI* nci = constructClause((*exprs)[j], newLHS->id()); + auto* rhs = (*exprs)[j]->cast(); + if (rhs->decl() != newLHS) { + ConstraintI* nci = constructClause(rhs, newLHS->id()); _boolConstraints.push_back(addItem(nci)); } } @@ -260,10 +253,8 @@ ConstraintI* ImpCompressor::constructClause(Expression* pos, Expression* neg) { args[1]->type(Type::varbool(1)); } // NEVER CREATE (a -> a) - assert(!(*args[0]->cast())[0]->isa() || - !(*args[1]->cast())[0]->isa() || - (*args[0]->cast())[0]->cast()->decl() != - (*args[1]->cast())[0]->cast()->decl()); + assert((*args[0]->dynamicCast())[0]->dynamicCast()->decl() != + (*args[1]->dynamicCast())[0]->dynamicCast()->decl()); auto* nc = new Call(MiniZinc::Location().introduce(), constants().ids.clause, args); nc->type(Type::varbool()); nc->decl(_env.model->matchFn(_env, nc, false)); diff --git a/lib/eval_par.cpp b/lib/eval_par.cpp index 042722a..e694390 100644 --- a/lib/eval_par.cpp +++ b/lib/eval_par.cpp @@ -103,21 +103,15 @@ bool EvalBase::evalBoolCV(EnvI& env, Expression* e) { return eval_bool(env, e); }; -KeepAlive EvalBase::flattenCV(EnvI& env, Expression* e) { - GCLock lock; - Ctx ctx; - ctx.i = C_MIX; - ctx.b = (e->type().bt() == Type::BT_BOOL) ? C_MIX : C_ROOT; - EE ee = flat_exp(env, ctx, e, nullptr, constants().varTrue); - return ee.r; -} - class EvalIntLit : public EvalBase { public: typedef IntLit* Val; typedef Expression* ArrayVal; static IntLit* e(EnvI& env, Expression* e) { return IntLit::a(eval_int(env, e)); } static Expression* exp(IntLit* e) { return e; } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalIntVal : public EvalBase { public: @@ -134,6 +128,9 @@ public: } } } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalFloatVal : public EvalBase { public: @@ -150,6 +147,9 @@ public: } } } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalFloatLit : public EvalBase { public: @@ -157,6 +157,9 @@ public: typedef Expression* ArrayVal; static FloatLit* e(EnvI& env, Expression* e) { return FloatLit::a(eval_float(env, e)); } static Expression* exp(Expression* e) { return e; } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalString : public EvalBase { public: @@ -165,6 +168,9 @@ public: static std::string e(EnvI& env, Expression* e) { return eval_string(env, e); } static Expression* exp(const std::string& e) { return new StringLit(Location(), e); } static void checkRetVal(EnvI& env, const Val& v, FunctionI* fi) {} + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalStringLit : public EvalBase { public: @@ -174,6 +180,9 @@ public: return new StringLit(Location(), eval_string(env, e)); } static Expression* exp(Expression* e) { return e; } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalBoolLit : public EvalBase { public: @@ -181,6 +190,9 @@ public: typedef Expression* ArrayVal; static BoolLit* e(EnvI& env, Expression* e) { return constants().boollit(eval_bool(env, e)); } static Expression* exp(Expression* e) { return e; } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalBoolVal : public EvalBase { public: @@ -188,6 +200,9 @@ public: static bool e(EnvI& env, Expression* e) { return eval_bool(env, e); } static Expression* exp(bool e) { return constants().boollit(e); } static void checkRetVal(EnvI& env, Val v, FunctionI* fi) {} + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalArrayLit : public EvalBase { public: @@ -195,6 +210,9 @@ public: typedef Expression* ArrayVal; static ArrayLit* e(EnvI& env, Expression* e) { return eval_array_lit(env, e); } static Expression* exp(Expression* e) { return e; } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalArrayLitCopy : public EvalBase { public: @@ -273,6 +291,9 @@ public: } } } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalIntSet : public EvalBase { public: @@ -290,6 +311,9 @@ public: } } } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalFloatSet : public EvalBase { public: @@ -307,6 +331,9 @@ public: } } } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalBoolSet : public EvalBase { public: @@ -318,6 +345,9 @@ public: return sl; } static void checkRetVal(EnvI& env, Val v, FunctionI* fi) {} + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalSetLit : public EvalBase { public: @@ -325,6 +355,9 @@ public: typedef Expression* ArrayVal; static SetLit* e(EnvI& env, Expression* e) { return eval_set_lit(env, e); } static Expression* exp(Expression* e) { return e; } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalFloatSetLit : public EvalBase { public: @@ -332,6 +365,9 @@ public: typedef Expression* ArrayVal; static SetLit* e(EnvI& env, Expression* e) { return new SetLit(e->loc(), eval_floatset(env, e)); } static Expression* exp(Expression* e) { return e; } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalBoolSetLit : public EvalBase { public: @@ -343,6 +379,9 @@ public: return sl; } static Expression* exp(Expression* e) { return e; } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalCopy : public EvalBase { public: @@ -350,6 +389,9 @@ public: typedef Expression* ArrayVal; static Expression* e(EnvI& env, Expression* e) { return copy(env, e, true); } static Expression* exp(Expression* e) { return e; } + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; class EvalPar : public EvalBase { public: @@ -358,6 +400,9 @@ public: static Expression* e(EnvI& env, Expression* e) { return eval_par(env, e); } static Expression* exp(Expression* e) { return e; } static void checkRetVal(EnvI& env, Val v, FunctionI* fi) {} + static Expression* flatten(EnvI& /*env*/, Expression* /*e*/) { + throw InternalError("evaluating var assignment generator inside par expression not supported"); + } }; void check_dom(EnvI& env, Id* arg, IntSetVal* dom, Expression* e) { @@ -1199,9 +1244,7 @@ bool eval_bool(EnvI& env, Expression* e) { return false; } } else if (bo->op() == BOT_EQ && lhs->type().isAnn()) { - // follow ann id to value, since there might be indirection (e.g. func argument, see - // test_equality_of_indirect_annotations.mzn) - return Expression::equal(follow_id_to_value(lhs), follow_id_to_value(rhs)); + return Expression::equal(lhs, rhs); } else if (bo->op() == BOT_EQ && lhs->type().dim() > 0 && rhs->type().dim() > 0) { try { ArrayLit* al0 = eval_array_lit(env, lhs); diff --git a/lib/flatten.cpp b/lib/flatten.cpp index da50c2b..4df7fdd 100644 --- a/lib/flatten.cpp +++ b/lib/flatten.cpp @@ -681,7 +681,6 @@ EnvI::EnvI(Model* model0, std::ostream& outstream0, std::ostream& errstream0) ignoreUnknownIds(false), maxCallStack(0), inRedundantConstraint(0), - inSymmetryBreakingConstraint(0), inMaybePartial(0), inReverseMapVar(false), counters({0, 0, 0, 0}), @@ -737,9 +736,6 @@ EnvI::~EnvI() { } long long int EnvI::genId() { return _ids++; } void EnvI::cseMapInsert(Expression* e, const EE& ee) { - if (e->type().isPar() && !e->isa()) { - return; - } KeepAlive ka(e); _cseMap.insert(ka, WW(ee.r(), ee.b())); Call* c = e->dynamicCast(); @@ -857,11 +853,6 @@ void EnvI::annotateFromCallStack(Expression* e) { bool allCalls = true; for (int i = static_cast(callStack.size()) - 1; i >= prev; i--) { Expression* ee = callStack[i]->untag(); - if (ee->type().isAnn()) { - // If we are inside an annotation call, don't annotate it again with - // anything from outside the call - break; - } allCalls = allCalls && (i == callStack.size() - 1 || ee->isa() || ee->isa()); for (ExpressionSetIter it = ee->ann().begin(); it != ee->ann().end(); ++it) { EE ee_ann = flat_exp(*this, Ctx(), *it, nullptr, constants().varTrue); @@ -1113,9 +1104,6 @@ CallStackItem::CallStackItem(EnvI& env0, Expression* e) : env(env0) { if (e->isa() && e->cast()->id() == "redundant_constraint") { env.inRedundantConstraint++; } - if (e->isa() && e->cast()->id() == "symmetry_breaking_constraint") { - env.inSymmetryBreakingConstraint++; - } if (e->ann().contains(constants().ann.maybe_partial)) { env.inMaybePartial++; } @@ -1136,9 +1124,6 @@ CallStackItem::~CallStackItem() { if (e->isa() && e->cast()->id() == "redundant_constraint") { env.inRedundantConstraint--; } - if (e->isa() && e->cast()->id() == "symmetry_breaking_constraint") { - env.inSymmetryBreakingConstraint--; - } if (e->ann().contains(constants().ann.maybe_partial)) { env.inMaybePartial--; } @@ -2689,6 +2674,10 @@ KeepAlive flat_cv_exp(EnvI& env, Ctx ctx, Expression* e) { typedef Expression* ArrayVal; Expression* e(EnvI& env, Expression* e) const { return flat_cv_exp(env, ctx, e)(); } static Expression* exp(Expression* e) { return e; } + static Expression* flatten(EnvI& env, Expression* e0) { + return flat_exp(env, Ctx(), e0, nullptr, constants().varTrue).r(); + } + } eval(ctx); std::vector a = eval_comp(env, eval, c); @@ -3157,14 +3146,8 @@ void flatten(Env& e, FlatteningOptions opt) { GCLock lock; IntSetVal* dom = eval_intset(env, vdi->e()->ti()->domain()); - if (0 == dom->size()) { - std::ostringstream oss; - oss << "Variable has empty domain: " << (*vdi->e()); - env.fail(oss.str()); - } - - bool needRangeDomain = onlyRangeDomains && !vdi->e()->type().isOpt(); - if (!needRangeDomain && !vdi->e()->type().isOpt()) { + bool needRangeDomain = onlyRangeDomains; + if (!needRangeDomain && dom->size() > 0) { if (dom->min(0).isMinusInfinity() || dom->max(dom->size() - 1).isPlusInfinity()) { needRangeDomain = true; } @@ -3203,7 +3186,7 @@ void flatten(Env& e, FlatteningOptions opt) { std::vector args(2); args[0] = vdi->e()->id(); args[1] = new SetLit(vdi->e()->loc(), dom); - Call* call = new Call(vdi->e()->loc(), constants().ids.mzn_set_in_internal, args); + Call* call = new Call(vdi->e()->loc(), constants().ids.set_in, args); call->type(Type::varbool()); call->decl(env.model->matchFn(env, call, false)); // Give distinct call stack @@ -3224,11 +3207,6 @@ void flatten(Env& e, FlatteningOptions opt) { vdi->e()->ti()->domain() != nullptr) { GCLock lock; FloatSetVal* vdi_dom = eval_floatset(env, vdi->e()->ti()->domain()); - if (0 == vdi_dom->size()) { - std::ostringstream oss; - oss << "Variable has empty domain: " << (*vdi->e()); - env.fail(oss.str()); - } FloatVal vmin = vdi_dom->min(); FloatVal vmax = vdi_dom->max(); if (vmin == -FloatVal::infinity() && vmax == FloatVal::infinity()) { diff --git a/lib/flatten/flatten_comp.cpp b/lib/flatten/flatten_comp.cpp index 94503cd..6297309 100644 --- a/lib/flatten/flatten_comp.cpp +++ b/lib/flatten/flatten_comp.cpp @@ -193,6 +193,9 @@ EE flatten_comp(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b : nullptr; return flat_exp(env, ctx, e0, r, b); } + static Expression* flatten(EnvI& env, Expression* e0) { + return flat_exp(env, Ctx(), e0, nullptr, constants().varTrue).r(); + } } _evalf(ctx); std::vector elems_ee; bool wasUndefined = false; diff --git a/lib/flatten/flatten_par.cpp b/lib/flatten/flatten_par.cpp index 2cb78f6..70fe7b2 100644 --- a/lib/flatten/flatten_par.cpp +++ b/lib/flatten/flatten_par.cpp @@ -36,35 +36,26 @@ EE flatten_par(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b) } if (e->type().dim() > 0) { EnvI::CSEMap::iterator it; - auto* ident = e->dynamicCast(); - if (ident != nullptr) { - Expression* e_val = follow_id_to_decl(ident); - if (e_val->isa()) { - ident = e_val->cast(); - } else if (e_val->isa()) { - ident = e_val->cast()->id(); - } - if (ident->decl()->flat() == nullptr || ident->decl()->toplevel()) { - VarDecl* vd = ident->decl()->flat(); - if (vd == nullptr) { - EE flat_ident = flat_exp(env, Ctx(), ident->decl(), nullptr, constants().varTrue); - vd = flat_ident.r()->cast()->decl(); - ident->decl()->flat(vd); - auto* al = follow_id(vd->id())->cast(); - if (al->size() == 0) { - if (r == nullptr) { - ret.r = al; - } else { - ret.r = bind(env, ctx, r, al); - } - ret.b = bind(env, Ctx(), b, constants().literalTrue); - return ret; + Id* id = e->dynamicCast(); + if ((id != nullptr) && (id->decl()->flat() == nullptr || id->decl()->toplevel())) { + VarDecl* vd = id->decl()->flat(); + if (vd == nullptr) { + vd = flat_exp(env, Ctx(), id->decl(), nullptr, constants().varTrue).r()->cast()->decl(); + id->decl()->flat(vd); + auto* al = follow_id(vd->id())->cast(); + if (al->size() == 0) { + if (r == nullptr) { + ret.r = al; + } else { + ret.r = bind(env, ctx, r, al); } + ret.b = bind(env, Ctx(), b, constants().literalTrue); + return ret; } - ret.r = bind(env, ctx, r, e->cast()->decl()->flat()->id()); - ret.b = bind(env, Ctx(), b, constants().literalTrue); - return ret; } + ret.r = bind(env, ctx, r, e->cast()->decl()->flat()->id()); + ret.b = bind(env, Ctx(), b, constants().literalTrue); + return ret; } if ((it = env.cseMapFind(e)) != env.cseMapEnd()) { ret.r = bind(env, ctx, r, it->second.r()->cast()->id()); diff --git a/lib/flatten/flatten_setlit.cpp b/lib/flatten/flatten_setlit.cpp index 44da837..4da79d1 100644 --- a/lib/flatten/flatten_setlit.cpp +++ b/lib/flatten/flatten_setlit.cpp @@ -34,11 +34,7 @@ EE flatten_setlit(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* ret.b = conj(env, b, Ctx(), elems_ee); if (allPar) { GCLock lock; - auto* nsl = new SetLit(Location().introduce(), elems); - Type nsl_t(e->type()); - nsl_t.ti(Type::TI_PAR); - nsl->type(nsl_t); - Expression* ee = eval_set_lit(env, nsl); + Expression* ee = eval_set_lit(env, e); ret.r = bind(env, Ctx(), r, ee); } else { GCLock lock; diff --git a/lib/flatten/flatten_vardecl.cpp b/lib/flatten/flatten_vardecl.cpp index c8fd6ef..1e63505 100644 --- a/lib/flatten/flatten_vardecl.cpp +++ b/lib/flatten/flatten_vardecl.cpp @@ -63,13 +63,6 @@ EE flatten_vardecl(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl } } } - if (vd->e() != nullptr && vd->e()->type().isPar() && !vd->ti()->type().isPar()) { - // Flattening the RHS resulted in a par expression. Make the variable par. - Type t(vd->ti()->type()); - t.ti(Type::TI_PAR); - vd->ti()->type(t); - vd->type(t); - } } ret.r = bind(env, Ctx(), r, vd->id()); diff --git a/lib/flattener.cpp b/lib/flattener.cpp index de3fa20..1072a35 100644 --- a/lib/flattener.cpp +++ b/lib/flattener.cpp @@ -474,10 +474,9 @@ void Flattener::flatten(const std::string& modelString, const std::string& model } if (!_globalsDir.empty()) { - _includePaths.insert(_includePaths.begin(), - FileUtils::file_path(_stdLibDir + "/" + _globalsDir + "/")); + _includePaths.insert(_includePaths.begin(), _stdLibDir + "/" + _globalsDir + "/"); } - _includePaths.push_back(FileUtils::file_path(_stdLibDir + "/std/")); + _includePaths.push_back(_stdLibDir + "/std/"); for (auto& includePath : _includePaths) { if (!FileUtils::directory_exists(includePath)) { diff --git a/lib/json_parser.cpp b/lib/json_parser.cpp index 4090692..1bf1c5a 100644 --- a/lib/json_parser.cpp +++ b/lib/json_parser.cpp @@ -629,8 +629,7 @@ void JSONParser::parseModel(Model* m, std::istream& is, bool isData) { string ident = expectString(is); expectToken(is, T_COLON); auto it = knownIds.find(ident); - bool possibleString = it == knownIds.end() || - (!it->second->isEnum() && it->second->type().bt() != Type::BT_UNKNOWN); + bool possibleString = it == knownIds.end() || it->second->type().bt() != Type::BT_UNKNOWN; Expression* e = parseExp(is, isData, possibleString); if (ident[0] != '_' && (!isData || it != knownIds.end())) { if (e == nullptr) { @@ -648,7 +647,7 @@ void JSONParser::parseModel(Model* m, std::istream& is, bool isData) { e = coerceArray(it->second, al); } else if (it->second->type().isSet()) { // Convert array to a set - e = new SetLit(Location().introduce(), al->getVec()); + e = new Call(Location().introduce(), "array2set", {al}); } } auto* ai = new AssignI(e->loc().introduce(), ident, e); diff --git a/lib/output.cpp b/lib/output.cpp index 1570686..0d09d76 100644 --- a/lib/output.cpp +++ b/lib/output.cpp @@ -217,7 +217,7 @@ void make_par(EnvI& env, Expression* e) { bool outputObjective = (c.argCount() == 1 && eval_bool(env, c.arg(0))); c.id(ASTString("array1d")); Expression* json = - copy(env, env.cmap, create_json_output(env, outputObjective, false, false)); + copy(env, env.cmap, create__json_output(env, outputObjective, false, false)); std::vector new_args({json}); new_args[0]->type(Type::parstring(1)); c.args(new_args); @@ -655,14 +655,12 @@ void create_dzn_output_item(EnvI& e, bool outputObjective, bool includeOutputIte bool needArrayXd = false; if (vd->type().dim() > 0) { ArrayLit* al = nullptr; - if (!vd->ann().contains(constants().ann.output_only)) { - if ((vd->flat() != nullptr) && (vd->flat()->e() != nullptr)) { - al = eval_array_lit(_e, vd->flat()->e()); - } else if (vd->e() != nullptr) { - al = eval_array_lit(_e, vd->e()); - } + if ((vd->flat() != nullptr) && (vd->flat()->e() != nullptr)) { + al = eval_array_lit(_e, vd->flat()->e()); + } else if (vd->e() != nullptr) { + al = eval_array_lit(_e, vd->e()); } - if (al == nullptr || al->size() > 0) { + if (al->size() > 0) { needArrayXd = true; s << "array" << vd->type().dim() << "d("; for (int i = 0; i < vd->type().dim(); i++) { @@ -672,33 +670,9 @@ void create_dzn_output_item(EnvI& e, bool outputObjective, bool includeOutputIte s << _e.getEnum(enumId)->e()->id()->str() << ", "; } else if (al != nullptr) { s << al->min(i) << ".." << al->max(i) << ", "; - } else if (vd->ti()->ranges()[i]->domain() != nullptr) { + } else { IntSetVal* idxset = eval_intset(_e, vd->ti()->ranges()[i]->domain()); s << *idxset << ", "; - } else { - // Don't know index set range - have to compute in solns2out - auto* sl = new StringLit(Location().introduce(), s.str()); - _outputVars.push_back(sl); - - std::string index_set_fn = "index_set"; - if (vd->type().dim() > 1) { - index_set_fn += - "_" + std::to_string(i + 1) + "of" + std::to_string(vd->type().dim()); - } - auto* index_set_xx = new Call(Location().introduce(), index_set_fn, {vd->id()}); - index_set_xx->type(Type::parsetint()); - auto* i_fi = _e.model->matchFn(_e, index_set_xx, false); - assert(i_fi); - index_set_xx->decl(i_fi); - - auto* show = new Call(Location().introduce(), constants().ids.show, {index_set_xx}); - show->type(Type::parstring()); - FunctionI* s_fi = _e.model->matchFn(_e, show, false); - assert(s_fi); - show->decl(s_fi); - - _outputVars.push_back(show); - s.str(", "); } } } @@ -764,8 +738,8 @@ void create_dzn_output_item(EnvI& e, bool outputObjective, bool includeOutputIte e.model->addItem(newOutputItem); } -ArrayLit* create_json_output(EnvI& e, bool outputObjective, bool includeOutputItem, - bool hasChecker) { +ArrayLit* create__json_output(EnvI& e, bool outputObjective, bool includeOutputItem, + bool hasChecker) { std::vector outputVars; outputVars.push_back(new StringLit(Location().introduce(), "{\n")); @@ -893,7 +867,7 @@ void create_json_output_item(EnvI& e, bool outputObjective, bool includeOutputIt bool hasChecker) { auto* newOutputItem = new OutputI(Location().introduce(), - create_json_output(e, outputObjective, includeOutputItem, hasChecker)); + create__json_output(e, outputObjective, includeOutputItem, hasChecker)); e.model->addItem(newOutputItem); } diff --git a/lib/parser.cpp b/lib/parser.cpp index 7de8e73..f94d19f 100644 --- a/lib/parser.cpp +++ b/lib/parser.cpp @@ -53,27 +53,6 @@ std::string get_file_contents(std::ifstream& in) { namespace MiniZinc { -std::string ParserState::canonicalFilename(const std::string& f) const { - if (FileUtils::is_absolute(f) || std::string(filename).empty()) { - return f; - } - for (const auto& ip : includePaths) { - std::string fullname = FileUtils::file_path(ip + "/" + f); - if (FileUtils::file_exists(fullname)) { - return fullname; - } - } - std::string parentPath = FileUtils::dir_name(filename); - if (parentPath.empty()) { - parentPath = "."; - } - std::string fullname = FileUtils::file_path(parentPath + "/" + f); - if (FileUtils::file_exists(fullname)) { - return fullname; - } - return f; -} - void parse(Env& env, Model*& model, const vector& filenames, const vector& datafiles, const std::string& modelString, const std::string& modelStringName, const vector& ip, bool isFlatZinc, @@ -103,7 +82,7 @@ void parse(Env& env, Model*& model, const vector& filenames, string fullName = filenames[i]; string baseName = FileUtils::base_name(filenames[i]); if (!FileUtils::is_absolute(fullName)) { - fullName = FileUtils::file_path(workingDir + "/" + fullName); + fullName = workingDir + "/" + fullName; } bool isFzn = (baseName.compare(baseName.length() - 4, 4, ".fzn") == 0); if (isFzn) { @@ -112,7 +91,7 @@ void parse(Env& env, Model*& model, const vector& filenames, auto* includedModel = new Model; includedModel->setFilename(baseName); files.emplace_back(includedModel, nullptr, "", fullName); - seenModels.insert(pair(fullName, includedModel)); + seenModels.insert(pair(baseName, includedModel)); Location loc(ASTString(filenames[i]), 0, 0, 0, 0); auto* inc = new IncludeI(loc, includedModel->filename()); inc->m(includedModel, true); @@ -138,19 +117,11 @@ void parse(Env& env, Model*& model, const vector& filenames, auto include_file = [&](const std::string& libname, bool builtin) { GCLock lock; auto* lib = new Model; - std::string fullname; - for (const auto& ip : includePaths) { - std::string n = FileUtils::file_path(ip + "/" + libname); - if (FileUtils::file_exists(n)) { - fullname = n; - break; - } - } - lib->setFilename(fullname); - files.emplace_back(lib, nullptr, "./", fullname, builtin); - seenModels.insert(pair(fullname, lib)); + lib->setFilename(libname); + files.emplace_back(lib, nullptr, "./", libname, builtin); + seenModels.insert(pair(libname, lib)); Location libloc(ASTString(model->filename()), 0, 0, 0, 0); - auto* libinc = new IncludeI(libloc, libname); + auto* libinc = new IncludeI(libloc, lib->filename()); libinc->m(lib, true); model->addItem(libinc); }; @@ -178,7 +149,6 @@ void parse(Env& env, Model*& model, const vector& filenames, std::string s; std::string fullname; - std::string basename; bool isFzn; if (!isModelString) { for (Model* p = m->parent(); p != nullptr; p = p->parent()) { @@ -191,36 +161,46 @@ void parse(Env& env, Model*& model, const vector& filenames, } } ifstream file; - if (FileUtils::is_absolute(f)) { + if (FileUtils::is_absolute(f) || parentPath.empty()) { fullname = f; - basename = FileUtils::base_name(fullname); if (FileUtils::file_exists(fullname)) { file.open(FILE_PATH(fullname), std::ios::binary); } - } - if (file.is_open() && - FileUtils::file_path(FileUtils::dir_name(fullname)) != FileUtils::file_path(workingDir) && - FileUtils::file_exists(workingDir + "/" + basename)) { - err << "Warning: file " << basename - << " included from library, but also exists in current working directory" << endl; - } - for (const auto& includePath : includePaths) { - std::string deprecatedName = includePath + "/" + basename + ".deprecated.mzn"; - if (FileUtils::file_exists(deprecatedName)) { - string deprecatedFullPath = FileUtils::file_path(deprecatedName); - string deprecatedBaseName = FileUtils::base_name(deprecatedFullPath); - string deprecatedDirName = FileUtils::dir_name(deprecatedFullPath); - auto* includedModel = new Model; - includedModel->setFilename(deprecatedName); - files.emplace_back(includedModel, nullptr, "", deprecatedName, isSTDLib, false); - seenModels.insert(pair(deprecatedName, includedModel)); - Location loc(ASTString(deprecatedName), 0, 0, 0, 0); - auto* inc = new IncludeI(loc, includedModel->filename()); - inc->m(includedModel, true); - m->addItem(inc); - files.emplace_back(includedModel, inc, deprecatedDirName, deprecatedFullPath, isSTDLib, - false); + } else { + includePaths.push_back(parentPath); + unsigned int i = 0; + for (; i < includePaths.size(); i++) { + fullname = includePaths[i] + "/" + f; + if (FileUtils::file_exists(fullname)) { + file.open(FILE_PATH(fullname), std::ios::binary); + if (file.is_open()) { + break; + } + } } + if (file.is_open() && i < includePaths.size() - 1 && parentPath == workingDir && + FileUtils::file_path(includePaths[i], workingDir) != FileUtils::file_path(workingDir) && + FileUtils::file_exists(workingDir + "/" + f)) { + err << "Warning: file " << f + << " included from library, but also exists in current working directory" << endl; + } + for (; i < includePaths.size(); i++) { + std::string deprecatedName = includePaths[i] + "/" + f + ".deprecated.mzn"; + if (FileUtils::file_exists(deprecatedName)) { + string deprecatedBaseName = FileUtils::base_name(deprecatedName); + auto* includedModel = new Model; + includedModel->setFilename(deprecatedBaseName); + files.emplace_back(includedModel, nullptr, "", deprecatedName, isSTDLib, false); + seenModels.insert(pair(deprecatedBaseName, includedModel)); + Location loc(ASTString(deprecatedName), 0, 0, 0, 0); + auto* inc = new IncludeI(loc, includedModel->filename()); + inc->m(includedModel, true); + m->addItem(inc); + files.emplace_back(includedModel, inc, deprecatedName, deprecatedBaseName, isSTDLib, + false); + } + } + includePaths.pop_back(); } if (!file.is_open()) { if (np_ii != nullptr) { @@ -248,7 +228,7 @@ void parse(Env& env, Model*& model, const vector& filenames, fullname = f; s = parentPath; } - ParserState pp(fullname, s, err, includePaths, files, seenModels, m, false, isFzn, isSTDLib, + ParserState pp(fullname, s, err, files, seenModels, m, false, isFzn, isSTDLib, parseDocComments); mzn_yylex_init(&pp.yyscanner); mzn_yyset_extra(&pp, pp.yyscanner); @@ -285,8 +265,7 @@ void parse(Env& env, Model*& model, const vector& filenames, s = get_file_contents(file); } - ParserState pp(f, s, err, includePaths, files, seenModels, model, true, false, false, - parseDocComments); + ParserState pp(f, s, err, files, seenModels, model, true, false, false, parseDocComments); mzn_yylex_init(&pp.yyscanner); mzn_yyset_extra(&pp, pp.yyscanner); mzn_yyparse(&pp); diff --git a/lib/parser.yxx b/lib/parser.yxx index 52eb9ea..44beac1 100644 --- a/lib/parser.yxx +++ b/lib/parser.yxx @@ -395,20 +395,20 @@ error_item_start : MZN_INCLUDE | MZN_ENUM | MZN_OUTPUT include_item : MZN_INCLUDE MZN_STRING_LITERAL { ParserState* pp = static_cast(parm); - string canonicalName=pp->canonicalFilename($2); - map::iterator ret = pp->seenModels.find(canonicalName); + map::iterator ret = pp->seenModels.find($2); IncludeI* ii = new IncludeI(@$,ASTString($2)); $$ = ii; if (ret == pp->seenModels.end()) { Model* im = new Model; im->setParent(pp->model); - im->setFilename(canonicalName); + im->setFilename($2); string fpath = FileUtils::dir_name(pp->filename); + string fbase = FileUtils::base_name(pp->filename); if (fpath=="") fpath="./"; - pp->files.emplace_back(im, ii, fpath, canonicalName, pp->isSTDLib); + pp->files.emplace_back(im, ii, fpath, $2, pp->isSTDLib); ii->m(im); - pp->seenModels.insert(pair(canonicalName,im)); + pp->seenModels.insert(pair($2,im)); } else { ii->m(ret->second, false); } diff --git a/lib/passes/compile_pass.cpp b/lib/passes/compile_pass.cpp index 33e53f6..c892e9c 100644 --- a/lib/passes/compile_pass.cpp +++ b/lib/passes/compile_pass.cpp @@ -33,20 +33,6 @@ namespace MiniZinc { using std::string; using std::vector; -ASTString strip_stdlib_path(const vector& includePaths, const ASTString& fs) { - std::string f(fs.c_str()); - for (const auto& p : includePaths) { - if (f.size() > p.size() && f.substr(0, p.size()) == p) { - f = f.substr(p.size()); - while (!f.empty() && f[0] == '/') { - f = f.substr(1); - } - return ASTString(f); - } - } - return fs; -} - Env* change_library(Env& e, vector& includePaths, const string& globals_dir, CompilePassFlags& compflags, bool verbose = false) { GCLock lock; @@ -67,11 +53,7 @@ Env* change_library(Env& e, vector& includePaths, const string& globals_ vector include_names; for (Item* item : *m) { if (auto* inc = item->dynamicCast()) { - if (FileUtils::is_absolute(inc->f().c_str())) { - include_names.push_back(inc->f()); - } else { - include_names.push_back(strip_stdlib_path(new_includePaths, inc->m()->filepath())); - } + include_names.push_back(inc->m()->filepath()); } else { new_mod->addItem(copy(e.envi(), cm, item)); } diff --git a/lib/prettyprinter.cpp b/lib/prettyprinter.cpp index 7b22c92..2b858cb 100644 --- a/lib/prettyprinter.cpp +++ b/lib/prettyprinter.cpp @@ -657,7 +657,7 @@ public: } switch (i->iid()) { case Item::II_INC: - _os << "include \"" << Printer::escapeStringLit(i->cast()->f()) << "\""; + _os << "include \"" << i->cast()->f() << "\""; break; case Item::II_VD: p(i->cast()->e()); @@ -1648,7 +1648,7 @@ public: typedef Document* ret; static ret mapIncludeI(const IncludeI& ii) { std::ostringstream oss; - oss << "include \"" << Printer::escapeStringLit(ii.f()) << "\";"; + oss << "include \"" << ii.f() << "\";"; return new StringDocument(oss.str()); } static ret mapVarDeclI(const VarDeclI& vi) { diff --git a/lib/solver_instance_base.cpp b/lib/solver_instance_base.cpp index fa34db8..be056a9 100644 --- a/lib/solver_instance_base.cpp +++ b/lib/solver_instance_base.cpp @@ -18,7 +18,7 @@ namespace MiniZinc { -SolverInstanceBase::Status SolverInstanceBase::solve() { return SolverInstanceError; } +SolverInstanceBase::Status SolverInstanceBase::solve() { return SolverInstance__ERROR; } void SolverInstanceBase::reset() { assert(false); } diff --git a/lib/typecheck.cpp b/lib/typecheck.cpp index 645b588..26081c2 100644 --- a/lib/typecheck.cpp +++ b/lib/typecheck.cpp @@ -154,45 +154,10 @@ public: } }; -// Create all required mapping functions for a new enum -// (mapping enum identifiers to strings, and mapping between different enums) void create_enum_mapper(EnvI& env, Model* m, unsigned int enumId, VarDecl* vd, Model* enumItems) { GCLock lock; Id* ident = vd->id(); - - if (vd->e() == nullptr) { - // Enum without right hand side (may be supplied later in an assignment - // item, or we may be runnint in --model-interface-only mode). - // Need to create stub function declarations, so that the type checker - // is happy. - Type tx = Type::parint(); - tx.ot(Type::OT_OPTIONAL); - auto* ti_aa = new TypeInst(Location().introduce(), tx); - auto* vd_aa = new VarDecl(Location().introduce(), ti_aa, "x"); - vd_aa->toplevel(false); - - auto* ti_ab = new TypeInst(Location().introduce(), Type::parbool()); - auto* vd_ab = new VarDecl(Location().introduce(), ti_ab, "b"); - vd_ab->toplevel(false); - - auto* ti_aj = new TypeInst(Location().introduce(), Type::parbool()); - auto* vd_aj = new VarDecl(Location().introduce(), ti_aj, "json"); - vd_aj->toplevel(false); - - auto* ti_fi = new TypeInst(Location().introduce(), Type::parstring()); - std::vector fi_params(3); - fi_params[0] = vd_aa; - fi_params[1] = vd_ab; - fi_params[2] = vd_aj; - auto* fi = - new FunctionI(Location().introduce(), create_enum_to_string_name(ident, "_toString_"), - ti_fi, fi_params, nullptr); - enumItems->addItem(fi); - - return; - } - Call* c = vd->e()->dynamicCast(); auto* al = vd->e()->dynamicCast(); @@ -796,14 +761,7 @@ void create_enum_mapper(EnvI& env, Model* m, unsigned int enumId, VarDecl* vd, M } // Create set literal for overall enum - Expression* upperBound; - if (!partCardinality.empty()) { - upperBound = partCardinality.back(); - } else { - // For empty enums, just create 1..0. - upperBound = IntLit::a(0); - } - auto* rhs = new BinOp(vd->loc(), IntLit::a(1), BOT_DOTDOT, upperBound); + auto* rhs = new BinOp(vd->loc(), IntLit::a(1), BOT_DOTDOT, partCardinality.back()); vd->e(rhs); if (parts.size() > 1) { @@ -1162,7 +1120,9 @@ void TopoSorter::add(EnvI& env, VarDeclI* vdi, bool handleEnums, Model* enumItem vd->ti()->type(vdt); vd->type(vdt); - create_enum_mapper(env, model, enumId, vd, enumItems); + if (vd->e() != nullptr) { + create_enum_mapper(env, model, enumId, vd, enumItems); + } } scopes.add(env, vd); } @@ -1488,7 +1448,7 @@ KeepAlive add_coercion(EnvI& env, Model* m, Expression* e, const Type& funarg_t) FunctionI* fi = m->matchFn(env, c, false); assert(fi); Type ct = fi->rtype(env, args, false); - ct.cv(e->type().cv() || ct.cv()); + ct.cv(e->type().cv()); c->type(ct); c->decl(fi); KeepAlive ka(c); @@ -2143,7 +2103,7 @@ public: args[0] = bop.lhs(); args[1] = bop.rhs(); Type ty = fi->rtype(_env, args, true); - ty.cv(bop.lhs()->type().cv() || bop.rhs()->type().cv() || ty.cv()); + ty.cv(bop.lhs()->type().cv() || bop.rhs()->type().cv()); bop.type(ty); if (fi->e() != nullptr) { @@ -2292,7 +2252,7 @@ public: uop.e(add_coercion(_env, _model, uop.e(), fi->argtype(_env, args, 0))()); args[0] = uop.e(); Type ty = fi->rtype(_env, args, true); - ty.cv(uop.e()->type().cv() || ty.cv()); + ty.cv(uop.e()->type().cv()); uop.type(ty); if (fi->e() != nullptr) { uop.decl(fi); @@ -2420,7 +2380,7 @@ public: // Set type and decl Type ty = fi->rtype(_env, args, true); - ty.cv(cv || ty.cv()); + ty.cv(cv); call.type(ty); if (Call* deprecated = fi->ann().getCall(constants().ann.mzn_deprecated)) { @@ -2476,7 +2436,7 @@ public: isVar |= li->type().isvar(); } Type ty = let.in()->type(); - ty.cv(cv || ty.cv()); + ty.cv(cv); if (isVar && ty.bt() == Type::BT_BOOL && ty.dim() == 0) { ty.ti(Type::TI_VAR); } @@ -2952,13 +2912,6 @@ void typecheck(Env& env, Model* origModel, std::vector& typeErrors, _bottomUpTyper.run(i->e()); if (i->e() != nullptr) { Type et = i->e()->type(); - if (et.isbool()) { - Type target_t = Type::varint(); - if (et.isOpt()) { - target_t.ot(Type::OT_OPTIONAL); - } - i->e(add_coercion(_env, _env.model, i->e(), target_t)()); - } bool needOptCoercion = et.isOpt() && et.isint(); if (needOptCoercion) { @@ -3180,34 +3133,10 @@ void typecheck(Env& env, Model* origModel, std::vector& typeErrors, } while (didRemove); // Create par versions of remaining functions - if (!fnsToMakePar.empty()) { + { // First step: copy and register functions std::vector parFunctions; CopyMap parCopyMap; - // Step 1a: enter all global declarations into copy map - class EnterGlobalDecls : public EVisitor { - public: - CopyMap& cm; - EnterGlobalDecls(CopyMap& cm0) : cm(cm0) {} - void vId(Id& ident) { - if (ident.decl() != nullptr && ident.decl()->toplevel()) { - cm.insert(ident.decl(), ident.decl()); - } - } - } _egd(parCopyMap); - for (auto& p : fnsToMakePar) { - if (!p.second.first) { - for (auto* param : p.first->params()) { - top_down(_egd, param); - } - for (ExpressionSetIter i = p.first->ann().begin(); i != p.first->ann().end(); ++i) { - top_down(_egd, *i); - } - top_down(_egd, p.first->e()); - } - } - - // Step 1b: copy functions for (auto& p : fnsToMakePar) { if (!p.second.first) { GCLock lock; @@ -3574,7 +3503,7 @@ void output_model_interface(Env& env, Model* m, std::ostream& os, os << ",\n \"method\": \""; os << _ifc.method; os << "\""; - os << ",\n \"has_output_item\": " << (_ifc.outputItem ? "true" : "false"); + os << ",\n \"has_outputItem\": " << (_ifc.outputItem ? "true" : "false"); os << ",\n \"included_files\": [\n" << _ifc.ossIncludedFiles.str() << "\n ]"; os << "\n}\n"; } diff --git a/share/minizinc/Preferences.json b/share/minizinc/Preferences.json index ce23431..704ca6f 100644 --- a/share/minizinc/Preferences.json +++ b/share/minizinc/Preferences.json @@ -5,10 +5,8 @@ "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", ""] + ["org.minizinc.mip.scip", "-DQuadrIntSolverConfig=true", ""], + ["org.minizinc.mip.scip", "-DQuadrFloatSolverConfig=true", ""] ] } diff --git a/share/minizinc/linear/fzn_lex_chain_lesseq_bool.mzn b/share/minizinc/linear/fzn_lex_chain_lesseq_bool.mzn deleted file mode 100644 index fcc7f22..0000000 --- a/share/minizinc/linear/fzn_lex_chain_lesseq_bool.mzn +++ /dev/null @@ -1,4 +0,0 @@ -include "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); diff --git a/share/minizinc/linear/fzn_lex_chain_lesseq_int.mzn b/share/minizinc/linear/fzn_lex_chain_lesseq_int.mzn deleted file mode 100644 index 1fc2920..0000000 --- a/share/minizinc/linear/fzn_lex_chain_lesseq_int.mzn +++ /dev/null @@ -1,23 +0,0 @@ -include "lex_lesseq.mzn"; -include "fzn_lex_chain_lesseq_orbitope.mzn"; - -predicate fzn_lex_chain_lesseq_int(array[int, int] of var int: a) = - if MZN__Orbitope /\ dom_array(a) subset 0..1 then - fzn_lex_chain_lesseq__orbitope( a, - card(index_set_1of2(a)), 0, true, - not mzn_in_symmetry_breaking_constraint() - ) - else - fzn_lex_chain_lesseq_int__CP(a) - endif; - - -predicate fzn_lex_chain_lesseq_int__CP(array[int, int] of var int: a) = - let { - int: lb2 = min(index_set_2of2(a)), - int: ub2 = max(index_set_2of2(a)) - } in ( - forall(j in lb2 + 1 .. ub2) ( - lex_lesseq(col(a, j-1), col(a, j)) - ) - ); diff --git a/share/minizinc/linear/fzn_lex_chain_lesseq_orbitope.mzn b/share/minizinc/linear/fzn_lex_chain_lesseq_orbitope.mzn deleted file mode 100644 index 630e310..0000000 --- a/share/minizinc/linear/fzn_lex_chain_lesseq_orbitope.mzn +++ /dev/null @@ -1,40 +0,0 @@ -include "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( 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, 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 { - int: lb2 = min(index_set_2of2(a)), - int: ub2 = max(index_set_2of2(a)) - } in ( - forall(j in lb2 + 1 .. ub2) ( - lex_lesseq(col(a, j-1), col(a, j)) - ) - /\ - 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 - ); diff --git a/share/minizinc/linear/fzn_lex_less_bool.mzn b/share/minizinc/linear/fzn_lex_less_bool.mzn deleted file mode 100644 index 31c706c..0000000 --- a/share/minizinc/linear/fzn_lex_less_bool.mzn +++ /dev/null @@ -1,12 +0,0 @@ -%-----------------------------------------------------------------------------% -% 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); - -%-----------------------------------------------------------------------------% diff --git a/share/minizinc/linear/fzn_lex_less_bool_reif.mzn b/share/minizinc/linear/fzn_lex_less_bool_reif.mzn new file mode 100644 index 0000000..ca137f1 --- /dev/null +++ b/share/minizinc/linear/fzn_lex_less_bool_reif.mzn @@ -0,0 +1,21 @@ +include "../std/fzn_lex_less_bool_reif.mzn"; + +predicate fzn_lex_less_bool_imp(array[int] of var bool: x, + array[int] of var bool: y, + var bool: c) = + 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 = max(ux - lx, uy - ly), + array[0..size+1] of var bool: b } + in + (c -> b[0]) + /\ + forall(i in 0..size) ( + b[i] = ( x[lx + i] <= y[ly + i] + /\ + (x[lx + i] < y[ly + i] \/ b[i+1]) ) + ) + /\ + b[size + 1] = (ux - lx < uy - ly); diff --git a/share/minizinc/linear/fzn_lex_less_float.mzn b/share/minizinc/linear/fzn_lex_less_float.mzn deleted file mode 100644 index 6ae53c9..0000000 --- a/share/minizinc/linear/fzn_lex_less_float.mzn +++ /dev/null @@ -1,38 +0,0 @@ -%-----------------------------------------------------------------------------% -% 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) = - 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]) - ) - ; - -%-----------------------------------------------------------------------------% diff --git a/share/minizinc/linear/fzn_lex_less_int.mzn b/share/minizinc/linear/fzn_lex_less_int.mzn deleted file mode 100644 index 93b6929..0000000 --- a/share/minizinc/linear/fzn_lex_less_int.mzn +++ /dev/null @@ -1,39 +0,0 @@ -%-----------------------------------------------------------------------------% -% 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) = - assert(length(x) == length(y), - "lex_less_int(\(x), \(y)): arrays of different lengths") - /\ - fzn_lex_less_int__MIP(x, y) - ; - -predicate fzn_lex_less_int__MIP(array[int] of var int: x, - array[int] of var int: y) = - 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]) - ) - ; - -%-----------------------------------------------------------------------------% diff --git a/share/minizinc/linear/fzn_lex_lesseq_bool.mzn b/share/minizinc/linear/fzn_lex_lesseq_bool.mzn index cb53b68..16af74a 100644 --- a/share/minizinc/linear/fzn_lex_lesseq_bool.mzn +++ b/share/minizinc/linear/fzn_lex_lesseq_bool.mzn @@ -3,10 +3,47 @@ % 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); +% if (min(card(index_set(x)), card(index_set(y))) <= 25) then +% let { int: size = min(card(index_set(x)), card(index_set(y))); +% } in +% sum(i in 0..size-1)(pow(2, (size-1-i)) * bool2int(x[i+min(index_set(x))])) +% <= sum(i in 0..size-1)(pow(2, (size-1-i)) * bool2int(y[i+min(index_set(y))])) +% else +% my_trace ("lex_lesseq_bool(\(x), \(y))") /\ + 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 } + % b[i] is true if the lexicographical order holds from position i on. + in + b[0] + /\ + forall(i in 0..size) ( + b[i] -> ( ( ( x[lx + i] <= y[ly + i] ) ) /\ + % bool2int(b[i]) + bool2int(x[lx + i]) + (1-bool2int(y[ly + i])) <= 2 /\ + +% ( b[i] -> +( x[lx + i] < y[ly + i] \/ b[i+1] ) ) +% /\ ( bool2int(b[i]) <= bool2int(x[lx + i] < y[ly + i]) + bool2int(b[i+1]) ) /\ + % bool2int(b[i]) + (1-bool2int(x[lx + i])) + (1-bool2int(y[ly + i])) + (1-bool2int(b[i+1])) <= 3 + % /\ bool2int(b[i]) + bool2int(x[lx + i]) + bool2int(y[ly + i]) + (1-bool2int(b[i+1])) <= 3 + %% This guy is dominated by the 1st one above but helps: + % /\ bool2int(b[i]) + bool2int(x[lx + i]) + (1-bool2int(y[ly + i])) + (1-bool2int(b[i+1])) <= 3 + ) + /\ b[size+1] = (ux-lx <= uy-ly) +% endif +; + +% forall(i in 0..size) ( +% ( b[i] == ( x[lx + i] <= y[ly + i] ) ) +% /\ +% if i < size then +% ( b[i] == ( x[lx + i] < y[ly + i] \/ b[i+1] +% ) ) else true endif +% ); %-----------------------------------------------------------------------------% diff --git a/share/minizinc/linear/fzn_lex_lesseq_bool_reif.mzn b/share/minizinc/linear/fzn_lex_lesseq_bool_reif.mzn new file mode 100644 index 0000000..a4a63f5 --- /dev/null +++ b/share/minizinc/linear/fzn_lex_lesseq_bool_reif.mzn @@ -0,0 +1,50 @@ +predicate fzn_lex_lesseq_bool_reif(array[int] of var bool: x, + array[int] of var bool: y, + var bool: c) = + 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 = max(ux - lx, uy - ly), + array[0..size+1] of var bool: b } + % b[i] is true if the lexicographical order holds from position i on. + in + (c <-> b[0]) + /\ + forall(i in 0..size) ( + ( b[i] -> ( x[lx + i] <= y[ly + i] ) ) /\ + bool2int(b[i]) + bool2int(x[lx + i]) + (1-bool2int(y[ly + i])) <= 2 + /\ + ( b[i] -> ( x[lx + i] < y[ly + i] \/ b[i+1] ) ) /\ + bool2int(b[i]) + (1-bool2int(x[lx + i])) + (1-bool2int(y[ly + i])) + (1-bool2int(b[i+1])) <= 3 + /\ bool2int(b[i]) + bool2int(x[lx + i]) + bool2int(y[ly + i]) + (1-bool2int(b[i+1])) <= 3 + /\ bool2int(b[i]) + bool2int(x[lx + i]) + (1-bool2int(y[ly + i])) + (1-bool2int(b[i+1])) <= 3 + ) + /\ b[size+1] = (ux-lx <= uy-ly) +% endif +; + +predicate fzn_lex_lesseq_bool_imp(array[int] of var bool: x, + array[int] of var bool: y, + var bool: c) = + 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 = max(ux - lx, uy - ly), + array[0..size+1] of var bool: b } + % b[i] is true if the lexicographical order holds from position i on. + in + (c -> b[0]) + /\ + forall(i in 0..size) ( + ( b[i] -> ( x[lx + i] <= y[ly + i] ) ) /\ + bool2int(b[i]) + bool2int(x[lx + i]) + (1-bool2int(y[ly + i])) <= 2 + /\ + ( b[i] -> ( x[lx + i] < y[ly + i] \/ b[i+1] ) ) /\ + bool2int(b[i]) + (1-bool2int(x[lx + i])) + (1-bool2int(y[ly + i])) + (1-bool2int(b[i+1])) <= 3 + /\ bool2int(b[i]) + bool2int(x[lx + i]) + bool2int(y[ly + i]) + (1-bool2int(b[i+1])) <= 3 + /\ bool2int(b[i]) + bool2int(x[lx + i]) + (1-bool2int(y[ly + i])) + (1-bool2int(b[i+1])) <= 3 + ) + /\ b[size+1] = (ux-lx <= uy-ly) +; diff --git a/share/minizinc/linear/fzn_lex_lesseq_float.mzn b/share/minizinc/linear/fzn_lex_lesseq_float.mzn deleted file mode 100644 index c9b7fa0..0000000 --- a/share/minizinc/linear/fzn_lex_lesseq_float.mzn +++ /dev/null @@ -1,38 +0,0 @@ -%-----------------------------------------------------------------------------% -% 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) = - assert(length(x) == length(y), %% SCIP cannot - "lex_lesseq_float(\(x), \(y)): arrays of different lengths") - /\ - fzn_lex_lesseq_float__MIP(x, y); - -predicate fzn_lex_lesseq_float__MIP(array[int] of var float: x, - array[int] of var float: y) = - 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]) - ) - ; - -%-----------------------------------------------------------------------------% diff --git a/share/minizinc/linear/fzn_lex_lesseq_int.mzn b/share/minizinc/linear/fzn_lex_lesseq_int.mzn deleted file mode 100644 index c357581..0000000 --- a/share/minizinc/linear/fzn_lex_lesseq_int.mzn +++ /dev/null @@ -1,77 +0,0 @@ -%-----------------------------------------------------------------------------% -% 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, - array[int] of var int: y) = - 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 - fzn_lex_lesseq_int__CP(x, y) - else - fzn_lex_lesseq_int__MIP(x, y) - endif; - -predicate fzn_lex_lesseq_int__CP(array[int] of var int: x, - array[int] of var int: y) = - 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 } - % b[i] is true if the lexicographical order holds from position i on. - in - b[0] - /\ - forall(i in 0..size) ( - b[i] = ( x[lx + i] <= y[ly + i] - /\ - (x[lx + i] < y[ly + i] \/ b[i+1]) - ) - ) - /\ - b[size + 1] = (ux - lx <= uy - ly) - ; - -predicate fzn_lex_lesseq_int__MIP(array[int] of var int: x, - array[int] of var int: y) = - 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]) - ) - ; - -%% SCIP constraint handler orbisack -predicate fzn_lex_lesseq__orbisack( - array[int] of var int: vec1, array[int] of var int: vec2, bool: isModelCons); - -%-----------------------------------------------------------------------------% diff --git a/share/minizinc/linear/options.mzn b/share/minizinc/linear/options.mzn index 4be13bd..027c2d2 100644 --- a/share/minizinc/linear/options.mzn +++ b/share/minizinc/linear/options.mzn @@ -40,25 +40,11 @@ bool: MZN__MinMaxGeneral = if absent(MinMaxGeneral) then false else deopt(MinMax %% CUMULATIVE opt bool: CumulativeSolverConfig; %% As set in share/minizinc/Preferences.json -opt bool: UseCumulative; %% User option, e.g., with -D -bool: MZN__Cumulative_Fixed_d_r = if occurs(UseCumulative) then deopt(UseCumulative) +opt bool: Cumulative; %% User option, e.g., with -D +bool: MZN__Cumulative_Fixed_d_r = if occurs(Cumulative) then deopt(Cumulative) elseif occurs(CumulativeSolverConfig) then deopt(CumulativeSolverConfig) else false endif; -%% ORBISACK -opt bool: OrbisackSolverConfig; %% As set in share/minizinc/Preferences.json -opt bool: UseOrbisack; %% User option, e.g., with -D -bool: MZN__Orbisack = if occurs(UseOrbisack) then deopt(UseOrbisack) - elseif occurs(OrbisackSolverConfig) then deopt(OrbisackSolverConfig) - else false endif; - -%% ORBITOPE -opt bool: OrbitopeSolverConfig; %% As set in share/minizinc/Preferences.json -opt bool: UseOrbitope; %% User option, e.g., with -D -bool: MZN__Orbitope = if occurs(UseOrbitope) then deopt(UseOrbitope) - elseif occurs(OrbitopeSolverConfig) then deopt(OrbitopeSolverConfig) - else false endif; - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Quadratic expressions %%%%%%%%%%%%%%%%%%%%%%%%%%%%% % --------------------------------------------------------------------------------------- % diff --git a/share/minizinc/std/fzn_lex2.mzn b/share/minizinc/std/fzn_lex2.mzn index 614ccb0..c9319eb 100644 --- a/share/minizinc/std/fzn_lex2.mzn +++ b/share/minizinc/std/fzn_lex2.mzn @@ -1,10 +1,21 @@ -include "lex_chain_lesseq.mzn"; +include "lex_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)] + let { + int: lbx1 = min(index_set_1of2(x)), + int: ubx1 = max(index_set_1of2(x)), + int: lbx2 = min(index_set_2of2(x)), + int: ubx2 = max(index_set_2of2(x)) + } in ( + forall(i in lbx1 + 1 .. ubx1) ( + lex_lesseq([x[i - 1, j] | j in index_set_2of2(x)], + [x[i, j] | j in index_set_2of2(x)] + ) + ) + /\ + forall(j in lbx2 + 1 .. ubx2) ( + lex_lesseq([x[i, j - 1] | i in index_set_1of2(x)], + [x[i, j ] | i in index_set_1of2(x)] + ) ) ); diff --git a/share/minizinc/std/fzn_lex2_reif.mzn b/share/minizinc/std/fzn_lex2_reif.mzn index 485c6b1..784f054 100644 --- a/share/minizinc/std/fzn_lex2_reif.mzn +++ b/share/minizinc/std/fzn_lex2_reif.mzn @@ -1,12 +1,21 @@ include "lex_lesseq.mzn"; predicate fzn_lex2_reif(array[int, int] of var int: x, var bool: b) = - b <-> ( - lex_chain_lesseq(x) + let { + int: lbx1 = min(index_set_1of2(x)), + int: ubx1 = max(index_set_1of2(x)), + int: lbx2 = min(index_set_2of2(x)), + int: ubx2 = max(index_set_2of2(x)) + } in b <-> ( + forall(i in lbx1 + 1 .. ubx1) ( + lex_lesseq([x[i - 1, j] | j in index_set_2of2(x)], + [x[i, j] | j in index_set_2of2(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)] + forall(j in lbx2 + 1 .. ubx2) ( + lex_lesseq([x[i, j - 1] | i in index_set_1of2(x)], + [x[i, j ] | i in index_set_1of2(x)] ) ) ); diff --git a/share/minizinc/std/fzn_lex_chain_less_bool.mzn b/share/minizinc/std/fzn_lex_chain_less_bool.mzn deleted file mode 100644 index 017465b..0000000 --- a/share/minizinc/std/fzn_lex_chain_less_bool.mzn +++ /dev/null @@ -1,11 +0,0 @@ -include "lex_less.mzn"; - -predicate fzn_lex_chain_less_bool(array[int, int] of var bool: a) = - let { - int: lb2 = min(index_set_2of2(a)), - int: ub2 = max(index_set_2of2(a)) - } in ( - forall(j in lb2 + 1 .. ub2) ( - lex_less(col(a, j-1), col(a, j)) - ) - ); diff --git a/share/minizinc/std/fzn_lex_chain_less_bool_reif.mzn b/share/minizinc/std/fzn_lex_chain_less_bool_reif.mzn deleted file mode 100644 index cd269e1..0000000 --- a/share/minizinc/std/fzn_lex_chain_less_bool_reif.mzn +++ /dev/null @@ -1,12 +0,0 @@ -include "lex_less.mzn"; - -predicate fzn_lex_chain_less_bool_reif( - array[int, int] of var bool: a, var bool: b) = - let { - int: lb2 = min(index_set_2of2(a)), - int: ub2 = max(index_set_2of2(a)) - } in b <-> ( - forall(j in lb2 + 1 .. ub2) ( - lex_less(col(a, j-1), col(a, j)) - ) - ); diff --git a/share/minizinc/std/fzn_lex_chain_less_int.mzn b/share/minizinc/std/fzn_lex_chain_less_int.mzn deleted file mode 100644 index 021f2c5..0000000 --- a/share/minizinc/std/fzn_lex_chain_less_int.mzn +++ /dev/null @@ -1,11 +0,0 @@ -include "lex_less.mzn"; - -predicate fzn_lex_chain_less_int(array[int, int] of var int: a) = - let { - int: lb2 = min(index_set_2of2(a)), - int: ub2 = max(index_set_2of2(a)) - } in ( - forall(j in lb2 + 1 .. ub2) ( - lex_less(col(a, j-1), col(a, j)) - ) - ); diff --git a/share/minizinc/std/fzn_lex_chain_less_int_reif.mzn b/share/minizinc/std/fzn_lex_chain_less_int_reif.mzn deleted file mode 100644 index 28bcfc9..0000000 --- a/share/minizinc/std/fzn_lex_chain_less_int_reif.mzn +++ /dev/null @@ -1,12 +0,0 @@ -include "lex_less.mzn"; - -predicate fzn_lex_chain_less_int_reif( - array[int, int] of var int: a, var bool: b) = - let { - int: lb2 = min(index_set_2of2(a)), - int: ub2 = max(index_set_2of2(a)) - } in b <-> ( - forall(j in lb2 + 1 .. ub2) ( - lex_less(col(a, j-1), col(a, j)) - ) - ); diff --git a/share/minizinc/std/fzn_lex_chain_lesseq_bool.mzn b/share/minizinc/std/fzn_lex_chain_lesseq_bool.mzn deleted file mode 100644 index 9e4f2d3..0000000 --- a/share/minizinc/std/fzn_lex_chain_lesseq_bool.mzn +++ /dev/null @@ -1,11 +0,0 @@ -include "lex_lesseq.mzn"; - -predicate fzn_lex_chain_lesseq_bool(array[int, int] of var bool: a) = - let { - int: lb2 = min(index_set_2of2(a)), - int: ub2 = max(index_set_2of2(a)) - } in ( - forall(j in lb2 + 1 .. ub2) ( - lex_lesseq(col(a, j-1), col(a, j)) - ) - ); diff --git a/share/minizinc/std/fzn_lex_chain_lesseq_bool_reif.mzn b/share/minizinc/std/fzn_lex_chain_lesseq_bool_reif.mzn deleted file mode 100644 index 41d0861..0000000 --- a/share/minizinc/std/fzn_lex_chain_lesseq_bool_reif.mzn +++ /dev/null @@ -1,12 +0,0 @@ -include "lex_lesseq.mzn"; - -predicate fzn_lex_chain_lesseq_bool_reif( - array[int, int] of var bool: a, var bool: b) = - let { - int: lb2 = min(index_set_2of2(a)), - int: ub2 = max(index_set_2of2(a)) - } in b <-> ( - forall(j in lb2 + 1 .. ub2) ( - lex_lesseq(col(a, j-1), col(a, j)) - ) - ); diff --git a/share/minizinc/std/fzn_lex_chain_lesseq_int.mzn b/share/minizinc/std/fzn_lex_chain_lesseq_int.mzn deleted file mode 100644 index 6485364..0000000 --- a/share/minizinc/std/fzn_lex_chain_lesseq_int.mzn +++ /dev/null @@ -1,11 +0,0 @@ -include "lex_lesseq.mzn"; - -predicate fzn_lex_chain_lesseq_int(array[int, int] of var int: a) = - let { - int: lb2 = min(index_set_2of2(a)), - int: ub2 = max(index_set_2of2(a)) - } in ( - forall(j in lb2 + 1 .. ub2) ( - lex_lesseq(col(a, j-1), col(a, j)) - ) - ); diff --git a/share/minizinc/std/fzn_lex_chain_lesseq_int_reif.mzn b/share/minizinc/std/fzn_lex_chain_lesseq_int_reif.mzn deleted file mode 100644 index 7ef0ae9..0000000 --- a/share/minizinc/std/fzn_lex_chain_lesseq_int_reif.mzn +++ /dev/null @@ -1,12 +0,0 @@ -include "lex_lesseq.mzn"; - -predicate fzn_lex_chain_lesseq_int_reif( - array[int, int] of var int: a, var bool: b) = - let { - int: lb2 = min(index_set_2of2(a)), - int: ub2 = max(index_set_2of2(a)) - } in b <-> ( - forall(j in lb2 + 1 .. ub2) ( - lex_lesseq(col(a, j-1), col(a, j)) - ) - ); diff --git a/share/minizinc/std/fzn_lex_chain_lesseq_orbitope.mzn b/share/minizinc/std/fzn_lex_chain_lesseq_orbitope.mzn deleted file mode 100644 index 3d2de11..0000000 --- a/share/minizinc/std/fzn_lex_chain_lesseq_orbitope.mzn +++ /dev/null @@ -1,23 +0,0 @@ -include "lex_lesseq.mzn"; - -predicate fzn_lex_chain_lesseq_orbitope( - array[int, int] of var int: a, int: kind) = - let { - int: lb2 = min(index_set_2of2(a)), - int: ub2 = max(index_set_2of2(a)) - } in ( - forall(j in lb2 + 1 .. ub2) ( - lex_lesseq(col(a, j-1), col(a, j)) - ) - /\ - 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 - ); diff --git a/share/minizinc/std/fzn_lex_chain_lesseq_orbitope_reif.mzn b/share/minizinc/std/fzn_lex_chain_lesseq_orbitope_reif.mzn deleted file mode 100644 index ddcaeca..0000000 --- a/share/minizinc/std/fzn_lex_chain_lesseq_orbitope_reif.mzn +++ /dev/null @@ -1,23 +0,0 @@ -include "lex_lesseq.mzn"; - -predicate fzn_lex_chain_lesseq_orbitope_reif( - array[int, int] of var int: a, int: kind, var bool: b) = - let { - int: lb2 = min(index_set_2of2(a)), - int: ub2 = max(index_set_2of2(a)) - } in b <-> ( - forall(j in lb2 + 1 .. ub2) ( - lex_lesseq(col(a, j-1), col(a, j)) - ) - /\ - 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 - ); diff --git a/share/minizinc/std/fzn_piecewise_linear.mzn b/share/minizinc/std/fzn_piecewise_linear.mzn index f102c34..8219e38 100644 --- a/share/minizinc/std/fzn_piecewise_linear.mzn +++ b/share/minizinc/std/fzn_piecewise_linear.mzn @@ -1,9 +1,8 @@ /* * Function fzn_piecewise_linear_base creates - * auxiliary variables for the interval representation of xi - * and constrains them to correspond to the value of x. - * The auxiliaries are reusable if we have several pwls - * on the same set of breakpoints and x. + * interval representation of x, + * which is reusable if we have several pwls + * on the same set of breakpoints */ function array[int, int] of var 0.0..1.0: fzn_piecewise_linear_base( var float: x, array[int] of float: xi) ::promise_total = diff --git a/share/minizinc/std/fzn_piecewise_linear_non_continuous.mzn b/share/minizinc/std/fzn_piecewise_linear_non_continuous.mzn deleted file mode 100644 index bc0a7e5..0000000 --- a/share/minizinc/std/fzn_piecewise_linear_non_continuous.mzn +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Function fzn_piecewise_linear_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_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(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 ( - lex_chain_less(x) + let { + int: lbx1 = min(index_set_1of2(x)), + int: ubx1 = max(index_set_1of2(x)), + int: lbx2 = min(index_set_2of2(x)), + int: ubx2 = max(index_set_2of2(x)) + } in b <-> ( + forall(i in lbx1 + 1 .. ubx1) ( + lex_less([x[i - 1, j] | j in index_set_2of2(x)], + [x[i, j] | j in index_set_2of2(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)] + + forall(j in lbx2 + 1 .. ubx2) ( + lex_less([x[i, j - 1] | i in index_set_1of2(x)], + [x[i, j ] | i in index_set_1of2(x)] ) ) ); diff --git a/share/minizinc/std/fzn_strictly_decreasing_int_opt.mzn b/share/minizinc/std/fzn_strictly_decreasing_int_opt.mzn deleted file mode 100644 index 5242d82..0000000 --- a/share/minizinc/std/fzn_strictly_decreasing_int_opt.mzn +++ /dev/null @@ -1,8 +0,0 @@ -include "fzn_strictly_increasing_int_opt.mzn"; - -%-----------------------------------------------------------------------------% -% Requires that the array 'x' is in strict decreasing order -%-----------------------------------------------------------------------------% - -predicate fzn_strictly_decreasing_int_opt(array[int] of var opt int: x) = - fzn_strictly_increasing_int_opt(reverse(x)); diff --git a/share/minizinc/std/globals.mzn b/share/minizinc/std/globals.mzn index c7099a3..63df09f 100644 --- a/share/minizinc/std/globals.mzn +++ b/share/minizinc/std/globals.mzn @@ -93,18 +93,11 @@ 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_greatereq.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"; diff --git a/share/minizinc/std/lex2_strict.mzn b/share/minizinc/std/lex2_strict.mzn deleted file mode 100644 index 6abb0ac..0000000 --- a/share/minizinc/std/lex2_strict.mzn +++ /dev/null @@ -1,8 +0,0 @@ -include "strict_lex2.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) = - strict_lex2(x); diff --git a/share/minizinc/std/lex_chain_greater.mzn b/share/minizinc/std/lex_chain_greater.mzn deleted file mode 100644 index 589147e..0000000 --- a/share/minizinc/std/lex_chain_greater.mzn +++ /dev/null @@ -1,28 +0,0 @@ -include "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; - diff --git a/share/minizinc/std/lex_chain_greatereq.mzn b/share/minizinc/std/lex_chain_greatereq.mzn deleted file mode 100644 index a22ef4a..0000000 --- a/share/minizinc/std/lex_chain_greatereq.mzn +++ /dev/null @@ -1,28 +0,0 @@ -include "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; - diff --git a/share/minizinc/std/lex_chain_greatereq_orbitope.mzn b/share/minizinc/std/lex_chain_greatereq_orbitope.mzn deleted file mode 100644 index eedd929..0000000 --- a/share/minizinc/std/lex_chain_greatereq_orbitope.mzn +++ /dev/null @@ -1,19 +0,0 @@ -include "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 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 1>=card(index_set_2of2(a)) then true - else 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; - diff --git a/share/minizinc/std/lex_chain_less.mzn b/share/minizinc/std/lex_chain_less.mzn deleted file mode 100644 index a3388f0..0000000 --- a/share/minizinc/std/lex_chain_less.mzn +++ /dev/null @@ -1,19 +0,0 @@ -include "lex_chain_less_bool.mzn"; -include "lex_chain_less_int.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 1>=card(index_set_2of2(a)) then true - else lex_chain_less_bool(a) endif; - -/** @group globals.lexicographic - Requires that the columns of matrix \a a are lexicographically sorted, - non-decreasing. -*/ -predicate lex_chain_less(array[int, int] of var int: a) = - if 1>=card(index_set_2of2(a)) then true - else lex_chain_less_int(a) endif; - diff --git a/share/minizinc/std/lex_chain_less_bool.mzn b/share/minizinc/std/lex_chain_less_bool.mzn deleted file mode 100644 index 1f3da2c..0000000 --- a/share/minizinc/std/lex_chain_less_bool.mzn +++ /dev/null @@ -1,12 +0,0 @@ -include "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); - -%-----------------------------------------------------------------------------% diff --git a/share/minizinc/std/lex_chain_less_int.mzn b/share/minizinc/std/lex_chain_less_int.mzn deleted file mode 100644 index 9b81617..0000000 --- a/share/minizinc/std/lex_chain_less_int.mzn +++ /dev/null @@ -1,12 +0,0 @@ -include "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); - -%-----------------------------------------------------------------------------% diff --git a/share/minizinc/std/lex_chain_lesseq.mzn b/share/minizinc/std/lex_chain_lesseq.mzn deleted file mode 100644 index 606483b..0000000 --- a/share/minizinc/std/lex_chain_lesseq.mzn +++ /dev/null @@ -1,33 +0,0 @@ -include "lex_chain_lesseq_bool.mzn"; -include "lex_chain_lesseq_int.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 1>=card(index_set_2of2(a)) then true - else 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 1>=card(index_set_2of2(a)) then true - else 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); - diff --git a/share/minizinc/std/lex_chain_lesseq_bool.mzn b/share/minizinc/std/lex_chain_lesseq_bool.mzn deleted file mode 100644 index 8ee03dd..0000000 --- a/share/minizinc/std/lex_chain_lesseq_bool.mzn +++ /dev/null @@ -1,12 +0,0 @@ -include "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); - -%-----------------------------------------------------------------------------% diff --git a/share/minizinc/std/lex_chain_lesseq_int.mzn b/share/minizinc/std/lex_chain_lesseq_int.mzn deleted file mode 100644 index 2c0d432..0000000 --- a/share/minizinc/std/lex_chain_lesseq_int.mzn +++ /dev/null @@ -1,12 +0,0 @@ -include "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); - -%-----------------------------------------------------------------------------% diff --git a/share/minizinc/std/lex_chain_lesseq_orbitope.mzn b/share/minizinc/std/lex_chain_lesseq_orbitope.mzn deleted file mode 100644 index 1c6bc11..0000000 --- a/share/minizinc/std/lex_chain_lesseq_orbitope.mzn +++ /dev/null @@ -1,18 +0,0 @@ -include "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 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 1>=card(index_set_2of2(a)) then true - else fzn_lex_chain_lesseq_orbitope(a, kind) endif; - diff --git a/share/minizinc/std/piecewise_linear.mzn b/share/minizinc/std/piecewise_linear.mzn index a7ac30e..bcd5f83 100644 --- a/share/minizinc/std/piecewise_linear.mzn +++ b/share/minizinc/std/piecewise_linear.mzn @@ -2,8 +2,8 @@ include "fzn_piecewise_linear.mzn"; include "fzn_piecewise_linear_reif.mzn"; /** @group globals - Return the piecewise-linear function of x - on the given point-value sequence + Return a piecewise-linear interpolation + of the given point sequence as a function of \a x */ function var float: piecewise_linear(var float: x, array[int] of float: xi, array[int] of float: vi) ::promise_total = let { @@ -13,8 +13,8 @@ function var float: piecewise_linear(var float: x, array[int] of float: xi, arra /** @group globals - Constrains \a y(\a x) to be the piecewise-linear function - on the provided point-value sequence. + Constrains \a y(\a x) to be a piecewise-linear interpolation of + the provided point sequence. */ predicate piecewise_linear(var float: x, var float: y, array[int] of float: xi, array[int] of float: vi) = diff --git a/share/minizinc/std/piecewise_linear_non_continuous.mzn b/share/minizinc/std/piecewise_linear_non_continuous.mzn deleted file mode 100644 index e05718c..0000000 --- a/share/minizinc/std/piecewise_linear_non_continuous.mzn +++ /dev/null @@ -1,29 +0,0 @@ -include "fzn_piecewise_linear_non_continuous.mzn"; -include "fzn_piecewise_linear_non_continuous_reif.mzn"; - -/** @group globals - Return the piecewise-linear function of x - on the given (possibly disconnected) intervals. - Each interval \a i connects - (\a x_start[\a i], \a v_start[\a i]) to (\a x_end[\a i], \a v_end[\a 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 - Constrains \a y(\a x) to be the piecewise-linear function on - the provided point-value intervals. -*/ -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(x, y, x_start,x_end, v_start,v_end); - -%-----------------------------------------------------------------------------% diff --git a/share/minizinc/std/restart.mzn b/share/minizinc/std/restart.mzn index 629267d..2e8caf5 100644 --- a/share/minizinc/std/restart.mzn +++ b/share/minizinc/std/restart.mzn @@ -17,6 +17,12 @@ ann: on_restart(string: pred); enum STATUS = {START, UNKNOWN, UNSAT, SAT, OPT}; function var STATUS: status(); +/* + When complete is set to 'true', then it marks the search as complete. +*/ +predicate complete();% = abort("'complete' should be used in reified context"); +predicate complete_reif(var bool: marker); + /* The 'uniform' function provides random values chosen by the solver. The arguments to the function limit the values to a certain domain. @@ -134,4 +140,4 @@ predicate round_robin(array[int] of var bool: nbhs) = select = -1 else select = (sol(select) + 1) mod len - endif; \ No newline at end of file + endif; diff --git a/share/minizinc/std/stdlib/stdlib_coercion.mzn b/share/minizinc/std/stdlib/stdlib_coercion.mzn index 1c92209..0575458 100644 --- a/share/minizinc/std/stdlib/stdlib_coercion.mzn +++ b/share/minizinc/std/stdlib/stdlib_coercion.mzn @@ -13,11 +13,6 @@ function int: round(float: x); /** @group stdlib.coercion Return Boolean \a b coerced to an integer */ function int: bool2int(bool: b); - -/** @group stdlib.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.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 = @@ -30,10 +25,6 @@ function var opt int: bool2int(var opt bool: x) ::promise_total = /** @group stdlib.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.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.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 { @@ -53,9 +44,6 @@ function var float: bool2float(var bool: b) = int2float(bool2int(b)); /** @group stdlib.coercion Return integer \a x coerced to a float */ function float: int2float(int: x); /** @group stdlib.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.coercion Return integer \a x coerced to a float */ function var float: int2float(var int: x) ::promise_total; /** @group stdlib.arithmetic Return optional 0/1 float that is absent iff \a x @@ -99,24 +87,12 @@ function array[$T] of var int: bool2int(array[$T] of var bool: x) ::promise_tota array[int] of var bool: xx = array1d(x) } in arrayXd(x,[bool2int(xx[i]) | i in index_set(xx)]); -/** @group stdlib.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.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.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.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 { @@ -129,12 +105,6 @@ function array[$T] of float: int2float(array[$T] of int: x) ::promise_total = array[int] of int: xx = array1d(x) } in arrayXd(x,[int2float(xx[i]) | i in index_set(xx)]); -/** @group stdlib.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.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 { diff --git a/share/minizinc/std/stdlib/stdlib_internal.mzn b/share/minizinc/std/stdlib/stdlib_internal.mzn index 84c6219..d77d5c2 100644 --- a/share/minizinc/std/stdlib/stdlib_internal.mzn +++ b/share/minizinc/std/stdlib/stdlib_internal.mzn @@ -159,8 +159,6 @@ test mzn_in_root_context(var $T); 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 { @@ -1227,23 +1225,3 @@ function var float: min_t(array[int] of var float: x) :: promise_total = 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 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_); - int: max_range = card(index_set_1of2(ranges)); - } in if max_range=2 /\ ranges[1,2]=ranges[2,1]-2 then - x != ranges[1,2]+1 - else - x <= ranges[1,2] \/ x >= ranges[max_range,1] \/ - exists (i in 2..max_range-1) (x in ranges[i,1]..ranges[i,2]) - endif - endif; diff --git a/share/minizinc/std/stdlib/stdlib_math.mzn b/share/minizinc/std/stdlib/stdlib_math.mzn index dd58cf2..94d9766 100644 --- a/share/minizinc/std/stdlib/stdlib_math.mzn +++ b/share/minizinc/std/stdlib/stdlib_math.mzn @@ -218,20 +218,29 @@ function float: product(array[int] of opt float: x) = function $T: min( $T: x, $T: y); /** @group stdlib.arithmetic Return minimum of elements in array \a x */ function $T: min(array[$U] of par $T: x); -/** @group stdlib.arithmetic Return minimum of elements in \a x that are not absent. */ -function var int: min(array[int] of var opt int: x) = +/** @group stdlib.arithmetic Return minimum of elements in \a x that are not absent, or +absent if all elements in \a x are absent. */ +function var opt int: min(array[int] of var opt int: x) ::promise_total = let { - var lb_array(x)..ub_array(x): xmax = max(xi in x)(deopt(xi)); - % Array cannot be empty, otherwise min is undefined - constraint exists(xi in x)(occurs(xi)); - } in min([if occurs(xi) then deopt(xi) else xmax endif | xi in x]); -/** @group stdlib.arithmetic Return minimum of elements in \a x that are not absent. */ -function var float: min(array[int] of var opt float: x) = + var opt lb_array(x)..ub_array(x): m; + var lb_array(x)..ub_array(x): xmax; + constraint if ub(xmax) != infinity then xmax = ub(xmax) else forall (i in index_set(x)) (xmax >= deopt(x[i])) endif; + constraint occurs(m) <-> exists (i in index_set(x)) (occurs(x[i])); + constraint occurs(m) -> + deopt(m) = min([if occurs(xi) then deopt(xi) else xmax endif | xi in x]); + } in m; +/** @group stdlib.arithmetic Return minimum of elements in \a x that are not absent, or +absent if all elements in \a x are absent. */ +% :NOTE: since -oo is always a lb for float variables, should we instead return -oo if all absent? +function var opt float: min(array[int] of var opt float: x) ::promise_total = let { - var lb_array(x)..ub_array(x): xmax = max(xi in x)(deopt(xi)); - % Array cannot be empty, otherwise min is undefined - constraint exists(xi in x)(occurs(xi)); - } in min([if occurs(xi) then deopt(xi) else xmax endif | xi in x]); + var opt lb_array(x)..ub_array(x): m; + var lb_array(x)..ub_array(x): xmax; + constraint if ub(xmax) != infinity then xmax = ub(xmax) else forall (i in index_set(x)) (xmax >= deopt(x[i])) endif; + constraint occurs(m) <-> exists (i in index_set(x)) (occurs(x[i])); + constraint occurs(m) -> + deopt(m) = min([if occurs(xi) then deopt(xi) else xmax endif | xi in x]); + } in m; /** @group stdlib.arithmetic Return maximum of \a x and \a y */ function $T: max( $T: x, $T: y); @@ -239,11 +248,15 @@ function $T: max( $T: x, $T: y); function $T: max(array[$U] of $T: x); /** @group stdlib.arithmetic Return maximum of elements in \a x that are not absent, or absent if all elements in \a x are absent. */ -function var int: max(array[int] of var opt int: x) = +function var opt int: max(array[int] of var opt int: x) ::promise_total = let { - var lb_array(x)..ub_array(x): xmin = min(xi in x)(deopt(xi)); - constraint exists (xi in x) (occurs(xi)); - } in max([if occurs(xi) then deopt(xi) else xmin endif | xi in x]); + var opt lb_array(x)..ub_array(x): m; + var lb_array(x)..ub_array(x): xmin; + constraint if lb(xmin) != -infinity then xmin = lb(xmin) else forall (i in index_set(x)) (xmin <= deopt(x[i])) endif; + constraint occurs(m) <-> exists (i in index_set(x)) (occurs(x[i])); + constraint occurs(m) -> + deopt(m) = max([if occurs(xi) then deopt(xi) else xmin endif | xi in x]); + } in m; /** @group stdlib.arithmetic Return minimum of elements in set \a x */ function $$E: min(set of $$E: x); /** @group stdlib.arithmetic Return maximum of elements in set \a x */ @@ -261,12 +274,17 @@ function var int: max(array[$U] of var int: x) = array[int] of var int: xx = array1d(x); constraint length(x) >= 1; } in max_t(xx); -/** @group stdlib.arithmetic Return maximum of elements in \a x that are not absent. */ -function var float: max(array[int] of var opt float: x) = +/** @group stdlib.arithmetic Return maximum of elements in \a x that are not absent, or +absent if all elements in \a x are absent. */ +function var opt float: max(array[int] of var opt float: x) ::promise_total = let { - var lb_array(x)..ub_array(x): xmin = min(xi in x)(deopt(xi)); - constraint exists (xi in x) (occurs(xi)); - } in max([if occurs(xi) then deopt(xi) else xmin endif | xi in x]); + var opt lb_array(x)..ub_array(x): m; + var lb_array(x)..ub_array(x): xmin; + constraint if lb(xmin) != -infinity then xmin = lb(xmin) else forall (i in index_set(x)) (xmin <= deopt(x[i])) endif; + constraint occurs(m) <-> exists (i in index_set(x)) (occurs(x[i])); + constraint occurs(m) -> + deopt(m) = max([if occurs(xi) then deopt(xi) else xmin endif | xi in x]); + } in m; /** @group stdlib.arithmetic Return minimum of \a x and \a y */ function var int: min(var int: x, var int: y) :: promise_total = diff --git a/share/minizinc/std/strictly_decreasing.mzn b/share/minizinc/std/strictly_decreasing.mzn index 45f206a..f24e572 100644 --- a/share/minizinc/std/strictly_decreasing.mzn +++ b/share/minizinc/std/strictly_decreasing.mzn @@ -1,5 +1,4 @@ include "fzn_strictly_decreasing_int.mzn"; -include "fzn_strictly_decreasing_int_opt.mzn"; include "fzn_strictly_decreasing_int_reif.mzn"; include "fzn_strictly_decreasing_bool.mzn"; include "fzn_strictly_decreasing_bool_reif.mzn"; @@ -9,7 +8,6 @@ include "analyse_all_different.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) = analyse_all_different(array1d(x)) /\ fzn_strictly_decreasing_bool(array1d(x)); @@ -17,15 +15,9 @@ predicate strictly_decreasing(array[$X] of var bool: x) = predicate strictly_decreasing_reif(array[$X] of var bool: x, var bool: b) = fzn_strictly_decreasing_bool_reif(array1d(x),b); -/** @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 int: x) = analyse_all_different(array1d(x)) /\ fzn_strictly_decreasing_int(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) = - analyse_all_different(array1d(x)) /\ - fzn_strictly_decreasing_int_opt(array1d(x)); - predicate strictly_decreasing_reif(array[$X] of var int: x, var bool: b) = fzn_strictly_decreasing_int_reif(array1d(x),b); diff --git a/solvers/MIP/MIP_cplex_wrap.cpp b/solvers/MIP/MIP_cplex_wrap.cpp index 9a9f2ec..e06e894 100644 --- a/solvers/MIP/MIP_cplex_wrap.cpp +++ b/solvers/MIP/MIP_cplex_wrap.cpp @@ -1070,7 +1070,7 @@ MIPCplexWrapper::Status MIPCplexWrapper::convertStatus(int cplexStatus) { break; // case CPXMIP_ABORT_INFEAS: case CPXMIP_FAIL_INFEAS: - s = Status::ERROR_STATUS; + s = Status::__ERROR; break; default: // case CPXMIP_OPTIMAL_TOL: diff --git a/solvers/MIP/MIP_gurobi_wrap.cpp b/solvers/MIP/MIP_gurobi_wrap.cpp index 508e48e..350c721 100644 --- a/solvers/MIP/MIP_gurobi_wrap.cpp +++ b/solvers/MIP/MIP_gurobi_wrap.cpp @@ -461,10 +461,7 @@ std::vector MIPGurobiWrapper::getExtraFlags( param_name == GRB_DBL_PAR_NODEFILESTART || param_name == GRB_STR_PAR_NODEFILEDIR || param_name == GRB_DBL_PAR_MIPGAPABS || param_name == GRB_INT_PAR_MIPFOCUS || param_name == GRB_DBL_PAR_MIPGAP || param_name == GRB_DBL_PAR_INTFEASTOL || - param_name == GRB_DBL_PAR_FEASIBILITYTOL || -#ifdef GRB_INT_PAR_NONCONVEX - param_name == GRB_INT_PAR_NONCONVEX || -#endif + param_name == GRB_DBL_PAR_FEASIBILITYTOL || param_name == GRB_INT_PAR_NONCONVEX || param_name == GRB_INT_PAR_PRECRUSH || param_name == GRB_INT_PAR_LAZYCONSTRAINTS || param_name == GRB_STR_PAR_DUMMY) { // These parameters are handled by us or are not useful diff --git a/solvers/MIP/MIP_osicbc_wrap.cpp b/solvers/MIP/MIP_osicbc_wrap.cpp index ca3f23c..920bf83 100644 --- a/solvers/MIP/MIP_osicbc_wrap.cpp +++ b/solvers/MIP/MIP_osicbc_wrap.cpp @@ -656,7 +656,7 @@ MIPosicbcWrapper::Status MIPosicbcWrapper::convertStatus(CbcModel* pModel) { s = Status::SAT; output.statusName = "Feasible"; } else if (pModel->isAbandoned()) { // AFTER feas-ty - s = Status::ERROR_STATUS; + s = Status::__ERROR; output.statusName = "Abandoned"; } else { s = Status::UNKNOWN; @@ -680,7 +680,7 @@ MIPosicbcWrapper::Status MIPosicbcWrapper::convertStatus() { output.statusName = "Dual infeasible"; // s = Status::UNSATorUNBND; } else if (_osi.isAbandoned()) { - s = Status::ERROR_STATUS; + s = Status::__ERROR; output.statusName = "Abandoned"; } else if // wrong: (pModel->getColSolution()) (fabs(_osi.getObjValue()) < _osi.getInfinity()) { @@ -763,12 +763,12 @@ void MIPosicbcWrapper::solve() { // Move into ancestor? cerr << " Model creation..." << endl; } - // #define MZN_USE_CbcSolver -- not linked rev2274 + // #define __USE_CbcSolver__ -- not linked rev2274 /// FOR WARMSTART for (const auto& vv : _warmstart) { _osi.setColName(vv.first, colNames[vv.first]); } -#ifdef MZN_USE_CbcSolver +#ifdef __USE_CbcSolver__ CbcSolver control(osi); // initialize control.fillValuesInSolver(); @@ -938,14 +938,14 @@ void MIPosicbcWrapper::solve() { // Move into ancestor? // CbcCbcParamUtils::setCbcModelDefaults(model) ; // const char * argv2[]={"mzn-cbc","-solve","-quit"}; // CbcMain1(3,argv2,model); -#ifdef MZN_USE_CbcSolver +#ifdef __USE_CbcSolver__ if (fVerbose) cerr << " Calling control.solve() with options '" << options->cbcCmdOptions << "'..." << endl; control.solve(options->cbcCmdOptions.c_str(), 1); #else -#define MZN_USE_callCbc1 -#ifdef MZN_USE_callCbc1 +#define __USE_callCbc1__ +#ifdef __USE_callCbc1__ if (fVerbose) { cerr << " Calling CbcMain with command 'cbc"; for (const auto& arg : _options->cbcCmdOptions) { diff --git a/solvers/MIP/MIP_scip_wrap.cpp b/solvers/MIP/MIP_scip_wrap.cpp index b3c928f..0087dff 100644 --- a/solvers/MIP/MIP_scip_wrap.cpp +++ b/solvers/MIP/MIP_scip_wrap.cpp @@ -88,8 +88,6 @@ void ScipPlugin::load() { load_symbol(SCIPcreateConsBasicIndicator); load_symbol(SCIPcreateConsBasicBounddisjunction); load_symbol(SCIPcreateConsBasicCumulative); - load_symbol(SCIPcreateConsBasicOrbisack); - load_symbol(SCIPcreateConsBasicOrbitope); load_symbol(SCIPgetNSolsFound); load_symbol(SCIPgetNSols); load_symbol(SCIPsetIntParam); @@ -566,48 +564,6 @@ void MIPScipWrapper::addCumulative(int nnz, int* rmatind, double* d, double* r, SCIP_PLUGIN_CALL(_plugin->SCIPreleaseCons(_scip, &cons)); } -/// Lex-lesseq binary, currently SCIP only -/// TODO check all variables are binary, SCIP 7.0.2 does not -void MIPScipWrapper::addLexLesseq(int nnz, int* rmatind1, int* rmatind2, bool isModelCons, - const std::string& rowName) { - SCIP_CONS* cons; - vector vars1(nnz); - vector vars2(nnz); - - for (int j = 0; j < nnz; ++j) { - vars1[j] = _scipVars[rmatind1[j]]; - vars2[j] = _scipVars[rmatind2[j]]; - } - - SCIP_PLUGIN_CALL(_plugin->SCIPcreateConsBasicOrbisack( - _scip, &cons, rowName.c_str(), vars2.data(), vars1.data(), // it's actually lex_greatereq - nnz, FALSE, FALSE, (SCIP_Bool)isModelCons)); - SCIP_PLUGIN_CALL(_plugin->SCIPaddCons(_scip, cons)); - SCIP_PLUGIN_CALL(_plugin->SCIPreleaseCons(_scip, &cons)); -} - -/// Lex-chain-lesseq binary, currently SCIP only -void MIPScipWrapper::addLexChainLesseq(int m, int n, int* rmatind, int nOrbitopeType, - bool resolveprop, bool isModelCons, - const std::string& rowName) { - SCIP_CONS* cons; - vector > vars(m, vector(size_t(n))); - vector vars_data(m); - - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - vars[i][j] = _scipVars[rmatind[i * n + (n - j - 1)]]; // it's actually lex_chain_greatereq - } - vars_data[i] = vars[i].data(); - } - - SCIP_PLUGIN_CALL(_plugin->SCIPcreateConsBasicOrbitope( - _scip, &cons, rowName.c_str(), vars_data.data(), (SCIP_ORBITOPETYPE)nOrbitopeType, m, n, - (SCIP_Bool)resolveprop, (SCIP_Bool)isModelCons)); - SCIP_PLUGIN_CALL(_plugin->SCIPaddCons(_scip, cons)); - SCIP_PLUGIN_CALL(_plugin->SCIPreleaseCons(_scip, &cons)); -} - void MIPScipWrapper::addTimes(int x, int y, int z, const string& rowName) { /// As x*y - z == 0 double zCoef = -1.0; @@ -627,13 +583,8 @@ void MIPScipWrapper::addTimes(int x, int y, int z, const string& rowName) { #define EVENTHDLR_NAME "bestsol" #define EVENTHDLR_DESC "event handler for best solutions found" -namespace { // Dirty way of accessing SCIP functions inside C callbacks -ScipPlugin* _cb_plugin; - -MIPWrapper::CBUserInfo* cbuiPtr = nullptr; -SCIP_VAR** _scipVarsPtr = nullptr; -} // namespace +static ScipPlugin* _cb_plugin; /** initialization method of event handler (called after problem was transformed) */ static SCIP_DECL_EVENTINIT(eventInitBestsol) { /*lint --e{715}*/ @@ -661,6 +612,9 @@ static SCIP_DECL_EVENTEXIT(eventExitBestsol) { /*lint --e{715}*/ return SCIP_OKAY; } +static MIPWrapper::CBUserInfo* cbuiPtr = nullptr; +static SCIP_VAR** _scipVarsPtr = nullptr; + /** execution method of event handler */ static SCIP_DECL_EVENTEXEC(eventExecBestsol) { /*lint --e{715}*/ SCIP_SOL* bestsol; @@ -700,11 +654,7 @@ static SCIP_DECL_EVENTEXEC(eventExecBestsol) { /*lint --e{715}*/ cbuiPtr->pOutput->nOpenNodes = _cb_plugin->SCIPgetNNodesLeft(scip); cbuiPtr->pOutput->bestBound = _cb_plugin->SCIPgetDualbound(scip); - cbuiPtr->pOutput->dWallTime = std::chrono::duration(std::chrono::steady_clock::now() - - cbuiPtr->pOutput->dWallTime0) - .count(); - cbuiPtr->pOutput->dCPUTime = - double(std::clock() - cbuiPtr->pOutput->cCPUTime0) / CLOCKS_PER_SEC; + cbuiPtr->pOutput->dCPUTime = -1; /// Call the user function: if (cbuiPtr->solcbfn != nullptr) { diff --git a/solvers/MIP/MIP_xpress_wrap.cpp b/solvers/MIP/MIP_xpress_wrap.cpp index df40a45..faa00a7 100644 --- a/solvers/MIP/MIP_xpress_wrap.cpp +++ b/solvers/MIP/MIP_xpress_wrap.cpp @@ -449,7 +449,7 @@ static MIPWrapper::Status convert_status(int xpressStatus) { case XPRB_MIP_NO_SOL_FOUND: return MIPWrapper::Status::UNKNOWN; case XPRB_MIP_NOT_LOADED: - return MIPWrapper::Status::ERROR_STATUS; + return MIPWrapper::Status::__ERROR; default: return MIPWrapper::Status::UNKNOWN; } diff --git a/tests/benchmarking/cmp_result_logs.py b/tests/benchmarking/cmp_result_logs.py index 3d388da..781665c 100644 --- a/tests/benchmarking/cmp_result_logs.py +++ b/tests/benchmarking/cmp_result_logs.py @@ -60,7 +60,7 @@ class CompareLogs: ] ) ## which of those to print for each method - hdrTable2P = "stt chk objMZN objSLV bnd tFlt tBest" + hdrTable2P = "stt objMZN objSLV bnd tFlt tBest" hdrTable2P_spl = hdrTable2P.split( " " ) mapStatShort = { ## Short status names @@ -268,10 +268,10 @@ class CompareLogs: 0]; -array [int] of opt float: y :: add_to_output = [1, <>]; -array [int] of opt float: z :: add_to_output = [false, <>]; diff --git a/tests/spec/unit/regression/cse_array_lit.fzn b/tests/spec/unit/regression/cse_array_lit.fzn deleted file mode 100644 index 870aa17..0000000 --- a/tests/spec/unit/regression/cse_array_lit.fzn +++ /dev/null @@ -1,5 +0,0 @@ -array [1..2] of int: X_INTRODUCED_0_ = [1,-1]; -var 1..10: x:: output_var; -var 1..10: y:: output_var; -constraint int_lin_le(X_INTRODUCED_0_,[x,y],-1); -solve satisfy; diff --git a/tests/spec/unit/regression/cse_array_lit.mzn b/tests/spec/unit/regression/cse_array_lit.mzn deleted file mode 100644 index 49e00fe..0000000 --- a/tests/spec/unit/regression/cse_array_lit.mzn +++ /dev/null @@ -1,17 +0,0 @@ -/*** -!Test -type: compile -solvers: [gecode] -expected: !FlatZinc cse_array_lit.fzn -***/ - -% Regression test for #458 - -% In 2.5.4, par arrays were not inserted into the CSE, -% leading to duplicate variables and constraints in the FlatZinc. - -var 1..10: x; -var 1..10: y; - -constraint x < y; -constraint x < y; diff --git a/tests/spec/unit/regression/flatten_comp_in.mzn b/tests/spec/unit/regression/flatten_comp_in.mzn index 62c56fd..ac8b079 100644 --- a/tests/spec/unit/regression/flatten_comp_in.mzn +++ b/tests/spec/unit/regression/flatten_comp_in.mzn @@ -8,8 +8,8 @@ expected: !Result % Previously we would only eval_array_lit on the in part -array[int] of var bool: x :: add_to_output = [y=1 | y in let { - array [1..1] of var 1..2: z; +array[int] of var bool: x :: add_to_output = [y | y in let { + array [1..1] of var bool: z; } in z]; constraint x[1]; diff --git a/tests/spec/unit/regression/flatten_comp_in2.mzn b/tests/spec/unit/regression/flatten_comp_in2.mzn index bba9353..d1d4a5a 100644 --- a/tests/spec/unit/regression/flatten_comp_in2.mzn +++ b/tests/spec/unit/regression/flatten_comp_in2.mzn @@ -9,13 +9,13 @@ expected: bs: [true, false, true, false] ***/ -function array[int] of var int: func() = +function array[int] of var bool: func() = let { - array[1..2] of var 1..2: x; + array[1..2] of var bool: x; } in x; array[1..2] of var bool: as; -array[1..4] of var bool: bs ::add_to_output = [ a \/ x=1 | a in as, x in func() ]; +array[1..4] of var bool: bs ::add_to_output = [ a \/ x | a in as, x in func() ]; constraint bs[1] != bs[2]; constraint bs[2] != bs[3]; diff --git a/tests/spec/unit/regression/test_equality_of_indirect_annotations.mzn b/tests/spec/unit/regression/test_equality_of_indirect_annotations.mzn deleted file mode 100644 index 7f1de27..0000000 --- a/tests/spec/unit/regression/test_equality_of_indirect_annotations.mzn +++ /dev/null @@ -1,19 +0,0 @@ -/*** -!Test -strict: true -expected: !Result - status: SATISFIED -***/ - -% Equality of annotation expression was failing if the annotation was an input argument (behind some indirection) -ann: some_ann; -ann: another_ann; -function bool: is_some_ann(ann: input_ann) = - input_ann == some_ann; - -constraint is_some_ann(some_ann); - -% constraint trace("some_ann == some_ann \(some_ann == some_ann)\n"); % true :) -% constraint trace("some_ann == another_ann \(some_ann == another_ann)\n"); % false :) -% constraint trace("is_some_ann(some_ann) \(is_some_ann(some_ann))\n"); % was false :( -% constraint trace("is_some_ann(another_ann) \(is_some_ann(another_ann))\n"); % false :)