From f1b5a32c0073cab420562d60f6a75fcc41c35efd Mon Sep 17 00:00:00 2001 From: Azzaare <jf@baffier.fr> Date: Wed, 7 Aug 2024 13:41:07 +0900 Subject: [PATCH] Updates constraints --- docs/Manifest.toml | 44 +- docs/make.jl | 1 + .../src/constraints/comparison_constraints.md | 117 ++++ .../src/constraints/connection_constraints.md | 165 +++++ docs/src/constraints/constraint_commons.md | 32 +- docs/src/constraints/constraint_domains.md | 58 +- docs/src/constraints/constraints.md | 29 +- docs/src/constraints/constraints_jl.md | 48 ++ .../counting_summing_constraints.md | 188 +++++ docs/src/constraints/generic_constraints.md | 655 ------------------ .../packing_scheduling_constraints.md | 94 +++ 11 files changed, 703 insertions(+), 728 deletions(-) create mode 100644 docs/src/constraints/constraints_jl.md diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 04e7a98..ce3e639 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -67,9 +67,9 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "8c5b39db37c1d0340bf3b14895fba160c2d6cbb5" +git-tree-sha1 = "f54c23a5d304fb87110de62bace7777d59088c34" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.14.0" +version = "7.15.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -80,7 +80,7 @@ version = "7.14.0" ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" ArrayInterfaceReverseDiffExt = "ReverseDiff" ArrayInterfaceSparseArraysExt = "SparseArrays" - ArrayInterfaceStaticArraysExt = "StaticArrays" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" ArrayInterfaceTrackerExt = "Tracker" [deps.ArrayInterface.weakdeps] @@ -92,7 +92,7 @@ version = "7.14.0" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" [[deps.Artifacts]] @@ -238,19 +238,19 @@ weakdeps = ["InverseFunctions"] [[deps.ConstraintCommons]] deps = ["Dictionaries", "TestItems"] -git-tree-sha1 = "ca8e5cfedb33fc75c5ba0a52d3e222d3d3c2b9e9" +git-tree-sha1 = "779227189854f846de5f72b518e50dda14c7886b" repo-rev = "main" repo-url = "https://github.com/JuliaConstraints/ConstraintCommons.jl.git" uuid = "e37357d9-0691-492f-a822-e5ea6a920954" -version = "0.2.2" +version = "0.2.3" [[deps.ConstraintDomains]] -deps = ["ConstraintCommons", "Dictionaries", "Intervals", "PatternFolds", "StatsBase", "TestItems"] -git-tree-sha1 = "20000526022d536c3c9fcbb3e9d92b6d9eef16c2" +deps = ["ConstraintCommons", "Intervals", "PatternFolds", "StatsBase", "TestItems"] +git-tree-sha1 = "02380c829c947c0579864c51affa1646a170d037" repo-rev = "main" repo-url = "https://github.com/JuliaConstraints/ConstraintDomains.jl.git" uuid = "5800fd60-8556-4464-8d61-84ebf7a0bedb" -version = "0.3.12" +version = "0.3.13" [[deps.ConstraintLearning]] deps = ["CompositionalNetworks", "ConstraintDomains", "Constraints", "DataFrames", "Dictionaries", "Evolutionary", "Flux", "LocalSearchSolvers", "Memoization", "PrettyTables", "QUBOConstraints", "TestItems", "ThreadPools"] @@ -483,19 +483,21 @@ version = "2.23.1" [[deps.Flux]] deps = ["Adapt", "ChainRulesCore", "Compat", "Functors", "LinearAlgebra", "MLUtils", "MacroTools", "NNlib", "OneHotArrays", "Optimisers", "Preferences", "ProgressLogging", "Random", "Reexport", "SparseArrays", "SpecialFunctions", "Statistics", "Zygote"] -git-tree-sha1 = "edacf029ed6276301e455e34d7ceeba8cc34078a" +git-tree-sha1 = "3dacce10e977918008944bb223ddec455fab6c16" uuid = "587475ba-b771-5e3f-ad9e-33799f191a9c" -version = "0.14.16" +version = "0.14.17" [deps.Flux.extensions] FluxAMDGPUExt = "AMDGPU" FluxCUDAExt = "CUDA" FluxCUDAcuDNNExt = ["CUDA", "cuDNN"] + FluxEnzymeExt = "Enzyme" FluxMetalExt = "Metal" [deps.Flux.weakdeps] AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" cuDNN = "02a925ec-e4fe-4b08-9a7e-0d78e3d38ccd" @@ -511,9 +513,9 @@ weakdeps = ["StaticArrays"] [[deps.Functors]] deps = ["LinearAlgebra"] -git-tree-sha1 = "8a66c07630d6428eaab3506a0eabfcf4a9edea05" +git-tree-sha1 = "64d8e93700c7a3f28f717d265382d52fac9fa1c1" uuid = "d9f16b24-f501-4c13-a1f2-28368ffc5196" -version = "0.4.11" +version = "0.4.12" [[deps.Future]] deps = ["Random"] @@ -668,9 +670,9 @@ version = "0.9.22" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "020abd49586480c1be84f57da0017b5d3db73f7c" +git-tree-sha1 = "2470e69781ddd70b8878491233cd09bc1bd7fc96" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "8.0.0" +version = "8.1.0" [deps.LLVM.extensions] BFloat16sExt = "BFloat16s" @@ -680,9 +682,9 @@ version = "8.0.0" [[deps.LLVMExtra_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "c2636c264861edc6d305e6b4d528f09566d24c5e" +git-tree-sha1 = "597d1c758c9ae5d985ba4202386a607c675ee700" uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.30+0" +version = "0.0.31+0" [[deps.LaTeXStrings]] git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" @@ -803,9 +805,9 @@ version = "0.1.2" [[deps.MathOptInterface]] deps = ["BenchmarkTools", "CodecBzip2", "CodecZlib", "DataStructures", "ForwardDiff", "JSON", "LinearAlgebra", "MutableArithmetics", "NaNMath", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays", "SpecialFunctions", "Test", "Unicode"] -git-tree-sha1 = "91b08d27a27d83cf1e63e50837403e7f53a0fd74" +git-tree-sha1 = "c0fe113e9c72aa0c9a185fd3c5ca1daa51de1486" uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" -version = "1.31.0" +version = "1.31.1" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] @@ -852,9 +854,9 @@ version = "2023.1.10" [[deps.MutableArithmetics]] deps = ["LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "898c56fbf8bf71afb0c02146ef26f3a454e88873" +git-tree-sha1 = "d0a6b1096b584a2b88efb70a92f8cb8c881eb38a" uuid = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" -version = "1.4.5" +version = "1.4.6" [[deps.NLSolversBase]] deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] diff --git a/docs/make.jl b/docs/make.jl index 567f408..6aa62b0 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -77,6 +77,7 @@ makedocs(; "Internals" => [ "ConstraintCommons.jl" => "constraints/constraint_commons.md", "ConstraintDomains.jl" => "constraints/constraint_domains.md", + "Constraints.jl" => "constraints/constraints_jl.md", ], ], "Learning" => [ diff --git a/docs/src/constraints/comparison_constraints.md b/docs/src/constraints/comparison_constraints.md index ee70c3d..c02255a 100644 --- a/docs/src/constraints/comparison_constraints.md +++ b/docs/src/constraints/comparison_constraints.md @@ -4,6 +4,123 @@ CurrentModule = Constraints ``` +::: code-group + +```julia [JC-API] +using Constraints + +concept(:all_different, [1,1,1,2]) # false +concept(:all_different, [1,9,3,2]) # true +``` + +```julia [XCSP] +using Constraints + +c = x -> Constraints.xcsp_all_different( + list = x +) +@info c([1, 2, 3, 3]) # false +@info c([1, 2, 3, 4]) # true +``` + +```julia [JuMP] +using CBLS, JuMP + +model = Model(CBLS.Optimizer) +@variable(model, 1≤X[1:4]≤4, Int) +@variable(model, 0≤Y[1:4]≤2, Int) +@constraint(model, X in AllDifferent()) +@constraint(model, Y in AllDifferent(; vals = [0])) +JuMP.optimize!(model) +@info "All Different" value.(X) value.(Y) + +# Note that this example gives a solution for the all_different constraint. +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + +::: code-group + +```julia [JC-API] +using Constraints + +concept(:all_equal, [1,1,1,2]) #false +concept(:all_equal, [1,1,1,1]) #true +``` + +```julia [XCSP] +using Constraints + +c = x -> Constraints.xcsp_all_equal( + list = x +) + +@info c([1, 1, 1, 1]) # false +@info c([1, 2, 3, 4]) # true +``` + +```julia [JuMP] +using JuMP, CBLS + +model = Model(CBLS.Optimizer) +@variable(model, 0≤X[1:4]≤4, Int) +@constraint(model, X in AllEqual()) +JuMP.optimize!(model) +@info "All Equal" value.(X) + +# Note that this example gives a solution for the all_equal constraint. +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + +::: code-group + +```julia [JC-API] +using Constraints + +@info concept(:ordered, [1, 2, 3, 4, 4]; op=≤) +@info concept(:ordered, [1, 2, 3, 3, 5]; op=<) +@info concept(:increasing, [1,2,2,3]) +``` + +```julia [XCSP] +using Constraints + +c = x -> Constraints.xcsp_ordered( + list = x, + operator = ≥ +) + +@info c([1, 1, 1, 1]) +@info c([9, 3, 6, 8]) +``` + +```julia [JuMP] +using CBLS, JuMP + +model = Model(CBLS.Optimizer) +@variable(model, 1≤X[1:5]≤5, Int) +@variable(model, 1≤Y[1:5]≤5, Int) +@constraint(model, X in Ordered()) +@constraint(model, Y in Ordered(; op = <)) +JuMP.optimize!(model) +@info "Ordered" value.(X) value.(Y) +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + ### Comparison-based Constraints ```@docs; canonical=false diff --git a/docs/src/constraints/connection_constraints.md b/docs/src/constraints/connection_constraints.md index 46e2604..1c8f285 100644 --- a/docs/src/constraints/connection_constraints.md +++ b/docs/src/constraints/connection_constraints.md @@ -4,6 +4,171 @@ CurrentModule = Constraints ``` +::: code-group + +```julia [JC-API] +using Constraints + +concept(:maximum, [1,1,1,2], val = 2, op = ==) # true +concept(:maximum, [1,2,4,4], val = 2, op = ==) # false +``` + +```julia [XCSP] +using Constraints + +c = x -> Constraints.xcsp_maximum( + list = x, + condition = (==, 4) +) + +@info c([1, 1, 4, 1]) # true +@info c([1, 2, 3, 8]) # false +``` + +```julia [JuMP] +using CBLS, JuMP + +model = Model(CBLS.Optimizer) +@variable(model, 1≤X[1:5]≤5, Int) +@constraint(model, X in Maximum(; op = ==, val = 5)) +optimize!(model) +@info "Maximum" value.(X) +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + +::: code-group + +```julia [JC-API] +using Constraints + +concept(:minimum, [1,1,1,2], val = 1, op = ==) # true +concept(:minimum, [1,2,4,4], val = 2, op = ==) # false +``` + +```julia [XCSP] +using Constraints + +c = x -> Constraints.xcsp_minimum( + list = x, + condition = (==, 1) +) + +@info c([1, 1, 4, 1]) +@info c([0, 2, 3, 8]) +``` + +```julia [JuMP] +using CBLS, JuMP + +model = Model(CBLS.Optimizer) +@variable(model, 1≤X[1:5]≤5, Int) +@constraint(model, X in Minimum(; op = ==, val = 3)) +JuMP.optimize!(model) +@info "Minimum" value.(X) + +# Note that this example gives a solution for the minimum constraint. +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + +::: code-group + +```julia [JC-API] +using Constraints + +@info concept(:element, [1, 2, 3, 4, 5]; id=1, val=1) +@info concept(:element, [1, 2, 3, 4, 5]; id=1, val=2) +@info concept(:element, [1, 2, 3, 4, 2]) +@info concept(:element, [1, 2, 3, 4, 1]) +``` + +```julia [XCSP] +using Constraints + +c = x -> Constraints.xcsp_element( + list = x, + index = 1, + condition = (==, 3) +) + +@info c([3, 3, 10]) +@info c([1, 1, 4, 3]) +``` + +```julia [JuMP] +using CBLS, JuMP + +model = Model(CBLS.Optimizer) +@variable(model, 1≤X[1:5]≤5, Int) +@variable(model, 1≤Y[1:5]≤5, Int) +@variable(model, 0≤Z[1:5]≤5, Int) +@constraint(model, X in Element()) +@constraint(model, Y in Element(; id = 1, val = 1)) +@constraint(model, Z in Element(; id = 2, val = 2)) +JuMP.optimize!(model) +@info "Element" value.(X) value.(Y) value.(Z) +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + +::: code-group + +```julia [JC-API] +using Constraints + +@info concept(:channel, [2, 1, 4, 3]) +@info concept(:channel, [1, 2, 3, 4]) +@info concept(:channel, [2, 3, 1, 4]) +@info concept(:channel, [2, 1, 5, 3, 4, 2, 1, 4, 5, 3]; dim=2) +@info concept(:channel, [2, 1, 4, 3, 5, 2, 1, 4, 5, 3]; dim=2) +@info concept(:channel, [false, false, true, false]; id=3) +@info concept(:channel, [false, false, true, false]; id=1) +``` + +```julia [XCSP] +using Constraints + +c = x -> Constraints.xcsp_channel( + list = x +) + +@info c([2, 1, 4, 3]) +@info c([2, 3, 1, 4]) +``` + +```julia [JuMP] +using CBLS, JuMP + +model = Model(CBLS.Optimizer) +@variable(model, 1≤X[1:4]≤4, Int) +@variable(model, 1≤Y[1:10]≤5, Int) +@variable(model, 0≤Z[1:4]≤1, Int) +@constraint(model, X in CBLS.Channel()) +@constraint(model, Y in CBLS.Channel(; dim = 2)) +@constraint(model, Z in CBLS.Channel(; id = 3)) +JuMP.optimize!(model) +@info "Channel" value.(X) value.(Y) value.(Z) +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + ### Connection Constraints ```@docs; canonical=false diff --git a/docs/src/constraints/constraint_commons.md b/docs/src/constraints/constraint_commons.md index 707208c..b62f42e 100644 --- a/docs/src/constraints/constraint_commons.md +++ b/docs/src/constraints/constraint_commons.md @@ -21,8 +21,8 @@ extract_parameters ```@raw html <div style="display: flex; justify-content: space-between;"> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/bench_evolution_parameters.png?raw=true" alt="Bench Evolution Parameters" style="width:48%;"/> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/chair_evolution_parameters.png?raw=true" alt="Chair Evolution Parameters" style="width:48%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/bench_evolution_parameters.png?raw=true" alt="Bench Evolution Parameters" style="width:48%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/chair_evolution_parameters.png?raw=true" alt="Chair Evolution Parameters" style="width:48%;"/> </div> ``` @@ -44,16 +44,16 @@ at_end ```@raw html <div style="display: flex; flex-wrap: wrap; justify-content: space-between;"> <div style="flex: 1 1 48%; margin: 1%;"> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/bench_evolution_automata.png?raw=true" alt="Bench Evolution Automata" style="width:100%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/bench_evolution_automata.png?raw=true" alt="Bench Evolution Automata" style="width:100%;"/> </div> <div style="flex: 1 1 48%; margin: 1%;"> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/chair_evolution_automata.png?raw=true" alt="Chair Evolution Automata" style="width:100%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/chair_evolution_automata.png?raw=true" alt="Chair Evolution Automata" style="width:100%;"/> </div> <div style="flex: 1 1 48%; margin: 1%;"> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/bench_evolution_diagrams.png?raw=true" alt="Bench Evolution Diagrams" style="width:100%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/bench_evolution_diagrams.png?raw=true" alt="Bench Evolution Diagrams" style="width:100%;"/> </div> <div style="flex: 1 1 48%; margin: 1%;"> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/chair_evolution_diagrams.png?raw=true" alt="Chair Evolution Diagrams" style="width:100%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/chair_evolution_diagrams.png?raw=true" alt="Chair Evolution Diagrams" style="width:100%;"/> </div> </div> ``` @@ -73,16 +73,16 @@ consisempty ```@raw html <div style="display: flex; flex-wrap: wrap; justify-content: space-between;"> <div style="flex: 1 1 48%; margin: 1%;"> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/bench_evolution_nothing.png?raw=true" alt="Bench Evolution Nothing" style="width:100%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/bench_evolution_nothing.png?raw=true" alt="Bench Evolution Nothing" style="width:100%;"/> </div> <div style="flex: 1 1 48%; margin: 1%;"> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/chair_evolution_nothing.png?raw=true" alt="Chair Evolution Nothing" style="width:100%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/chair_evolution_nothing.png?raw=true" alt="Chair Evolution Nothing" style="width:100%;"/> </div> <div style="flex: 1 1 48%; margin: 1%;"> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/bench_evolution_symbols.png?raw=true" alt="Bench Evolution Symbols" style="width:100%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/bench_evolution_symbols.png?raw=true" alt="Bench Evolution Symbols" style="width:100%;"/> </div> <div style="flex: 1 1 48%; margin: 1%;"> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/chair_evolution_symbols.png?raw=true" alt="Chair Evolution Symbols" style="width:100%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/chair_evolution_symbols.png?raw=true" alt="Chair Evolution Symbols" style="width:100%;"/> </div> </div> ``` @@ -99,8 +99,8 @@ oversample ```@raw html <div style="display: flex; justify-content: space-between;"> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/bench_evolution_samplings.png?raw=true" alt="Bench Evolution" style="width:48%;"/> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/chair_evolution_samplings.png?raw=true" alt="Chair Evolution" style="width:48%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/bench_evolution_samplings.png?raw=true" alt="Bench Evolution" style="width:48%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/chair_evolution_samplings.png?raw=true" alt="Chair Evolution" style="width:48%;"/> </div> ``` @@ -114,8 +114,8 @@ We need to compute the difference between extrema of various kind of collections ```@raw html <div style="display: flex; justify-content: space-between;"> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/bench_evolution_extrema.png?raw=true" alt="Bench Evolution" style="width:48%;"/> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/chair_evolution_extrema.png?raw=true" alt="Chair Evolution" style="width:48%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/bench_evolution_extrema.png?raw=true" alt="Bench Evolution" style="width:48%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/chair_evolution_extrema.png?raw=true" alt="Chair Evolution" style="width:48%;"/> </div> ``` @@ -133,7 +133,7 @@ incsert! ```@raw html <div style="display: flex; justify-content: space-between;"> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/bench_evolution_dictionaries.png?raw=true" alt="Bench Evolution" style="width:48%;"/> - <img src="https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/main/perf/visuals/chair_evolution_dictionaries.png?raw=true" alt="Chair Evolution" style="width:48%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/bench_evolution_dictionaries.png?raw=true" alt="Bench Evolution" style="width:48%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintCommons/visuals/chair_evolution_dictionaries.png?raw=true" alt="Chair Evolution" style="width:48%;"/> </div> ``` \ No newline at end of file diff --git a/docs/src/constraints/constraint_domains.md b/docs/src/constraints/constraint_domains.md index e9679ca..c53f211 100644 --- a/docs/src/constraints/constraint_domains.md +++ b/docs/src/constraints/constraint_domains.md @@ -1,30 +1,12 @@ -# ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints +# ConstraintDomains.jl: Defining Variables and Exploring Domains ```@meta CurrentModule = ConstraintDomains ``` -*ConstraintDomains.jl* stands as a critical package within the *Julia Constraints* ecosystem, focusing on the definition and manipulation of variable domains that underpin the search spaces of constraint programming problems. This package provides the infrastructure necessary for specifying both discrete and continuous domains, thereby enabling a broad range of constraint programming applications. +*ConstraintDomains.jl* is the standard way to define variables and explore domains in the *Julia Constraints* ecosystem. This package can be used to specify both discrete and continuous domains. Explorations features are primarily related to learning about constraints, aka constraint learning. -## Key Features and Functionalities - -- **AbstractDomain Super Type**: At the foundation of ConstraintDomains.jl is the AbstractDomain type, an abstract supertype for all domain types. Implementations of AbstractDomain must provide methods for checking membership (∈), generating random elements (rand), and determining the domain's size or range (length). These functionalities are essential for defining the behavior and properties of variable domains within constraint models. - -- **Domain Types**: The package distinguishes between various domain types to cater to different needs: - - - *ContinuousDomain*: A supertype for domains representing continuous ranges of real numbers. - - *DiscreteDomain*: Serves as a supertype for domains defined by discrete sets or ranges of numbers. - - *EmptyDomain*: Handles yet-to-be-defined domains, facilitating dynamic problem formulation. - - *Intervals and RangeDomain*: Represent continuous intervals and discrete ranges, respectively, providing flexible domain specification options. -- **Dynamic Domain Manipulation**: ConstraintDomains.jl supports dynamic changes to domains, allowing for the addition (add!) and deletion (delete!) of elements, crucial for problems where domain definitions evolve based on the search process or external inputs. - -- **Exploration Settings and Methods**: The package offers ExploreSettings to configure the exploration of search spaces, including parameters for complete searches, maximum samplings, and solution limits. This feature is pivotal for tailoring the search process to the problem's characteristics and the computational resources available. - -- **Support for Advanced Modeling**: Beyond basic domain definition and manipulation, ConstraintDomains.jl integrates with learning and parameter exploration tools. For instance, FakeAutomaton facilitates the generation of pseudo-automata for parameter exploration, while the package also provides functions for generating random parameters (generate_parameters), accessing domain internals (get_domain), and merging or intersecting domains (merge_domains, intersect_domains). - -## Empowering Constraint Programming in Julia - -ConstraintDomains.jl embodies the versatility and power of the JuliaConstraints ecosystem, offering users a comprehensive toolkit for defining and exploring variable domains. By abstracting complex domain manipulations and providing a rich set of functionalities, ConstraintDomains.jl enhances the ease and efficiency of modeling constraint programming problems. Whether for educational purposes, research, or practical applications, this package lays the groundwork for advanced problem-solving strategies in the realm of constraint programming. +Most users should use it through JuMP/MOI interfaces. ## Commons @@ -49,6 +31,13 @@ Base.string ### Performances +```@raw html +<div style="display: flex; justify-content: space-between;"> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintDomains/visuals/bench_evolution_common.png?raw=true" alt="Bench Evolution Common" style="width:48%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintDomains/visuals/chair_evolution_common.png?raw=true" alt="Chair Evolution Common" style="width:48%;"/> +</div> +``` + ## Continuous ```@docs; canonical=false @@ -71,6 +60,15 @@ Base.in Base.string ``` +### Performances + +```@raw html +<div style="display: flex; justify-content: space-between;"> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintDomains/visuals/bench_evolution_continuous.png?raw=true" alt="Bench Evolution Continuous" style="width:48%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintDomains/visuals/chair_evolution_continuous.png?raw=true" alt="Chair Evolution Continuous" style="width:48%;"/> +</div> +``` + ## Discrete ```@docs; canonical=false @@ -97,6 +95,15 @@ Base.in Base.string ``` +### Performances + +```@raw html +<div style="display: flex; justify-content: space-between;"> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintDomains/visuals/bench_evolution_discrete.png?raw=true" alt="Bench Evolution Discrete" style="width:48%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintDomains/visuals/chair_evolution_discrete.png?raw=true" alt="Chair Evolution Discrete" style="width:48%;"/> +</div> +``` + ## General ```@docs; canonical=false @@ -112,6 +119,15 @@ _explore explore ``` +### Performances + +```@raw html +<div style="display: flex; justify-content: space-between;"> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintDomains/visuals/bench_evolution_explore.png?raw=true" alt="Bench Evolution Exploration" style="width:48%;"/> + <img src="https://github.com/JuliaConstraints/Benchmarks/blob/main/ConstraintDomains/visuals/chair_evolution_explore.png?raw=true" alt="Chair Evolution Exploration" style="width:48%;"/> +</div> +``` + ## Parameters ```@docs; canonical=false diff --git a/docs/src/constraints/constraints.md b/docs/src/constraints/constraints.md index 5ead229..d39ed7e 100644 --- a/docs/src/constraints/constraints.md +++ b/docs/src/constraints/constraints.md @@ -4,11 +4,12 @@ CurrentModule = Constraints ``` -*Constraints.jl* is a pivotal package within Julia Constraints, designed to facilitate the definition, manipulation, and application of constraints in constraint programming (CP). +*Constraints.jl* is designed to facilitate the definition, manipulation, and application of constraints in constraint programming (CP). -It also acts as a catalog of various information and features learned about constraints by the learning part of the ecosystem. Per design, we only store the practical information extracted by those tools and not the heavy machinery. +!!! note + It also acts as a catalog of various information and features learned about constraints by the learning part of the ecosystem. Per design, we only store the practical information extracted by those tools (such as CompositionalNetworks or QUBOConstraints) and not the heavy machinery (ConstraintLearning). -## Usual Parameters +## Usual Constraints and Parameters The usual constraints of Julia Constraints are heavily inspired by the core constraints of the *XCSP3-core* standard. The main difference lies in the name chosen to describe the different parameters those core constraints can have. @@ -18,6 +19,15 @@ In *XCSP3*, the parameters are described based on their roles, which the user ca USUAL_CONSTRAINT_PARAMETERS ``` +We provide a couple of methods to navigate the usual constraints extracted from *XCSP3-Core*. + +```@docs; canonical=false +USUAL_CONSTRAINTS +describe +constraints_parameters +constraints_descriptions +``` + ## Concepts, Error Functions, and QUBO matrices One major use of this collection of usual constraint is to extract the `concept` or the error function (`error_f`) of a given constraint. @@ -28,21 +38,10 @@ concept Note that the error function is a finer estimation of how much a constraint is violated or not. By default, the `error_f` method simply return ``0.`` if the constraint is satisfied or ``1.`` otherwise. -Efficient versions of `error_r` are either hand-coded or generated through `CompositionalNetworks.jl`. +Efficient versions of `error_f` are either hand-coded or generated through `CompositionalNetworks.jl`. ```@docs; canonical=false error_f ``` Finally, another use is to provide `QUBO` matrices of those usual constraints through `QUBOConstraints.jl`. The syntax and interface for this feature are still a work in progress. - -## Usual Constraints - -We provide a couple of methods to navigate the usual constraints extracted from *XCSP3-Core*. - -```@docs; canonical=false -USUAL_CONSTRAINTS -describe -constraints_parameters -constraints_descriptions -``` diff --git a/docs/src/constraints/constraints_jl.md b/docs/src/constraints/constraints_jl.md new file mode 100644 index 0000000..5ead229 --- /dev/null +++ b/docs/src/constraints/constraints_jl.md @@ -0,0 +1,48 @@ +# Interacting with Constraints in Julia + +```@meta +CurrentModule = Constraints +``` + +*Constraints.jl* is a pivotal package within Julia Constraints, designed to facilitate the definition, manipulation, and application of constraints in constraint programming (CP). + +It also acts as a catalog of various information and features learned about constraints by the learning part of the ecosystem. Per design, we only store the practical information extracted by those tools and not the heavy machinery. + +## Usual Parameters + +The usual constraints of Julia Constraints are heavily inspired by the core constraints of the *XCSP3-core* standard. The main difference lies in the name chosen to describe the different parameters those core constraints can have. + +In *XCSP3*, the parameters are described based on their roles, which the user can find as keyword argument in the `xcsp_` prefixed collection of constraints (for instance `xcsp_all_different`). In our the Julia Constraints API (`JC-API`), the keyword arguments correspond to the nature of each parameter. + +```@docs; canonical=false +USUAL_CONSTRAINT_PARAMETERS +``` + +## Concepts, Error Functions, and QUBO matrices + +One major use of this collection of usual constraint is to extract the `concept` or the error function (`error_f`) of a given constraint. + +```@docs; canonical=false +concept +``` + +Note that the error function is a finer estimation of how much a constraint is violated or not. By default, the `error_f` method simply return ``0.`` if the constraint is satisfied or ``1.`` otherwise. + +Efficient versions of `error_r` are either hand-coded or generated through `CompositionalNetworks.jl`. + +```@docs; canonical=false +error_f +``` + +Finally, another use is to provide `QUBO` matrices of those usual constraints through `QUBOConstraints.jl`. The syntax and interface for this feature are still a work in progress. + +## Usual Constraints + +We provide a couple of methods to navigate the usual constraints extracted from *XCSP3-Core*. + +```@docs; canonical=false +USUAL_CONSTRAINTS +describe +constraints_parameters +constraints_descriptions +``` diff --git a/docs/src/constraints/counting_summing_constraints.md b/docs/src/constraints/counting_summing_constraints.md index e8d7601..438caf0 100644 --- a/docs/src/constraints/counting_summing_constraints.md +++ b/docs/src/constraints/counting_summing_constraints.md @@ -4,6 +4,194 @@ CurrentModule = Constraints ``` +::: code-group + +```julia [JC-API] +using Constraints + +@info concept(:sum, [1, 2, 3, 4, 5]; op = ==, val=15) +@info concept(:sum, [1, 2, 3, 4, 5]; op = ==, val=2) +@info concept(:sum, [1, 2, 3, 4, 3]; op = ≤, val=15) +@info concept(:sum, [1, 2, 3, 4, 3]; op = ≤, val=3) + +``` + +```julia [XCSP] +using Constraints + +c = x -> Constraints.xcsp_sum( + list = x, + condition = (>, 4), + coeffs = [1,2,3,4] +) + +@info c([1, 1, 1, 1]) +@info c([0, 1, 0, 0]) +``` + +```julia [JuMP] +using CBLS, JuMP + +model = Model(CBLS.Optimizer) +@variable(model, 1≤X[1:5]≤5, Int) +@variable(model, 1≤Y[1:5]≤5, Int) +@constraint(model, X in Sum(; op = ==, val = 15)) +@constraint(model, Y in Sum(; op = <=, val = 10)) +JuMP.optimize!(model) +@info "Sum" value.(X) value.(Y) +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + +::: code-group + +```julia [JC-API] +using Constraints + +concept(:count, [1,1,1,2], vals = [1, 1, 1, 2], op = ==, val = 4) # true +concept(:count, [1,1,1,2], vals = [1, 1, 1, 2], op = ==, val = 5) # false +concept(:count, [2, 1, 4, 3]; vals=[1, 2, 3, 4], op=≥, val=2) # true +concept(:at_least, [1,1,1,2], vals = [1, 1, 1, 2], val = 4) # true +concept(:at_least, [1,1,1,2], vals = [1, 2], val = 4) # true +concept(:at_least, [1,1,1,2], vals = [1, 3], val = 4) # false +concept(:at_most, [1,1,1,2], vals = [1, 1, 1, 2], val = 4) # true +concept(:at_most, [1,1,1,2], vals = [2, 5, 3], val = 2) #true +concept(:at_most, [1,1,1,2], vals = [1, 1, 1, 3], val = 3) # true +concept(:exactly, [1,1,1,2], vals = [1, 3, 4, 2], val = 4) # true +concept(:exactly, [1,1,1,2], vals = [1, 1, 2, 3], val = 4) # true +concept(:exactly, [1,1,1,2], vals = [1, 1, 1, 3], val = 4) # false +``` + +```julia [XCSP] +using Constraints + +c_count = x -> Constraints.xcsp_count( + list = x, + condition = (≥, 4), + values = [1, 2, 3] +) + +@info c_count([1, 1, 1, 1, 5]) # true +@info c_count([0, 2, 3, 8]) # false +``` + +```julia [JuMP] +using CBLS, JuMP + +model = Model(CBLS.Optimizer) +@variable(model, 1≤X[1:4]≤4, Int) +@variable(model, 1≤X_at_least[1:4]≤4, Int) +@variable(model, 1≤X_at_most[1:4]≤4, Int) +@variable(model, 1≤X_exactly[1:4]≤4, Int) +@constraint(model, X in Count(vals = [1, 2, 3, 4], op = ≥, val = 2)) +@constraint(model, X_at_least in AtLeast(vals = [1, 2, 3, 4], val = 2)) +@constraint(model, X_at_most in AtMost(vals = [1, 2], val = 1)) +@constraint(model, X_exactly in Exactly(vals = [1, 2], val = 2)) +JuMP.optimize!(model) +@info "Count" value.(X) value.(X_at_least) value.(X_at_most) value.(X_exactly) +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + +::: code-group + +```julia [JC-API] +using Constraints + +@info concept(:nvalues, [1, 2, 3, 4, 5]; op = ==, val = 5) +@info concept(:nvalues, [1, 2, 3, 4, 5]; op = ==, val = 2) +@info concept(:nvalues, [1, 2, 3, 4, 3]; op = <=, val = 5) +@info concept(:nvalues, [1, 2, 3, 4, 3]; op = <=, val = 3) +``` + +```julia [XCSP] +using Constraints + +c = x -> Constraints.xcsp_nvalues( + list = x, + condition = (≥, 3), + except = [1,2,3,4] +) + +@info c([1, 1, 1, 1]) +@info c([9, 3, 6, 8]) +``` + +```julia [JuMP] +using CBLS, JuMP + +model = Model(CBLS.Optimizer) +@variable(model, 1≤X[1:5]≤5, Int) +@variable(model, 1≤Y[1:5]≤5, Int) +@variable(model, 1≤Z[1:5]≤5, Int) +@constraint(model, X in NValues(; op = ==, val = 5)) +@constraint(model, Y in NValues(; op = ==, val = 2)) +@constraint(model, Z in NValues(; op = <=, val = 5, vals = [1, 2])) +JuMP.optimize!(model) +@info "NValues" value.(X) value.(Y) value.(Z) +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + +::: code-group + +```julia [JC-API] +using Constraints + +# [v1, v2, v3], [v1, a1, a2; v2, b1, b2; v3, c1, c2] means v1 occurs between a1 and a2 times in the first array, similar for v2 and v3. + +@info concept(:cardinality, [2, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) +@info concept(:cardinality, [8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=false) +@info concept(:cardinality, [8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=true) +@info concept(:cardinality, [2, 5, 10, 10]; vals=[2 1; 5 1; 10 2]) +@info concept(:cardinality_closed, [8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) +@info concept(:cardinality_open, [8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) +``` + +```julia [XCSP] +using Constraints + +c = x -> Constraints.xcsp_cardinality( + list = x, + values = [1, 2], + occurs = [2 3; 1 5] +) + +@info c([1, 2, 1, 2]) +``` + +```julia [JuMP] +using CBLS, JuMP + +model = Model(CBLS.Optimizer) +@variable(model, 1≤X[1:4]≤10, Int) +@variable(model, 1≤Y[1:4]≤10, Int) +@variable(model, 1≤Z[1:4]≤10, Int) +@constraint(model, X in Cardinality(; vals = [2 0 1; 5 1 3; 10 2 3])) +@constraint(model, Y in CardinalityOpen(; vals = [2 0 1; 5 1 3; 10 2 3])) +@constraint(model, Z in CardinalityClosed(; vals = [2 0 1; 5 1 3; 10 2 3])) +JuMP.optimize!(model) +@info "Cardinality" value.(X) value.(Y) value.(Z) +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + ### Counting and Summing Constraints ```@docs; canonical=false diff --git a/docs/src/constraints/generic_constraints.md b/docs/src/constraints/generic_constraints.md index acf28ea..51554d0 100644 --- a/docs/src/constraints/generic_constraints.md +++ b/docs/src/constraints/generic_constraints.md @@ -91,661 +91,6 @@ optimize!(model) ::: -::: code-group - -```julia [JC-API] -using Constraints - -concept(:all_equal, [1,1,1,2]) #false -concept(:all_equal, [1,1,1,1]) #true -``` - -```julia [XCSP] -using Constraints - -c = x -> Constraints.xcsp_all_equal( - list = x -) - -@info c([1, 1, 1, 1]) # false -@info c([1, 2, 3, 4]) # true -``` - -```julia [JuMP] -using JuMP, CBLS - -model = Model(CBLS.Optimizer) -@variable(model, 0≤X[1:4]≤4, Int) -@constraint(model, X in AllEqual()) -JuMP.optimize!(model) -@info "All Equal" value.(X) - -# Note that this example gives a solution for the all_equal constraint. -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - -concept(:minimum, [1,1,1,2], val = 1, op = ==) # true -concept(:minimum, [1,2,4,4], val = 2, op = ==) # false -``` - -```julia [XCSP] -using Constraints - -c = x -> Constraints.xcsp_minimum( - list = x, - condition = (==, 1) -) - -@info c([1, 1, 4, 1]) -@info c([0, 2, 3, 8]) -``` - -```julia [JuMP] -using CBLS, JuMP - -model = Model(CBLS.Optimizer) -@variable(model, 1≤X[1:5]≤5, Int) -@constraint(model, X in Minimum(; op = ==, val = 3)) -JuMP.optimize!(model) -@info "Minimum" value.(X) - -# Note that this example gives a solution for the minimum constraint. -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - -concept(:maximum, [1,1,1,2], val = 2, op = ==) # true -concept(:maximum, [1,2,4,4], val = 2, op = ==) # false -``` - -```julia [XCSP] -using Constraints - -c = x -> Constraints.xcsp_maximum( - list = x, - condition = (==, 4) -) - -@info c([1, 1, 4, 1]) # true -@info c([1, 2, 3, 8]) # false -``` - -```julia [JuMP] -using CBLS, JuMP - -model = Model(CBLS.Optimizer) -@variable(model, 1≤X[1:5]≤5, Int) -@constraint(model, X in Maximum(; op = ==, val = 5)) -optimize!(model) -@info "Maximum" value.(X) -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - -concept(:all_different, [1,1,1,2]) # false -concept(:all_different, [1,9,3,2]) # true -``` - -```julia [XCSP] -using Constraints - -c = x -> Constraints.xcsp_all_different( - list = x -) -@info c([1, 2, 3, 3]) # false -@info c([1, 2, 3, 4]) # true -``` - -```julia [JuMP] -using CBLS, JuMP - -model = Model(CBLS.Optimizer) -@variable(model, 1≤X[1:4]≤4, Int) -@variable(model, 0≤Y[1:4]≤2, Int) -@constraint(model, X in AllDifferent()) -@constraint(model, Y in AllDifferent(; vals = [0])) -JuMP.optimize!(model) -@info "All Different" value.(X) value.(Y) - -# Note that this example gives a solution for the all_different constraint. -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - -concept(:count, [1,1,1,2], vals = [1, 1, 1, 2], op = ==, val = 4) # true -concept(:count, [1,1,1,2], vals = [1, 1, 1, 2], op = ==, val = 5) # false -concept(:count, [2, 1, 4, 3]; vals=[1, 2, 3, 4], op=≥, val=2) # true -concept(:at_least, [1,1,1,2], vals = [1, 1, 1, 2], val = 4) # true -concept(:at_least, [1,1,1,2], vals = [1, 2], val = 4) # true -concept(:at_least, [1,1,1,2], vals = [1, 3], val = 4) # false -concept(:at_most, [1,1,1,2], vals = [1, 1, 1, 2], val = 4) # true -concept(:at_most, [1,1,1,2], vals = [2, 5, 3], val = 2) #true -concept(:at_most, [1,1,1,2], vals = [1, 1, 1, 3], val = 3) # true -concept(:exactly, [1,1,1,2], vals = [1, 3, 4, 2], val = 4) # true -concept(:exactly, [1,1,1,2], vals = [1, 1, 2, 3], val = 4) # true -concept(:exactly, [1,1,1,2], vals = [1, 1, 1, 3], val = 4) # false -``` - -```julia [XCSP] -using Constraints - -c_count = x -> Constraints.xcsp_count( - list = x, - condition = (≥, 4), - values = [1, 2, 3] -) - -@info c_count([1, 1, 1, 1, 5]) # true -@info c_count([0, 2, 3, 8]) # false -``` - -```julia [JuMP] -using CBLS, JuMP - -model = Model(CBLS.Optimizer) -@variable(model, 1≤X[1:4]≤4, Int) -@variable(model, 1≤X_at_least[1:4]≤4, Int) -@variable(model, 1≤X_at_most[1:4]≤4, Int) -@variable(model, 1≤X_exactly[1:4]≤4, Int) -@constraint(model, X in Count(vals = [1, 2, 3, 4], op = ≥, val = 2)) -@constraint(model, X_at_least in AtLeast(vals = [1, 2, 3, 4], val = 2)) -@constraint(model, X_at_most in AtMost(vals = [1, 2], val = 1)) -@constraint(model, X_exactly in Exactly(vals = [1, 2], val = 2)) -JuMP.optimize!(model) -@info "Count" value.(X) value.(X_at_least) value.(X_at_most) value.(X_exactly) -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - -@info concept(:sum, [1, 2, 3, 4, 5]; op = ==, val=15) -@info concept(:sum, [1, 2, 3, 4, 5]; op = ==, val=2) -@info concept(:sum, [1, 2, 3, 4, 3]; op = ≤, val=15) -@info concept(:sum, [1, 2, 3, 4, 3]; op = ≤, val=3) - -``` - -```julia [XCSP] -using Constraints - -c = x -> Constraints.xcsp_sum( - list = x, - condition = (>, 4), - coeffs = [1,2,3,4] -) - -@info c([1, 1, 1, 1]) -@info c([0, 1, 0, 0]) -``` - -```julia [JuMP] -using CBLS, JuMP - -model = Model(CBLS.Optimizer) -@variable(model, 1≤X[1:5]≤5, Int) -@variable(model, 1≤Y[1:5]≤5, Int) -@constraint(model, X in Sum(; op = ==, val = 15)) -@constraint(model, Y in Sum(; op = <=, val = 10)) -JuMP.optimize!(model) -@info "Sum" value.(X) value.(Y) -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - -@info concept(:nvalues, [1, 2, 3, 4, 5]; op = ==, val = 5) -@info concept(:nvalues, [1, 2, 3, 4, 5]; op = ==, val = 2) -@info concept(:nvalues, [1, 2, 3, 4, 3]; op = <=, val = 5) -@info concept(:nvalues, [1, 2, 3, 4, 3]; op = <=, val = 3) -``` - -```julia [XCSP] -using Constraints - -c = x -> Constraints.xcsp_nvalues( - list = x, - condition = (≥, 3), - except = [1,2,3,4] -) - -@info c([1, 1, 1, 1]) -@info c([9, 3, 6, 8]) -``` - -```julia [JuMP] -using CBLS, JuMP - -model = Model(CBLS.Optimizer) -@variable(model, 1≤X[1:5]≤5, Int) -@variable(model, 1≤Y[1:5]≤5, Int) -@variable(model, 1≤Z[1:5]≤5, Int) -@constraint(model, X in NValues(; op = ==, val = 5)) -@constraint(model, Y in NValues(; op = ==, val = 2)) -@constraint(model, Z in NValues(; op = <=, val = 5, vals = [1, 2])) -JuMP.optimize!(model) -@info "NValues" value.(X) value.(Y) value.(Z) -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - -# [v1, v2, v3], [v1, a1, a2; v2, b1, b2; v3, c1, c2] means v1 occurs between a1 and a2 times in the first array, similar for v2 and v3. - -@info concept(:cardinality, [2, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) -@info concept(:cardinality, [8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=false) -@info concept(:cardinality, [8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=true) -@info concept(:cardinality, [2, 5, 10, 10]; vals=[2 1; 5 1; 10 2]) -@info concept(:cardinality_closed, [8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) -@info concept(:cardinality_open, [8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) -``` - -```julia [XCSP] -using Constraints - -c = x -> Constraints.xcsp_cardinality( - list = x, - values = [1, 2], - occurs = [2 3; 1 5] -) - -@info c([1, 2, 1, 2]) -``` - -```julia [JuMP] -using CBLS, JuMP - -model = Model(CBLS.Optimizer) -@variable(model, 1≤X[1:4]≤10, Int) -@variable(model, 1≤Y[1:4]≤10, Int) -@variable(model, 1≤Z[1:4]≤10, Int) -@constraint(model, X in Cardinality(; vals = [2 0 1; 5 1 3; 10 2 3])) -@constraint(model, Y in CardinalityOpen(; vals = [2 0 1; 5 1 3; 10 2 3])) -@constraint(model, Z in CardinalityClosed(; vals = [2 0 1; 5 1 3; 10 2 3])) -JuMP.optimize!(model) -@info "Cardinality" value.(X) value.(Y) value.(Z) -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - -@info concept(:ordered, [1, 2, 3, 4, 4]; op=≤) -@info concept(:ordered, [1, 2, 3, 3, 5]; op=<) -@info concept(:increasing, [1,2,2,3]) -``` - -```julia [XCSP] -using Constraints - -c = x -> Constraints.xcsp_ordered( - list = x, - operator = ≥ -) - -@info c([1, 1, 1, 1]) -@info c([9, 3, 6, 8]) -``` - -```julia [JuMP] -using CBLS, JuMP - -model = Model(CBLS.Optimizer) -@variable(model, 1≤X[1:5]≤5, Int) -@variable(model, 1≤Y[1:5]≤5, Int) -@constraint(model, X in Ordered()) -@constraint(model, Y in Ordered(; op = <)) -JuMP.optimize!(model) -@info "Ordered" value.(X) value.(Y) -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - -@info concept(:cumulative, [1, 2, 3, 4, 5]; val = 1) -@info concept(:cumulative, [1, 2, 2, 4, 5]; val = 1) -@info concept(:cumulative, [1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = ≤, val = 5) -@info concept(:cumulative, [1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5) -``` - -```julia [XCSP] -using Constraints - -c = x -> Constraints.xcsp_cumulative( - origins = x, - lengths = [3, 2, 5, 4, 2], - heights = [1, 2, 1, 1, 3], - condition = (≤, 5) -) - -@info c([1, 2, 3, 4, 5]) -@info c([1, 1, 1, 2, 2]) -``` - -```julia [JuMP] -using CBLS, JuMP - -model = Model(CBLS.Optimizer) -@variable(model, 1≤X[1:5]≤5, Int) -@variable(model, 1≤Y[1:5]≤5, Int) -@variable(model, 1≤Z[1:5]≤5, Int) -@constraint(model, X in Cumulative(; val = 1)) -@constraint(model, - Y in Cumulative(; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = ≤, val = 5)) -@constraint(model, - Z in Cumulative(; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5)) -JuMP.optimize!(model) -@info "Cumulative" value.(X) value.(Y) value.(Z) -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - -@info concept(:channel, [2, 1, 4, 3]) -@info concept(:channel, [1, 2, 3, 4]) -@info concept(:channel, [2, 3, 1, 4]) -@info concept(:channel, [2, 1, 5, 3, 4, 2, 1, 4, 5, 3]; dim=2) -@info concept(:channel, [2, 1, 4, 3, 5, 2, 1, 4, 5, 3]; dim=2) -@info concept(:channel, [false, false, true, false]; id=3) -@info concept(:channel, [false, false, true, false]; id=1) -``` - -```julia [XCSP] -using Constraints - -c = x -> Constraints.xcsp_channel( - list = x -) - -@info c([2, 1, 4, 3]) -@info c([2, 3, 1, 4]) -``` - -```julia [JuMP] -using CBLS, JuMP - -model = Model(CBLS.Optimizer) -@variable(model, 1≤X[1:4]≤4, Int) -@variable(model, 1≤Y[1:10]≤5, Int) -@variable(model, 0≤Z[1:4]≤1, Int) -@constraint(model, X in CBLS.Channel()) -@constraint(model, Y in CBLS.Channel(; dim = 2)) -@constraint(model, Z in CBLS.Channel(; id = 3)) -JuMP.optimize!(model) -@info "Channel" value.(X) value.(Y) value.(Z) -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - -@info concept(:no_overlap, [1, 2, 3, 4, 5]) -@info concept(:no_overlap, [1, 2, 3, 4, 1]) -@info concept(:no_overlap, [1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 1, 1]) -@info concept(:no_overlap, [1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 3, 1]) -@info concept(:no_overlap, [1, 2, 4, 6, 3]; pair_vars = [1, 1, 3, 1, 1]) -``` - -```julia [XCSP] -using Constraints - -c = x -> Constraints.xcsp_no_overlap( - origins = x, - lengths = [1, 4, 10], - zero_ignored = true -) - -@info c([1, 3, 10]) -@info c([2, 1, 4, 3]) -``` - -```julia [JuMP] -using CBLS, JuMP - -model = Model(CBLS.Optimizer) -@variable(model, 1≤X[1:5]≤5, Int) -@variable(model, 1≤Y[1:5]≤6, Int) -@variable(model, 1≤Z[1:12]≤12, Int) -@constraint(model, X in NoOverlap()) -@constraint(model, Y in NoOverlap(; pair_vars = [1, 1, 1, 1, 1])) -@constraint(model, - Z in NoOverlap(; pair_vars = [2, 4, 1, 4, 2, 3, 5, 1, 2, 3, 3, 2], dim = 3)) -JuMP.optimize!(model) -@info "NoOverlap" value.(X) value.(Y) value.(Z) -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - -@info concept(:element, [1, 2, 3, 4, 5]; id=1, val=1) -@info concept(:element, [1, 2, 3, 4, 5]; id=1, val=2) -@info concept(:element, [1, 2, 3, 4, 2]) -@info concept(:element, [1, 2, 3, 4, 1]) -``` - -```julia [XCSP] -using Constraints - -c = x -> Constraints.xcsp_element( - list = x, - index = 1, - condition = (==, 3) -) - -@info c([3, 3, 10]) -@info c([1, 1, 4, 3]) -``` - -```julia [JuMP] -using CBLS, JuMP - -model = Model(CBLS.Optimizer) -@variable(model, 1≤X[1:5]≤5, Int) -@variable(model, 1≤Y[1:5]≤5, Int) -@variable(model, 0≤Z[1:5]≤5, Int) -@constraint(model, X in Element()) -@constraint(model, Y in Element(; id = 1, val = 1)) -@constraint(model, Z in Element(; id = 2, val = 2)) -JuMP.optimize!(model) -@info "Element" value.(X) value.(Y) value.(Z) -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - - -``` - -```julia [XCSP] -using Constraints - - -``` - -```julia [JuMP] -using CBLS, JuMP - - -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - - -``` - -```julia [XCSP] -using Constraints - - -``` - -```julia [JuMP] -using CBLS, JuMP - - -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -::: code-group - -```julia [JC-API] -using Constraints - - -``` - -```julia [XCSP] -using Constraints - - -``` - -```julia [JuMP] -using CBLS, JuMP - - -``` - -```julia [MOI] -# TODO: How to handle intention in JuMP/MOI -``` - -::: - -### Test for DocumenterVitePress Issue - -```@example test1 -using Constraints # hide -c = concept(:dist_different) -c([1, 2, 3, 3]) && !c([1, 2, 3, 4]) -``` - -````@example test2 -using Constraints # hide -c = concept(:dist_different) -c([1, 2, 3, 3]) && !c([1, 2, 3, 4]) -```` - ### Specific documentation ```@docs; canonical=false diff --git a/docs/src/constraints/packing_scheduling_constraints.md b/docs/src/constraints/packing_scheduling_constraints.md index e3ad8cf..e73ce6f 100644 --- a/docs/src/constraints/packing_scheduling_constraints.md +++ b/docs/src/constraints/packing_scheduling_constraints.md @@ -4,6 +4,100 @@ CurrentModule = Constraints ``` +::: code-group + +```julia [JC-API] +using Constraints + +@info concept(:cumulative, [1, 2, 3, 4, 5]; val = 1) +@info concept(:cumulative, [1, 2, 2, 4, 5]; val = 1) +@info concept(:cumulative, [1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = ≤, val = 5) +@info concept(:cumulative, [1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5) +``` + +```julia [XCSP] +using Constraints + +c = x -> Constraints.xcsp_cumulative( + origins = x, + lengths = [3, 2, 5, 4, 2], + heights = [1, 2, 1, 1, 3], + condition = (≤, 5) +) + +@info c([1, 2, 3, 4, 5]) +@info c([1, 1, 1, 2, 2]) +``` + +```julia [JuMP] +using CBLS, JuMP + +model = Model(CBLS.Optimizer) +@variable(model, 1≤X[1:5]≤5, Int) +@variable(model, 1≤Y[1:5]≤5, Int) +@variable(model, 1≤Z[1:5]≤5, Int) +@constraint(model, X in Cumulative(; val = 1)) +@constraint(model, + Y in Cumulative(; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = ≤, val = 5)) +@constraint(model, + Z in Cumulative(; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5)) +JuMP.optimize!(model) +@info "Cumulative" value.(X) value.(Y) value.(Z) +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + + +::: code-group + +```julia [JC-API] +using Constraints + +@info concept(:no_overlap, [1, 2, 3, 4, 5]) +@info concept(:no_overlap, [1, 2, 3, 4, 1]) +@info concept(:no_overlap, [1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 1, 1]) +@info concept(:no_overlap, [1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 3, 1]) +@info concept(:no_overlap, [1, 2, 4, 6, 3]; pair_vars = [1, 1, 3, 1, 1]) +``` + +```julia [XCSP] +using Constraints + +c = x -> Constraints.xcsp_no_overlap( + origins = x, + lengths = [1, 4, 10], + zero_ignored = true +) + +@info c([1, 3, 10]) +@info c([2, 1, 4, 3]) +``` + +```julia [JuMP] +using CBLS, JuMP + +model = Model(CBLS.Optimizer) +@variable(model, 1≤X[1:5]≤5, Int) +@variable(model, 1≤Y[1:5]≤6, Int) +@variable(model, 1≤Z[1:12]≤12, Int) +@constraint(model, X in NoOverlap()) +@constraint(model, Y in NoOverlap(; pair_vars = [1, 1, 1, 1, 1])) +@constraint(model, + Z in NoOverlap(; pair_vars = [2, 4, 1, 4, 2, 3, 5, 1, 2, 3, 3, 2], dim = 3)) +JuMP.optimize!(model) +@info "NoOverlap" value.(X) value.(Y) value.(Z) +``` + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + +::: + ### Packing and Scheduling Constraints ```@docs; canonical=false