From 52b68630cd9581a16d10a079c50514ae4ca69092 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Tue, 18 Jun 2024 05:40:22 +0000 Subject: [PATCH] build based on 90e6640 --- dev/.documenter/.vitepress/config.mts | 202 + dev/.documenter/.vitepress/theme/index.ts | 19 + dev/.documenter/.vitepress/theme/style.css | 179 + .../assets}/JuMP-logo-dark.png | Bin dev/{ => .documenter/assets}/JuMP-logo.png | Bin dev/{ => .documenter/assets}/logo.png | Bin dev/{ => .documenter/assets}/pluto-logo.png | Bin dev/{ => .documenter/assets}/toqubo-logo.png | Bin .../constraints/comparison_constraints.md | 178 + .../constraints/connection_constraints.md | 189 + .../constraints/constraint_commons.md | 333 ++ .../constraints/constraint_domains.md | 1736 +++++++ .../constraints/constraint_models.md | 425 ++ dev/.documenter/constraints/constraints.md | 528 ++ .../counting_summing_constraints.md | 249 + .../constraints/elementary_constraints.md | 50 + .../constraints/generic_constraints.md | 244 + .../constraints/graph_constraints.md | 52 + dev/.documenter/constraints/intro.md | 4 + .../constraints/language_constraints.md | 132 + .../packing_scheduling_constraints.md | 123 + dev/.documenter/cp/advanced.md | 10 + dev/.documenter/cp/applications.md | 10 + dev/.documenter/cp/contribution.md | 10 + dev/.documenter/cp/cp101.md | 14 + dev/.documenter/cp/ecosystem.md | 10 + dev/.documenter/cp/getting_started.md | 141 + dev/.documenter/cp/intro.md | 4 + dev/.documenter/cp/models.md | 10 + dev/.documenter/cp/opt.md | 14 + dev/.documenter/cp/tuto_xp.md | 10 + dev/.documenter/full_api.md | 4441 +++++++++++++++++ dev/.documenter/index-old.md | 54 + dev/.documenter/index.md | 58 + dev/.documenter/learning/aggregation.md | 64 + dev/.documenter/learning/arithmetic.md | 64 + dev/.documenter/learning/comparison.md | 178 + .../learning/compositional_networks.md | 180 + .../learning/constraint_learning.md | 508 ++ dev/.documenter/learning/intro.md | 4 + dev/.documenter/learning/layers.md | 215 + dev/.documenter/learning/qubo_constraints.md | 44 + dev/.documenter/learning/qubo_encoding.md | 60 + dev/.documenter/learning/qubo_learning.md | 171 + dev/.documenter/learning/transformation.md | 443 ++ dev/.documenter/meta/meta_strategist.md | 4 + dev/.documenter/perf/api.md | 178 + dev/.documenter/perf/benchmark_ext.md | 39 + dev/.documenter/perf/chairmarks_ext.md | 35 + dev/.documenter/perf/perf_checker.md | 65 + dev/.documenter/perf/perf_interface.md | 118 + dev/.documenter/perf/tutorial.md | 71 + dev/.documenter/public/JuMP-logo-dark.png | Bin 0 -> 3318 bytes dev/.documenter/public/JuMP-logo.png | Bin 0 -> 3343 bytes dev/.documenter/public/logo.png | Bin 0 -> 60313 bytes dev/.documenter/public/pluto-logo.png | Bin 0 -> 3908 bytes dev/.documenter/public/toqubo-logo.png | Bin 0 -> 47032 bytes dev/.documenter/public_api.md | 1480 ++++++ dev/.documenter/solvers/cbls.md | 929 ++++ dev/.documenter/solvers/intro.md | 4 + .../solvers/local_search_solvers.md | 2704 ++++++++++ dev/404.html | 21 - dev/assets/app.BR380OMv.js | 1 - .../chunks/@localSearchIndexroot.CHYlrtr2.js | 1 - .../chunks/VPLocalSearchBox.B9WZ723L.js | 7 - dev/assets/chunks/framework.aA95Gx5L.js | 17 - dev/assets/chunks/theme.DQqwdnSU.js | 2 - ...ints_comparison_constraints.md.2Ukc8viw.js | 25 - ...comparison_constraints.md.2Ukc8viw.lean.js | 1 - ...ints_connection_constraints.md.0kSxmxNT.js | 24 - ...connection_constraints.md.0kSxmxNT.lean.js | 1 - ...straints_constraint_commons.md.PTLdrUW2.js | 10 - ...nts_constraint_commons.md.PTLdrUW2.lean.js | 1 - ...straints_constraint_domains.md.Cd0YH57K.js | 36 - ...nts_constraint_domains.md.Cd0YH57K.lean.js | 1 - ...nstraints_constraint_models.md.DjPMcFlD.js | 30 - ...ints_constraint_models.md.DjPMcFlD.lean.js | 1 - .../constraints_constraints.md.ijIsQmJK.js | 3 - ...onstraints_constraints.md.ijIsQmJK.lean.js | 1 - ...ounting_summing_constraints.md.BIdrSepq.js | 39 - ...ng_summing_constraints.md.BIdrSepq.lean.js | 1 - ...ints_elementary_constraints.md.BbiPuUtE.js | 5 - ...elementary_constraints.md.BbiPuUtE.lean.js | 1 - ...traints_generic_constraints.md.WUfYZUE9.js | 39 - ...ts_generic_constraints.md.WUfYZUE9.lean.js | 1 - ...nstraints_graph_constraints.md.CTf_lkG3.js | 7 - ...ints_graph_constraints.md.CTf_lkG3.lean.js | 1 - dev/assets/constraints_intro.md.SiDBJ4N_.js | 1 - .../constraints_intro.md.SiDBJ4N_.lean.js | 1 - ...raints_language_constraints.md.CE20vPnP.js | 48 - ...s_language_constraints.md.CE20vPnP.lean.js | 1 - ...king_scheduling_constraints.md.CSsKQ9F3.js | 18 - ...scheduling_constraints.md.CSsKQ9F3.lean.js | 1 - dev/assets/cp_advanced.md.Dsfkdtcs.js | 1 - dev/assets/cp_advanced.md.Dsfkdtcs.lean.js | 1 - dev/assets/cp_applications.md.-HdwrgYe.js | 1 - .../cp_applications.md.-HdwrgYe.lean.js | 1 - dev/assets/cp_contribution.md.CvjPxUVA.js | 1 - .../cp_contribution.md.CvjPxUVA.lean.js | 1 - dev/assets/cp_cp101.md.CrtqNaW3.js | 1 - dev/assets/cp_cp101.md.CrtqNaW3.lean.js | 1 - dev/assets/cp_ecosystem.md.BROmdRLS.js | 1 - dev/assets/cp_ecosystem.md.BROmdRLS.lean.js | 1 - dev/assets/cp_getting_started.md.CgxLSopb.js | 9 - .../cp_getting_started.md.CgxLSopb.lean.js | 1 - dev/assets/cp_intro.md.qCFhsnKE.js | 1 - dev/assets/cp_intro.md.qCFhsnKE.lean.js | 1 - dev/assets/cp_models.md.DjhzTYet.js | 1 - dev/assets/cp_models.md.DjhzTYet.lean.js | 1 - dev/assets/cp_opt.md.oWksNiMs.js | 1 - dev/assets/cp_opt.md.oWksNiMs.lean.js | 1 - dev/assets/cp_tuto_xp.md.CLy9H2hK.js | 1 - dev/assets/cp_tuto_xp.md.CLy9H2hK.lean.js | 1 - dev/assets/full_api.md.BiWge5EP.js | 255 - dev/assets/full_api.md.BiWge5EP.lean.js | 1 - dev/assets/index-old.md.BzPVACYs.js | 1 - dev/assets/index-old.md.BzPVACYs.lean.js | 1 - dev/assets/index.md.BcgCFTkL.js | 1 - dev/assets/index.md.BcgCFTkL.lean.js | 1 - .../inter-italic-cyrillic-ext.5XJwZIOp.woff2 | Bin 28332 -> 0 bytes .../inter-italic-cyrillic.D6csxwjC.woff2 | Bin 17824 -> 0 bytes .../inter-italic-greek-ext.CHOfFY1k.woff2 | Bin 12188 -> 0 bytes dev/assets/inter-italic-greek.9J96vYpw.woff2 | Bin 23264 -> 0 bytes .../inter-italic-latin-ext.BGcWXLrn.woff2 | Bin 63552 -> 0 bytes dev/assets/inter-italic-latin.DbsTr1gm.woff2 | Bin 46048 -> 0 bytes .../inter-italic-vietnamese.DHNAd7Wr.woff2 | Bin 8784 -> 0 bytes .../inter-roman-cyrillic-ext.DxP3Awbn.woff2 | Bin 26600 -> 0 bytes .../inter-roman-cyrillic.CMhn1ESj.woff2 | Bin 16780 -> 0 bytes .../inter-roman-greek-ext.D0mI3NpI.woff2 | Bin 11808 -> 0 bytes dev/assets/inter-roman-greek.JvnBZ4YD.woff2 | Bin 21776 -> 0 bytes .../inter-roman-latin-ext.ZlYT4o7i.woff2 | Bin 59608 -> 0 bytes dev/assets/inter-roman-latin.Bu8hRsVA.woff2 | Bin 42464 -> 0 bytes .../inter-roman-vietnamese.ClpjcLMQ.woff2 | Bin 8492 -> 0 bytes .../learning_aggregation.md.5RLMQ4Bd.js | 1 - .../learning_aggregation.md.5RLMQ4Bd.lean.js | 1 - dev/assets/learning_arithmetic.md.DW5u7RMW.js | 1 - .../learning_arithmetic.md.DW5u7RMW.lean.js | 1 - dev/assets/learning_comparison.md.BsnqPWC-.js | 1 - .../learning_comparison.md.BsnqPWC-.lean.js | 1 - ...ning_compositional_networks.md.BZgNyUW3.js | 1 - ...compositional_networks.md.BZgNyUW3.lean.js | 1 - ...earning_constraint_learning.md.DAfFojnp.js | 1 - ...ng_constraint_learning.md.DAfFojnp.lean.js | 1 - dev/assets/learning_intro.md.497AVcuz.js | 1 - dev/assets/learning_intro.md.497AVcuz.lean.js | 1 - dev/assets/learning_layers.md.DuFC9ol_.js | 4 - .../learning_layers.md.DuFC9ol_.lean.js | 1 - .../learning_qubo_constraints.md.DpCFckdQ.js | 1 - ...rning_qubo_constraints.md.DpCFckdQ.lean.js | 1 - .../learning_qubo_encoding.md.CDyoKOWI.js | 1 - ...learning_qubo_encoding.md.CDyoKOWI.lean.js | 1 - .../learning_qubo_learning.md.CLlNBMzd.js | 119 - ...learning_qubo_learning.md.CLlNBMzd.lean.js | 1 - .../learning_transformation.md.BtKPMNbs.js | 45 - ...earning_transformation.md.BtKPMNbs.lean.js | 1 - .../meta_meta_strategist.md.CuHkGJNL.js | 1 - .../meta_meta_strategist.md.CuHkGJNL.lean.js | 1 - dev/assets/perf_benchmark_ext.md.CVYCQYDt.js | 1 - .../perf_benchmark_ext.md.CVYCQYDt.lean.js | 1 - dev/assets/perf_perf_checker.md.C3kXwfzJ.js | 9 - .../perf_perf_checker.md.C3kXwfzJ.lean.js | 1 - dev/assets/perf_perf_interface.md.DaCOMv6z.js | 1 - .../perf_perf_interface.md.DaCOMv6z.lean.js | 1 - dev/assets/public_api.md.ByXB8t1V.js | 16 - dev/assets/public_api.md.ByXB8t1V.lean.js | 1 - dev/assets/solvers_cbls.md.BxYapv-Y.js | 1 - dev/assets/solvers_cbls.md.BxYapv-Y.lean.js | 1 - dev/assets/solvers_intro.md.BOddHRCt.js | 1 - dev/assets/solvers_intro.md.BOddHRCt.lean.js | 1 - ...olvers_local_search_solvers.md.BuFLqJZe.js | 36 - ...s_local_search_solvers.md.BuFLqJZe.lean.js | 1 - dev/assets/style.Bq13Ojh9.css | 1 - dev/constraints/comparison_constraints.html | 48 - dev/constraints/connection_constraints.html | 47 - dev/constraints/constraint_commons.html | 33 - dev/constraints/constraint_domains.html | 59 - dev/constraints/constraint_models.html | 53 - dev/constraints/constraints.html | 26 - .../counting_summing_constraints.html | 62 - dev/constraints/elementary_constraints.html | 28 - dev/constraints/generic_constraints.html | 62 - dev/constraints/graph_constraints.html | 30 - dev/constraints/intro.html | 24 - dev/constraints/language_constraints.html | 71 - .../packing_scheduling_constraints.html | 41 - dev/cp/advanced.html | 24 - dev/cp/applications.html | 24 - dev/cp/contribution.html | 24 - dev/cp/cp101.html | 24 - dev/cp/ecosystem.html | 24 - dev/cp/getting_started.html | 32 - dev/cp/intro.html | 24 - dev/cp/models.html | 24 - dev/cp/opt.html | 24 - dev/cp/tuto_xp.html | 24 - dev/full_api.html | 278 -- dev/hashmap.json | 1 - dev/index-old.html | 24 - dev/index.html | 24 - dev/learning/aggregation.html | 24 - dev/learning/arithmetic.html | 24 - dev/learning/comparison.html | 24 - dev/learning/compositional_networks.html | 24 - dev/learning/constraint_learning.html | 24 - dev/learning/intro.html | 24 - dev/learning/layers.html | 27 - dev/learning/qubo_constraints.html | 24 - dev/learning/qubo_encoding.html | 24 - dev/learning/qubo_learning.html | 142 - dev/learning/transformation.html | 68 - dev/meta/meta_strategist.html | 24 - dev/perf/benchmark_ext.html | 24 - dev/perf/perf_checker.html | 32 - dev/perf/perf_interface.html | 24 - dev/public_api.html | 39 - dev/solvers/cbls.html | 29 - dev/solvers/intro.html | 24 - dev/solvers/local_search_solvers.html | 59 - 218 files changed, 16987 insertions(+), 2740 deletions(-) create mode 100644 dev/.documenter/.vitepress/config.mts create mode 100644 dev/.documenter/.vitepress/theme/index.ts create mode 100644 dev/.documenter/.vitepress/theme/style.css rename dev/{ => .documenter/assets}/JuMP-logo-dark.png (100%) rename dev/{ => .documenter/assets}/JuMP-logo.png (100%) rename dev/{ => .documenter/assets}/logo.png (100%) rename dev/{ => .documenter/assets}/pluto-logo.png (100%) rename dev/{ => .documenter/assets}/toqubo-logo.png (100%) create mode 100644 dev/.documenter/constraints/comparison_constraints.md create mode 100644 dev/.documenter/constraints/connection_constraints.md create mode 100644 dev/.documenter/constraints/constraint_commons.md create mode 100644 dev/.documenter/constraints/constraint_domains.md create mode 100644 dev/.documenter/constraints/constraint_models.md create mode 100644 dev/.documenter/constraints/constraints.md create mode 100644 dev/.documenter/constraints/counting_summing_constraints.md create mode 100644 dev/.documenter/constraints/elementary_constraints.md create mode 100644 dev/.documenter/constraints/generic_constraints.md create mode 100644 dev/.documenter/constraints/graph_constraints.md create mode 100644 dev/.documenter/constraints/intro.md create mode 100644 dev/.documenter/constraints/language_constraints.md create mode 100644 dev/.documenter/constraints/packing_scheduling_constraints.md create mode 100644 dev/.documenter/cp/advanced.md create mode 100644 dev/.documenter/cp/applications.md create mode 100644 dev/.documenter/cp/contribution.md create mode 100644 dev/.documenter/cp/cp101.md create mode 100644 dev/.documenter/cp/ecosystem.md create mode 100644 dev/.documenter/cp/getting_started.md create mode 100644 dev/.documenter/cp/intro.md create mode 100644 dev/.documenter/cp/models.md create mode 100644 dev/.documenter/cp/opt.md create mode 100644 dev/.documenter/cp/tuto_xp.md create mode 100644 dev/.documenter/full_api.md create mode 100644 dev/.documenter/index-old.md create mode 100644 dev/.documenter/index.md create mode 100644 dev/.documenter/learning/aggregation.md create mode 100644 dev/.documenter/learning/arithmetic.md create mode 100644 dev/.documenter/learning/comparison.md create mode 100644 dev/.documenter/learning/compositional_networks.md create mode 100644 dev/.documenter/learning/constraint_learning.md create mode 100644 dev/.documenter/learning/intro.md create mode 100644 dev/.documenter/learning/layers.md create mode 100644 dev/.documenter/learning/qubo_constraints.md create mode 100644 dev/.documenter/learning/qubo_encoding.md create mode 100644 dev/.documenter/learning/qubo_learning.md create mode 100644 dev/.documenter/learning/transformation.md create mode 100644 dev/.documenter/meta/meta_strategist.md create mode 100644 dev/.documenter/perf/api.md create mode 100644 dev/.documenter/perf/benchmark_ext.md create mode 100644 dev/.documenter/perf/chairmarks_ext.md create mode 100644 dev/.documenter/perf/perf_checker.md create mode 100644 dev/.documenter/perf/perf_interface.md create mode 100644 dev/.documenter/perf/tutorial.md create mode 100644 dev/.documenter/public/JuMP-logo-dark.png create mode 100644 dev/.documenter/public/JuMP-logo.png create mode 100644 dev/.documenter/public/logo.png create mode 100644 dev/.documenter/public/pluto-logo.png create mode 100644 dev/.documenter/public/toqubo-logo.png create mode 100644 dev/.documenter/public_api.md create mode 100644 dev/.documenter/solvers/cbls.md create mode 100644 dev/.documenter/solvers/intro.md create mode 100644 dev/.documenter/solvers/local_search_solvers.md delete mode 100644 dev/404.html delete mode 100644 dev/assets/app.BR380OMv.js delete mode 100644 dev/assets/chunks/@localSearchIndexroot.CHYlrtr2.js delete mode 100644 dev/assets/chunks/VPLocalSearchBox.B9WZ723L.js delete mode 100644 dev/assets/chunks/framework.aA95Gx5L.js delete mode 100644 dev/assets/chunks/theme.DQqwdnSU.js delete mode 100644 dev/assets/constraints_comparison_constraints.md.2Ukc8viw.js delete mode 100644 dev/assets/constraints_comparison_constraints.md.2Ukc8viw.lean.js delete mode 100644 dev/assets/constraints_connection_constraints.md.0kSxmxNT.js delete mode 100644 dev/assets/constraints_connection_constraints.md.0kSxmxNT.lean.js delete mode 100644 dev/assets/constraints_constraint_commons.md.PTLdrUW2.js delete mode 100644 dev/assets/constraints_constraint_commons.md.PTLdrUW2.lean.js delete mode 100644 dev/assets/constraints_constraint_domains.md.Cd0YH57K.js delete mode 100644 dev/assets/constraints_constraint_domains.md.Cd0YH57K.lean.js delete mode 100644 dev/assets/constraints_constraint_models.md.DjPMcFlD.js delete mode 100644 dev/assets/constraints_constraint_models.md.DjPMcFlD.lean.js delete mode 100644 dev/assets/constraints_constraints.md.ijIsQmJK.js delete mode 100644 dev/assets/constraints_constraints.md.ijIsQmJK.lean.js delete mode 100644 dev/assets/constraints_counting_summing_constraints.md.BIdrSepq.js delete mode 100644 dev/assets/constraints_counting_summing_constraints.md.BIdrSepq.lean.js delete mode 100644 dev/assets/constraints_elementary_constraints.md.BbiPuUtE.js delete mode 100644 dev/assets/constraints_elementary_constraints.md.BbiPuUtE.lean.js delete mode 100644 dev/assets/constraints_generic_constraints.md.WUfYZUE9.js delete mode 100644 dev/assets/constraints_generic_constraints.md.WUfYZUE9.lean.js delete mode 100644 dev/assets/constraints_graph_constraints.md.CTf_lkG3.js delete mode 100644 dev/assets/constraints_graph_constraints.md.CTf_lkG3.lean.js delete mode 100644 dev/assets/constraints_intro.md.SiDBJ4N_.js delete mode 100644 dev/assets/constraints_intro.md.SiDBJ4N_.lean.js delete mode 100644 dev/assets/constraints_language_constraints.md.CE20vPnP.js delete mode 100644 dev/assets/constraints_language_constraints.md.CE20vPnP.lean.js delete mode 100644 dev/assets/constraints_packing_scheduling_constraints.md.CSsKQ9F3.js delete mode 100644 dev/assets/constraints_packing_scheduling_constraints.md.CSsKQ9F3.lean.js delete mode 100644 dev/assets/cp_advanced.md.Dsfkdtcs.js delete mode 100644 dev/assets/cp_advanced.md.Dsfkdtcs.lean.js delete mode 100644 dev/assets/cp_applications.md.-HdwrgYe.js delete mode 100644 dev/assets/cp_applications.md.-HdwrgYe.lean.js delete mode 100644 dev/assets/cp_contribution.md.CvjPxUVA.js delete mode 100644 dev/assets/cp_contribution.md.CvjPxUVA.lean.js delete mode 100644 dev/assets/cp_cp101.md.CrtqNaW3.js delete mode 100644 dev/assets/cp_cp101.md.CrtqNaW3.lean.js delete mode 100644 dev/assets/cp_ecosystem.md.BROmdRLS.js delete mode 100644 dev/assets/cp_ecosystem.md.BROmdRLS.lean.js delete mode 100644 dev/assets/cp_getting_started.md.CgxLSopb.js delete mode 100644 dev/assets/cp_getting_started.md.CgxLSopb.lean.js delete mode 100644 dev/assets/cp_intro.md.qCFhsnKE.js delete mode 100644 dev/assets/cp_intro.md.qCFhsnKE.lean.js delete mode 100644 dev/assets/cp_models.md.DjhzTYet.js delete mode 100644 dev/assets/cp_models.md.DjhzTYet.lean.js delete mode 100644 dev/assets/cp_opt.md.oWksNiMs.js delete mode 100644 dev/assets/cp_opt.md.oWksNiMs.lean.js delete mode 100644 dev/assets/cp_tuto_xp.md.CLy9H2hK.js delete mode 100644 dev/assets/cp_tuto_xp.md.CLy9H2hK.lean.js delete mode 100644 dev/assets/full_api.md.BiWge5EP.js delete mode 100644 dev/assets/full_api.md.BiWge5EP.lean.js delete mode 100644 dev/assets/index-old.md.BzPVACYs.js delete mode 100644 dev/assets/index-old.md.BzPVACYs.lean.js delete mode 100644 dev/assets/index.md.BcgCFTkL.js delete mode 100644 dev/assets/index.md.BcgCFTkL.lean.js delete mode 100644 dev/assets/inter-italic-cyrillic-ext.5XJwZIOp.woff2 delete mode 100644 dev/assets/inter-italic-cyrillic.D6csxwjC.woff2 delete mode 100644 dev/assets/inter-italic-greek-ext.CHOfFY1k.woff2 delete mode 100644 dev/assets/inter-italic-greek.9J96vYpw.woff2 delete mode 100644 dev/assets/inter-italic-latin-ext.BGcWXLrn.woff2 delete mode 100644 dev/assets/inter-italic-latin.DbsTr1gm.woff2 delete mode 100644 dev/assets/inter-italic-vietnamese.DHNAd7Wr.woff2 delete mode 100644 dev/assets/inter-roman-cyrillic-ext.DxP3Awbn.woff2 delete mode 100644 dev/assets/inter-roman-cyrillic.CMhn1ESj.woff2 delete mode 100644 dev/assets/inter-roman-greek-ext.D0mI3NpI.woff2 delete mode 100644 dev/assets/inter-roman-greek.JvnBZ4YD.woff2 delete mode 100644 dev/assets/inter-roman-latin-ext.ZlYT4o7i.woff2 delete mode 100644 dev/assets/inter-roman-latin.Bu8hRsVA.woff2 delete mode 100644 dev/assets/inter-roman-vietnamese.ClpjcLMQ.woff2 delete mode 100644 dev/assets/learning_aggregation.md.5RLMQ4Bd.js delete mode 100644 dev/assets/learning_aggregation.md.5RLMQ4Bd.lean.js delete mode 100644 dev/assets/learning_arithmetic.md.DW5u7RMW.js delete mode 100644 dev/assets/learning_arithmetic.md.DW5u7RMW.lean.js delete mode 100644 dev/assets/learning_comparison.md.BsnqPWC-.js delete mode 100644 dev/assets/learning_comparison.md.BsnqPWC-.lean.js delete mode 100644 dev/assets/learning_compositional_networks.md.BZgNyUW3.js delete mode 100644 dev/assets/learning_compositional_networks.md.BZgNyUW3.lean.js delete mode 100644 dev/assets/learning_constraint_learning.md.DAfFojnp.js delete mode 100644 dev/assets/learning_constraint_learning.md.DAfFojnp.lean.js delete mode 100644 dev/assets/learning_intro.md.497AVcuz.js delete mode 100644 dev/assets/learning_intro.md.497AVcuz.lean.js delete mode 100644 dev/assets/learning_layers.md.DuFC9ol_.js delete mode 100644 dev/assets/learning_layers.md.DuFC9ol_.lean.js delete mode 100644 dev/assets/learning_qubo_constraints.md.DpCFckdQ.js delete mode 100644 dev/assets/learning_qubo_constraints.md.DpCFckdQ.lean.js delete mode 100644 dev/assets/learning_qubo_encoding.md.CDyoKOWI.js delete mode 100644 dev/assets/learning_qubo_encoding.md.CDyoKOWI.lean.js delete mode 100644 dev/assets/learning_qubo_learning.md.CLlNBMzd.js delete mode 100644 dev/assets/learning_qubo_learning.md.CLlNBMzd.lean.js delete mode 100644 dev/assets/learning_transformation.md.BtKPMNbs.js delete mode 100644 dev/assets/learning_transformation.md.BtKPMNbs.lean.js delete mode 100644 dev/assets/meta_meta_strategist.md.CuHkGJNL.js delete mode 100644 dev/assets/meta_meta_strategist.md.CuHkGJNL.lean.js delete mode 100644 dev/assets/perf_benchmark_ext.md.CVYCQYDt.js delete mode 100644 dev/assets/perf_benchmark_ext.md.CVYCQYDt.lean.js delete mode 100644 dev/assets/perf_perf_checker.md.C3kXwfzJ.js delete mode 100644 dev/assets/perf_perf_checker.md.C3kXwfzJ.lean.js delete mode 100644 dev/assets/perf_perf_interface.md.DaCOMv6z.js delete mode 100644 dev/assets/perf_perf_interface.md.DaCOMv6z.lean.js delete mode 100644 dev/assets/public_api.md.ByXB8t1V.js delete mode 100644 dev/assets/public_api.md.ByXB8t1V.lean.js delete mode 100644 dev/assets/solvers_cbls.md.BxYapv-Y.js delete mode 100644 dev/assets/solvers_cbls.md.BxYapv-Y.lean.js delete mode 100644 dev/assets/solvers_intro.md.BOddHRCt.js delete mode 100644 dev/assets/solvers_intro.md.BOddHRCt.lean.js delete mode 100644 dev/assets/solvers_local_search_solvers.md.BuFLqJZe.js delete mode 100644 dev/assets/solvers_local_search_solvers.md.BuFLqJZe.lean.js delete mode 100644 dev/assets/style.Bq13Ojh9.css delete mode 100644 dev/constraints/comparison_constraints.html delete mode 100644 dev/constraints/connection_constraints.html delete mode 100644 dev/constraints/constraint_commons.html delete mode 100644 dev/constraints/constraint_domains.html delete mode 100644 dev/constraints/constraint_models.html delete mode 100644 dev/constraints/constraints.html delete mode 100644 dev/constraints/counting_summing_constraints.html delete mode 100644 dev/constraints/elementary_constraints.html delete mode 100644 dev/constraints/generic_constraints.html delete mode 100644 dev/constraints/graph_constraints.html delete mode 100644 dev/constraints/intro.html delete mode 100644 dev/constraints/language_constraints.html delete mode 100644 dev/constraints/packing_scheduling_constraints.html delete mode 100644 dev/cp/advanced.html delete mode 100644 dev/cp/applications.html delete mode 100644 dev/cp/contribution.html delete mode 100644 dev/cp/cp101.html delete mode 100644 dev/cp/ecosystem.html delete mode 100644 dev/cp/getting_started.html delete mode 100644 dev/cp/intro.html delete mode 100644 dev/cp/models.html delete mode 100644 dev/cp/opt.html delete mode 100644 dev/cp/tuto_xp.html delete mode 100644 dev/full_api.html delete mode 100644 dev/hashmap.json delete mode 100644 dev/index-old.html delete mode 100644 dev/index.html delete mode 100644 dev/learning/aggregation.html delete mode 100644 dev/learning/arithmetic.html delete mode 100644 dev/learning/comparison.html delete mode 100644 dev/learning/compositional_networks.html delete mode 100644 dev/learning/constraint_learning.html delete mode 100644 dev/learning/intro.html delete mode 100644 dev/learning/layers.html delete mode 100644 dev/learning/qubo_constraints.html delete mode 100644 dev/learning/qubo_encoding.html delete mode 100644 dev/learning/qubo_learning.html delete mode 100644 dev/learning/transformation.html delete mode 100644 dev/meta/meta_strategist.html delete mode 100644 dev/perf/benchmark_ext.html delete mode 100644 dev/perf/perf_checker.html delete mode 100644 dev/perf/perf_interface.html delete mode 100644 dev/public_api.html delete mode 100644 dev/solvers/cbls.html delete mode 100644 dev/solvers/intro.html delete mode 100644 dev/solvers/local_search_solvers.html diff --git a/dev/.documenter/.vitepress/config.mts b/dev/.documenter/.vitepress/config.mts new file mode 100644 index 0000000..e8d65d1 --- /dev/null +++ b/dev/.documenter/.vitepress/config.mts @@ -0,0 +1,202 @@ +import { defineConfig } from 'vitepress' +import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs' +import mathjax3 from "markdown-it-mathjax3"; +import footnote from "markdown-it-footnote"; + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + base: '/dev/',// TODO: replace this in makedocs! + title: 'Julia Constraints', + description: "A VitePress Site", + lastUpdated: true, + cleanUrls: true, + outDir: '../final_site', // This is required for MarkdownVitepress to work correctly... + + ignoreDeadLinks: true, + + markdown: { + math: true, + config(md) { + md.use(tabsMarkdownPlugin), + md.use(mathjax3), + md.use(footnote) + }, + theme: { + light: "github-light", + dark: "github-dark"} + }, + themeConfig: { + outline: 'deep', + logo: { src: '/logo.png', width: 24, height: 24}, + search: { + provider: 'local', + options: { + detailedView: true + } + }, + nav: [ +{ text: 'Home', link: '/index' }, +{ text: 'Constraint Programming', collapsed: false, items: [ +{ text: 'Part 1: Basics', collapsed: false, items: [ +{ text: 'Introduction', link: '/cp/intro' }, +{ text: 'CP 101', link: '/cp/cp101' }, +{ text: 'Optimization(s)?', link: '/cp/opt' }, +{ text: 'Getting Started', link: '/cp/getting_started' }, +{ text: 'Ecosystem', link: '/cp/ecosystem' }] + }, +{ text: 'Part 2: Advanced', collapsed: false, items: [ +{ text: 'CP Techniques', link: '/cp/advanced' }, +{ text: 'Applications', link: '/cp/applications' }, +{ text: 'Models', link: '/cp/models' }, +{ text: 'Tutorials&XP', link: '/cp/tuto_xp' }, +{ text: 'Contributing', link: '/cp/contribution' }] + }] + }, +{ text: 'Constraints', collapsed: false, items: [ +{ text: 'Introduction', link: '/constraints/intro' }, +{ text: 'ConstraintCommons.jl', link: '/constraints/constraint_commons' }, +{ text: 'ConstraintDomains.jl', link: '/constraints/constraint_domains' }, +{ text: 'Constraints.jl', collapsed: false, items: [ +{ text: 'Basic Tools', link: '/constraints/constraints' }, +{ text: 'Generic Constraints', link: '/constraints/generic_constraints' }, +{ text: 'Language Constraints', link: '/constraints/language_constraints' }, +{ text: 'Comparison Constraints', link: '/constraints/comparison_constraints' }, +{ text: 'Counting and Summing Constraints', link: '/constraints/counting_summing_constraints' }, +{ text: 'Connection Constraints', link: '/constraints/connection_constraints' }, +{ text: 'Packing and Scheduling Constraints', link: '/constraints/packing_scheduling_constraints' }, +{ text: 'Graph Constraints', link: '/constraints/graph_constraints' }, +{ text: 'Elementary Constraints', link: '/constraints/elementary_constraints' }] + }, +{ text: 'ConstraintModels.jl', link: '/constraints/constraint_models' }] + }, +{ text: 'Learning', collapsed: false, items: [ +{ text: 'Introduction', link: '/learning/intro' }, +{ text: 'CompositionalNetworks.jl', collapsed: false, items: [ +{ text: 'About ICNs', link: '/learning/compositional_networks' }, +{ text: 'Layers', link: '/learning/layers' }, +{ text: 'Transformations Layer', link: '/learning/transformation' }, +{ text: 'Arithmetic Layer', link: '/learning/arithmetic' }, +{ text: 'Aggregation Layer', link: '/learning/aggregation' }, +{ text: 'Comparison Layer', link: '/learning/comparison' }] + }, +{ text: 'QUBOConstraints.jl', collapsed: false, items: [ +{ text: 'Model as QUBO', link: '/learning/qubo_constraints' }, +{ text: 'Encoding', link: '/learning/qubo_encoding' }, +{ text: 'Learning', link: '/learning/qubo_learning' }] + }, +{ text: 'ConstraintLearning.jl', link: '/learning/constraint_learning' }] + }, +{ text: 'Solvers', collapsed: false, items: [ +{ text: 'Introduction', link: '/solvers/intro' }, +{ text: 'JuMPed', collapsed: false, items: [ +{ text: 'CBLS.jl', link: '/solvers/cbls' }] + }, +{ text: 'Others', collapsed: false, items: [ +{ text: 'LocalSearchSolvers.jl', link: '/solvers/local_search_solvers' }] + }] + }, +{ text: 'Meta Strategist', collapsed: false, items: [ +{ text: 'MetaStrategist.jl', link: '/meta/meta_strategist' }] + }, +{ text: 'Performance Checking', collapsed: false, items: [ +{ text: 'PerfChecker.jl', link: '/perf/perf_checker' }, +{ text: 'Tutorial', link: '/perf/tutorial' }, +{ text: 'Interface', link: '/perf/perf_interface' }, +{ text: 'BenchmarkToolsExt', link: '/perf/benchmark_ext' }, +{ text: 'ChairmarksExt', link: '/perf/chairmarks_ext' }, +{ text: 'API', link: '/perf/api' }] + }, +{ text: 'API', collapsed: false, items: [ +{ text: 'Public', link: '/public_api' }, +{ text: 'Full', link: '/full_api' }] + } +] +, + sidebar: [ +{ text: 'Home', link: '/index' }, +{ text: 'Constraint Programming', collapsed: false, items: [ +{ text: 'Part 1: Basics', collapsed: false, items: [ +{ text: 'Introduction', link: '/cp/intro' }, +{ text: 'CP 101', link: '/cp/cp101' }, +{ text: 'Optimization(s)?', link: '/cp/opt' }, +{ text: 'Getting Started', link: '/cp/getting_started' }, +{ text: 'Ecosystem', link: '/cp/ecosystem' }] + }, +{ text: 'Part 2: Advanced', collapsed: false, items: [ +{ text: 'CP Techniques', link: '/cp/advanced' }, +{ text: 'Applications', link: '/cp/applications' }, +{ text: 'Models', link: '/cp/models' }, +{ text: 'Tutorials&XP', link: '/cp/tuto_xp' }, +{ text: 'Contributing', link: '/cp/contribution' }] + }] + }, +{ text: 'Constraints', collapsed: false, items: [ +{ text: 'Introduction', link: '/constraints/intro' }, +{ text: 'ConstraintCommons.jl', link: '/constraints/constraint_commons' }, +{ text: 'ConstraintDomains.jl', link: '/constraints/constraint_domains' }, +{ text: 'Constraints.jl', collapsed: false, items: [ +{ text: 'Basic Tools', link: '/constraints/constraints' }, +{ text: 'Generic Constraints', link: '/constraints/generic_constraints' }, +{ text: 'Language Constraints', link: '/constraints/language_constraints' }, +{ text: 'Comparison Constraints', link: '/constraints/comparison_constraints' }, +{ text: 'Counting and Summing Constraints', link: '/constraints/counting_summing_constraints' }, +{ text: 'Connection Constraints', link: '/constraints/connection_constraints' }, +{ text: 'Packing and Scheduling Constraints', link: '/constraints/packing_scheduling_constraints' }, +{ text: 'Graph Constraints', link: '/constraints/graph_constraints' }, +{ text: 'Elementary Constraints', link: '/constraints/elementary_constraints' }] + }, +{ text: 'ConstraintModels.jl', link: '/constraints/constraint_models' }] + }, +{ text: 'Learning', collapsed: false, items: [ +{ text: 'Introduction', link: '/learning/intro' }, +{ text: 'CompositionalNetworks.jl', collapsed: false, items: [ +{ text: 'About ICNs', link: '/learning/compositional_networks' }, +{ text: 'Layers', link: '/learning/layers' }, +{ text: 'Transformations Layer', link: '/learning/transformation' }, +{ text: 'Arithmetic Layer', link: '/learning/arithmetic' }, +{ text: 'Aggregation Layer', link: '/learning/aggregation' }, +{ text: 'Comparison Layer', link: '/learning/comparison' }] + }, +{ text: 'QUBOConstraints.jl', collapsed: false, items: [ +{ text: 'Model as QUBO', link: '/learning/qubo_constraints' }, +{ text: 'Encoding', link: '/learning/qubo_encoding' }, +{ text: 'Learning', link: '/learning/qubo_learning' }] + }, +{ text: 'ConstraintLearning.jl', link: '/learning/constraint_learning' }] + }, +{ text: 'Solvers', collapsed: false, items: [ +{ text: 'Introduction', link: '/solvers/intro' }, +{ text: 'JuMPed', collapsed: false, items: [ +{ text: 'CBLS.jl', link: '/solvers/cbls' }] + }, +{ text: 'Others', collapsed: false, items: [ +{ text: 'LocalSearchSolvers.jl', link: '/solvers/local_search_solvers' }] + }] + }, +{ text: 'Meta Strategist', collapsed: false, items: [ +{ text: 'MetaStrategist.jl', link: '/meta/meta_strategist' }] + }, +{ text: 'Performance Checking', collapsed: false, items: [ +{ text: 'PerfChecker.jl', link: '/perf/perf_checker' }, +{ text: 'Tutorial', link: '/perf/tutorial' }, +{ text: 'Interface', link: '/perf/perf_interface' }, +{ text: 'BenchmarkToolsExt', link: '/perf/benchmark_ext' }, +{ text: 'ChairmarksExt', link: '/perf/chairmarks_ext' }, +{ text: 'API', link: '/perf/api' }] + }, +{ text: 'API', collapsed: false, items: [ +{ text: 'Public', link: '/public_api' }, +{ text: 'Full', link: '/full_api' }] + } +] +, + editLink: { pattern: "https://https://github.com/JuliaConstraints/JuliaConstraints.github.io/edit/main/docs/src/:path" }, + socialLinks: [ + { icon: 'github', link: 'https://github.com/JuliaConstraints/JuliaConstraints.github.io' } + ], + footer: { + message: 'Made with Documenter.jl & VitePress
', + copyright: `© Copyright ${new Date().getUTCFullYear()}.` + } + } +}) diff --git a/dev/.documenter/.vitepress/theme/index.ts b/dev/.documenter/.vitepress/theme/index.ts new file mode 100644 index 0000000..463b5d8 --- /dev/null +++ b/dev/.documenter/.vitepress/theme/index.ts @@ -0,0 +1,19 @@ +// .vitepress/theme/index.ts +import { h } from 'vue' +import type { Theme } from 'vitepress' +import DefaultTheme from 'vitepress/theme' + +import { enhanceAppWithTabs } from 'vitepress-plugin-tabs/client' +import './style.css' + +export default { + extends: DefaultTheme, + Layout() { + return h(DefaultTheme.Layout, null, { + // https://vitepress.dev/guide/extending-default-theme#layout-slots + }) + }, + enhanceApp({ app, router, siteData }) { + enhanceAppWithTabs(app) + } +} satisfies Theme \ No newline at end of file diff --git a/dev/.documenter/.vitepress/theme/style.css b/dev/.documenter/.vitepress/theme/style.css new file mode 100644 index 0000000..d2ca479 --- /dev/null +++ b/dev/.documenter/.vitepress/theme/style.css @@ -0,0 +1,179 @@ +@import url(https://fonts.googleapis.com/css?family=Space+Mono:regular,italic,700,700italic); +@import url(https://fonts.googleapis.com/css?family=Space+Grotesk:regular,italic,700,700italic); + +/* Customize default theme styling by overriding CSS variables: +https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css + */ + + /* Layouts */ + +/* + :root { + --vp-layout-max-width: 1440px; +} */ + +.VPHero .clip { + white-space: pre; + max-width: 500px; +} + +/* Fonts */ + + :root { + /* Typography */ + --vp-font-family-base: "Barlow", "Inter var experimental", "Inter var", + -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, + Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + + /* Code Snippet font */ + --vp-font-family-mono: "Space Mono", Menlo, Monaco, Consolas, "Courier New", + monospace; +} + +.mono { + /* + Disable contextual alternates (kind of like ligatures but different) in monospace, + which turns `/>` to an up arrow and `|>` (the Julia pipe symbol) to an up arrow as well. + This is pretty bad for Julia folks reading even though copy+paste retains the same text. + */ + font-feature-settings: 'calt' 0; +} + +/* Colors */ + +:root { + --julia-blue: #4063D8; + --julia-purple: #9558B2; + --julia-red: #CB3C33; + --julia-green: #389826; + + --vp-c-brand: #389826; + --vp-c-brand-light: #3dd027; + --vp-c-brand-lighter: #9499ff; + --vp-c-brand-lightest: #bcc0ff; + --vp-c-brand-dark: #535bf2; + --vp-c-brand-darker: #454ce1; + --vp-c-brand-dimm: #212425; +} + + /* Component: Button */ + +:root { + --vp-button-brand-border: var(--vp-c-brand-light); + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand); + --vp-button-brand-hover-border: var(--vp-c-brand-light); + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-light); + --vp-button-brand-active-border: var(--vp-c-brand-light); + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-button-brand-bg); +} + +/* Component: Home */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + #9558B2 30%, + #CB3C33 + ); + + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + #9558B2 30%, + #389826 30%, + #CB3C33 + ); + --vp-home-hero-image-filter: blur(40px); +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(72px); + } +} + +/* Component: Custom Block */ + +:root.dark { + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-lightest); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); + + /* // Tweak the color palette for blacks and dark grays */ + --vp-c-black: hsl(220 20% 9%); + --vp-c-black-pure: hsl(220, 24%, 4%); + --vp-c-black-soft: hsl(220 16% 13%); + --vp-c-black-mute: hsl(220 14% 17%); + --vp-c-gray: hsl(220 8% 56%); + --vp-c-gray-dark-1: hsl(220 10% 39%); + --vp-c-gray-dark-2: hsl(220 12% 28%); + --vp-c-gray-dark-3: hsl(220 12% 23%); + --vp-c-gray-dark-4: hsl(220 14% 17%); + --vp-c-gray-dark-5: hsl(220 16% 13%); + + /* // Backgrounds */ + /* --vp-c-bg: hsl(240, 2%, 11%); */ + --vp-custom-block-info-bg: hsl(220 14% 17%); + /* --vp-c-gutter: hsl(220 20% 9%); + + --vp-c-bg-alt: hsl(220 20% 9%); + --vp-c-bg-soft: hsl(220 14% 17%); + --vp-c-bg-mute: hsl(220 12% 23%); + */ +} + + /* Component: Algolia */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand) !important; +} + +/* Component: MathJax */ + +mjx-container > svg { + display: block; + margin: auto; +} + +mjx-container { + padding: 0.5rem 0; +} + +mjx-container { + display: inline-block; + margin: auto 2px -2px; +} + +mjx-container > svg { + margin: auto; + display: inline-block; +} + +/** + * Colors links + * -------------------------------------------------------------------------- */ + + :root { + --vp-c-brand-1: #CB3C33; + --vp-c-brand-2: #CB3C33; + --vp-c-brand-3: #CB3C33; + --vp-c-sponsor: #ca2971; + --vitest-c-sponsor-hover: #c13071; +} + +.dark { + --vp-c-brand-1: #91dd33; + --vp-c-brand-2: #91dd33; + --vp-c-brand-3: #91dd33; + --vp-c-sponsor: #91dd33; + --vitest-c-sponsor-hover: #e51370; +} \ No newline at end of file diff --git a/dev/JuMP-logo-dark.png b/dev/.documenter/assets/JuMP-logo-dark.png similarity index 100% rename from dev/JuMP-logo-dark.png rename to dev/.documenter/assets/JuMP-logo-dark.png diff --git a/dev/JuMP-logo.png b/dev/.documenter/assets/JuMP-logo.png similarity index 100% rename from dev/JuMP-logo.png rename to dev/.documenter/assets/JuMP-logo.png diff --git a/dev/logo.png b/dev/.documenter/assets/logo.png similarity index 100% rename from dev/logo.png rename to dev/.documenter/assets/logo.png diff --git a/dev/pluto-logo.png b/dev/.documenter/assets/pluto-logo.png similarity index 100% rename from dev/pluto-logo.png rename to dev/.documenter/assets/pluto-logo.png diff --git a/dev/toqubo-logo.png b/dev/.documenter/assets/toqubo-logo.png similarity index 100% rename from dev/toqubo-logo.png rename to dev/.documenter/assets/toqubo-logo.png diff --git a/dev/.documenter/constraints/comparison_constraints.md b/dev/.documenter/constraints/comparison_constraints.md new file mode 100644 index 0000000..2b84cf7 --- /dev/null +++ b/dev/.documenter/constraints/comparison_constraints.md @@ -0,0 +1,178 @@ + +# Constraints.jl: Streamlining Constraint Definition and Integration in Julia {#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia} + + + +### Comparison-based Constraints {#Comparison-based-Constraints} +
+# Constraints.xcsp_all_differentFunction. + + + + +```julia +xcsp_all_different(list::Vector{Int}) +``` + + +Return `true` if all the values of `list` are different, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + + +**Variants** +- `:all_different`: Global constraint ensuring that all the values of `x` are all different. + + +```julia +concept(:all_different, x; vals) +concept(:all_different)(x; vals) +``` + + +**Examples** + +```julia +c = concept(:all_different) + +c([1, 2, 3, 4]) +c([1, 2, 3, 1]) +c([1, 0, 0, 4]; vals=[0]) +c([1, 0, 0, 1]; vals=[0]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/all_different.jl#L7-L31) + +
+
+
+# Constraints.xcsp_all_equalFunction. + + + + +```julia +xcsp_all_equal(list::Vector{Int}, val::Int) +``` + + +Return `true` if all the values of `list` are equal to `val`, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `val::Int`: value to compare to. + + +**Variants** +- `:all_equal`: Global constraint ensuring that all the values of `x` are all equal. + + +```julia +concept(:all_equal, x; val=nothing, pair_vars=zeros(x), op=+) +concept(:all_equal)(x; val=nothing, pair_vars=zeros(x), op=+) +``` + + +**Examples** + +```julia +c = concept(:all_equal) + +c([0, 0, 0, 0]) +c([1, 2, 3, 4]) +c([3, 2, 1, 0]; pair_vars=[0, 1, 2, 3]) +c([0, 1, 2, 3]; pair_vars=[0, 1, 2, 3]) +c([1, 2, 3, 4]; op=/, val=1, pair_vars=[1, 2, 3, 4]) +c([1, 2, 3, 4]; op=*, val=1, pair_vars=[1, 2, 3, 4]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/all_equal.jl#L9-L36) + +
+
+
+# Constraints.xcsp_orderedFunction. + + + + +```julia +xcsp_ordered(list::Vector{Int}, operator, lengths) +``` + + +Return `true` if all the values of `list` are in an increasing order, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `operator`: comparison operator to use. + +- `lengths`: list of lengths to use. Defaults to `nothing`. + + +**Variants** +- `:ordered`: Global constraint ensuring that all the values of `x` are in an increasing order. + + +```julia +concept(:ordered, x; op=≤, pair_vars=nothing) +concept(:ordered)(x; op=≤, pair_vars=nothing) +``` + +- `:increasing`: Global constraint ensuring that all the values of `x` are in an increasing order. + + +```julia +concept(:increasing, x; op=≤, pair_vars=nothing) +concept(:increasing)(x; op=≤, pair_vars=nothing) +``` + +- `:decreasing`: Global constraint ensuring that all the values of `x` are in a decreasing order. + + +```julia +concept(:decreasing, x; op=≥, pair_vars=nothing) +concept(:decreasing)(x; op=≥, pair_vars=nothing) +``` + +- `:strictly_increasing`: Global constraint ensuring that all the values of `x` are in a strictly increasing order. + + +```julia +concept(:strictly_increasing, x; op=<, pair_vars=nothing) +concept(:strictly_increasing)(x; op=<, pair_vars=nothing) +``` + +- `:strictly_decreasing`: Global constraint ensuring that all the values of `x` are in a strictly decreasing order. + + +```julia +concept(:strictly_decreasing, x; op=>, pair_vars=nothing) +concept(:strictly_decreasing)(x; op=>, pair_vars=nothing) +``` + + +**Examples** + +```julia +c = concept(:ordered) + +c([1, 2, 3, 4, 4]; op=≤) +c([1, 2, 3, 4, 5]; op=<) +!c([1, 2, 3, 4, 3]; op=≤) +!c([1, 2, 3, 4, 3]; op=<) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/ordered.jl#L21-L67) + +
+
diff --git a/dev/.documenter/constraints/connection_constraints.md b/dev/.documenter/constraints/connection_constraints.md new file mode 100644 index 0000000..edee165 --- /dev/null +++ b/dev/.documenter/constraints/connection_constraints.md @@ -0,0 +1,189 @@ + +# Constraints.jl: Streamlining Constraint Definition and Integration in Julia {#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia} + + + +### Connection Constraints {#Connection-Constraints} +
+# Constraints.xcsp_maximumFunction. + + + + +```julia +xcsp_maximum(; list, condition) +``` + + +Return `true` if the maximum constraint is satisfied, `false` otherwise. The maximum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the maximum value in a list of variables. + +**Arguments** +- `list::Union{AbstractVector, Tuple}`: list of values to check. + +- `condition::Tuple`: condition to check. + + +**Variants** +- `:maximum`: The maximum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the maximum value in a list of variables. + + +```julia +concept(:maximum, x; op, val) +concept(:maximum)(x; op, val) +``` + + +**Examples** + +```julia +c = concept(:maximum) + +c([1, 2, 3, 4, 5]; op = ==, val = 5) +c([1, 2, 3, 4, 5]; op = ==, val = 6) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/maximum.jl#L5-L28) + +
+
+
+# Constraints.xcsp_minimumFunction. + + + + +```julia +xcsp_minimum(; list, condition) +``` + + +Return `true` if the minimum constraint is satisfied, `false` otherwise. The minimum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the minimum value in a list of variables. + +**Arguments** +- `list::Union{AbstractVector, Tuple}`: list of values to check. + +- `condition::Tuple`: condition to check. + + +**Variants** +- `:minimum`: The minimum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the minimum value in a list of variables. + + +```julia +concept(:minimum, x; op, val) +concept(:minimum)(x; op, val) +``` + + +**Examples** + +```julia +c = concept(:minimum) + +c([1, 2, 3, 4, 5]; op = ==, val = 1) +c([1, 2, 3, 4, 5]; op = ==, val = 0) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/minimum.jl#L5-L28) + +
+
+
+# Constraints.xcsp_elementFunction. + + + + +```julia +xcsp_element(; list, index, condition) +``` + + +Return `true` if the element constraint is satisfied, `false` otherwise. The element constraint is a global constraint used in constraint programming that specifies that the value of a variable should be equal to the value of another variable indexed by a third variable. + +**Arguments** +- `list::Union{AbstractVector, Tuple}`: list of values to check. + +- `index::Int`: index of the value to check. + +- `condition::Tuple`: condition to check. + + +**Variants** +- `:element`: The element constraint is a global constraint used in constraint programming that specifies that the value of a variable should be equal to the value of another variable indexed by a third variable. + + +```julia +concept(:element, x; id=nothing, op===, val=nothing) +concept(:element)(x; id=nothing, op===, val=nothing) +``` + + +**Examples** + +```julia +c = concept(:element) + +c([1, 2, 3, 4, 5]; id=1, val=1) +c([1, 2, 3, 4, 5]; id=1, val=2) +c([1, 2, 3, 4, 2]) +c([1, 2, 3, 4, 1]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/element.jl#L5-L31) + +
+
+
+# Constraints.xcsp_channelFunction. + + + + +```julia +xcsp_channel(; list) +``` + + +Return `true` if the channel constraint is satisfied, `false` otherwise. The channel constraint establishes a bijective correspondence between two sets of variables. This means that each value in the first set of variables corresponds to a unique value in the second set, and vice versa. + +**Arguments** +- `list::Union{AbstractVector, Tuple}`: list of values to check. + + +**Variants** +- `:channel`: The channel constraint establishes a bijective correspondence between two sets of variables. This means that each value in the first set of variables corresponds to a unique value in the second set, and vice versa. + + +```julia +concept(:channel, x; dim=1, id=nothing) +concept(:channel)(x; dim=1, id=nothing) +``` + + +**Examples** + +```julia +c = concept(:channel) + +c([2, 1, 4, 3]) +c([1, 2, 3, 4]) +c([2, 3, 1, 4]) +c([2, 1, 5, 3, 4, 2, 1, 4, 5, 3]; dim=2) +c([2, 1, 4, 3, 5, 2, 1, 4, 5, 3]; dim=2) +c([false, false, true, false]; id=3) +c([false, false, true, false]; id=1) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/channel.jl#L5-L32) + +
+
diff --git a/dev/.documenter/constraints/constraint_commons.md b/dev/.documenter/constraints/constraint_commons.md new file mode 100644 index 0000000..2b3ecb2 --- /dev/null +++ b/dev/.documenter/constraints/constraint_commons.md @@ -0,0 +1,333 @@ + +# ConstraintCommons.jl + +_ConstraintCommons.jl_ is an essential package within the _Julia Constraints_ ecosystem designed to facilitate the development and interoperability of constraint programming solutions in Julia. It serves as a foundational layer that provides shared structures, abstract types, functions, and generic methods utilized by both basic feature packages and learning-oriented packages. + + + +## Key Features and Functionalities {#Key-Features-and-Functionalities} +- **Shared Structures and Abstract Types**: ConstraintCommons.jl offers a collection of shared data structures and abstract types. This standardization is crucial for ensuring that packages such as ConstraintDomains, Constraints, ConstraintLearning, etc. can seamlessly interact and integrate, fostering a cohesive development environment. + +- **Generic Functions and Methods**: The package includes a set of generic functions and methods that are common across the JuliaConstraints ecosystem. This approach minimizes duplication and facilitates the extension of functionalities across different packages without requiring redundant code. + +- **Interface for Learning and Application Transition**: One of the pivotal roles of ConstraintCommons.jl is to provide a shared interface that bridges the gap between learning packages (e.g., CompositionalNetworks, QUBOConstraints, and ConstraintTranslator) and basic functionality packages. This interface ensures that once a learning process is complete, the resulting models or solutions can be directly utilized with the basic packages, eliminating the need for users to manage multiple package dependencies actively. + +- **Simplifying the User Experience**: By ensuring that learning outcomes are compatible with the fundamental packages for constraint programming, ConstraintCommons.jl simplifies the workflow for end-users. Once the learning aspect of problem modeling is completed, users can proceed with their projects relying solely on the basic packages, streamlining the development process and enhancing usability. + +- **Impact on the JuliaConstraints Ecosystem**: ConstraintCommons.jl plays a critical role in the JuliaConstraints ecosystem by providing the foundational elements that enable package interoperability and efficient development workflows. Its design emphasizes ease of use and seamless transition between the learning phase of constraint programming and practical application, thereby enhancing productivity and reducing the complexity of developing constraint-based solutions. + + +## Parameters + +This section of the package list or extract parameters based on the _XCSP3-core_ specifications. Note that, for the forseeable future, the default constraints specification will follow the XCSP3 format. +
+# ConstraintCommons.USUAL_CONSTRAINT_PARAMETERSConstant. + + + + +```julia +const USUAL_CONSTRAINT_PARAMETERS +``` + + +List of usual constraints parameters (based on XCSP3-core constraints). + +```julia +const USUAL_CONSTRAINT_PARAMETERS = [ + :bool, + :dim, + :id, + :language, + :op, + :pair_vars, + :val, + :vals, +] +``` + + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/parameters.jl#L1-L17) + +
+
+
+# ConstraintCommons.extract_parametersFunction. + + + + +```julia +extract_parameters(m::Union{Method, Function}; parameters) +``` + + +Extracts the intersection between the `kargs` of `m` and `parameters` (defaults to `USUAL_CONSTRAINT_PARAMETERS`). + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/parameters.jl#L21-L25) + + + +```julia +extract_parameters(s::Symbol, constraints_dict=USUAL_CONSTRAINTS; parameters=ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS) +``` + + +Return the parameters of the constraint `s` in `constraints_dict`. + +**Arguments** +- `s::Symbol`: the constraint name. + +- `constraints_dict::Dict{Symbol,Constraint}`: dictionary of constraints. Default is `USUAL_CONSTRAINTS`. + +- `parameters::Vector{Symbol}`: vector of parameters. Default is `ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS`. + + +**Example** + +```julia +extract_parameters(:all_different) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L44-L58) + +
+
+ +### Performances – TODO {#Performances-–-TODO} + +## Languages + +_XCSP3_ considers two kinds of structure to recognize languages as core constraints: Automata, Multivalued Decision Diagrams (MMDs). +
+# ConstraintCommons.AbstractMultivaluedDecisionDiagramType. + + + + +```julia +AbstractMultivaluedDecisionDiagram +``` + + +An abstract interface for Multivalued Decision Diagrams (MDD) used in Julia Constraints packages. Requirements: +- `accept(a<:AbstractMultivaluedDecisionDiagram, word)`: return `true` if `a` accepts `word`. + + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/diagrams.jl#L1-L6) + +
+
+
+# ConstraintCommons.MDDType. + + + + +```julia +MDD{S,T} <: AbstractMultivaluedDecisionDiagram +``` + + +A minimal implementation of a multivalued decision diagram structure. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/diagrams.jl#L9-L13) + +
+
+
+# ConstraintCommons.AbstractAutomatonType. + + + + +```julia +AbstractAutomaton +``` + + +An abstract interface for automata used in Julia Constraints packages. Requirements: +- `accept(a<:AbstractAutomaton, word)`: return `true` if `a` accepts `word`. + + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/automata.jl#L1-L6) + +
+
+
+# ConstraintCommons.AutomatonType. + + + + +```julia +Automaton{S, T, F <: Union{S, Vector{S}, Set{S}}} <: AbstractAutomaton +``` + + +A minimal implementation of a deterministic automaton structure. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/automata.jl#L9-L13) + +
+
+ +::: warning Missing docstring. + +Missing docstring for `Automaton(a::MDD)`. Check Documenter's build log for details. + +::: +
+# ConstraintCommons.acceptFunction. + + + + +```julia +accept(a::Union{Automaton, MDD}, w) +``` + + +Return `true` if `a` accepts the word `w` and `false` otherwise. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/automata.jl#L29-L33) + + + +```julia +ConstraintCommons.accept(fa::FakeAutomaton, word) +``` + + +Implement the `accept` methods for `FakeAutomaton`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L41-L45) + +
+
+
+# ConstraintCommons.at_endFunction. + + + + +```julia +at_end(a::Automaton, s) +``` + + +Internal method used by `accept` with `Automaton`. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/automata.jl#L20-L24) + +
+
+ +### Performances – TODO {#Performances-–-TODO-2} + +## Extensions + +We extended some operations for `Nothing` and `Symbol`. + +::: warning Missing docstring. + +Missing docstring for `Base.:*`. Check Documenter's build log for details. + +::: + +::: warning Missing docstring. + +Missing docstring for `Base.in(::Any, ::Nothing)`. Check Documenter's build log for details. + +::: + +::: warning Missing docstring. + +Missing docstring for `Base.isempty(::Nothing)`. Check Documenter's build log for details. + +::: + +### Performances – TODO {#Performances-–-TODO-3} + +## Sampling + +During our constraint learning processes, we use sampling to efficiently make partial exploration of search spaces. Follows some sampling utilities. +
+# ConstraintCommons.oversampleFunction. + + + + +```julia +oversample(X, f) +``` + + +Oversample elements of `X` until the boolean function `f` has as many `true` and `false` configurations. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/sampling.jl#L1-L5) + +
+
+ +### Performances – TODO {#Performances-–-TODO-4} + +## Extrema + +We need to compute the difference between extrema of various kind of collections in several situations. +
+# ConstraintCommons.δ_extremaFunction. + + + + +```julia +δ_extrema(X...) +``` + + +Compute both the difference between the maximum and the minimum of over all the collections of `X`. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/extrema.jl#L1-L4) + +
+
+ +### Performances – TODO {#Performances-–-TODO-5} + +## Dictionaries + +We provide the everuseful `incsert!` function for dictionaries. +
+# ConstraintCommons.incsert!Function. + + + + +```julia +incsert!(d::Union{AbstractDict, AbstractDictionary}, ind, val = 1) +``` + + +Increase or insert a counter in a dictionary-based collection. The counter insertion defaults to `val = 1`. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/dictionaries.jl#L2-L6) + +
+
+ +### Performances – TODO {#Performances-–-TODO-6} diff --git a/dev/.documenter/constraints/constraint_domains.md b/dev/.documenter/constraints/constraint_domains.md new file mode 100644 index 0000000..7b22526 --- /dev/null +++ b/dev/.documenter/constraints/constraint_domains.md @@ -0,0 +1,1736 @@ + +# ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints {#ConstraintDomains.jl:-Defining-and-Exploring-Variable-Domains-within-JuliaConstraints} + + + +_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. + +## Key Features and Functionalities {#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 {#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. + +## Commons +
+# ConstraintDomains.AbstractDomainType. + + + + +```julia +AbstractDomain +``` + + +An abstract super type for any domain type. A domain type `D <: AbstractDomain` must implement the following methods to properly interface `AbstractDomain`. +- `Base.∈(val, ::D)` + +- `Base.rand(::D)` + +- `Base.length(::D)` that is the number of elements in a discrete domain, and the distance between bounds or similar for a continuous domain + + +Additionally, if the domain is used in a dynamic context, it can extend +- `add!(::D, args)` + +- `delete!(::D, args)` + + +where `args` depends on `D`'s structure + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L1-L11) + +
+
+
+# ConstraintDomains.EmptyDomainType. + + + + +```julia +EmptyDomain +``` + + +A struct to handle yet to be defined domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L14-L17) + +
+
+
+# ConstraintDomains.domainFunction. + + + + +```julia +domain() +``` + + +Construct an `EmptyDomain`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L20-L23) + + + +```julia +domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real} +domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real} +``` + + +Construct a domain of continuous interval(s). + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L15-L19) + + + +```julia +domain(values) +domain(range::R) where {T <: Real, R <: AbstractRange{T}} +``` + + +Construct either a `SetDomain` or a `RangeDomain``. + +```julia +d1 = domain(1:5) +d2 = domain([53.69, 89.2, 0.12]) +d3 = domain([2//3, 89//123]) +d4 = domain(4.3) +d5 = domain(1,42,86.9) +``` + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L31-L42) + +
+
+
+# ConstraintDomains.domain_sizeFunction. + + + + +```julia +domain_size(d <: AbstractDomain) +``` + + +Fallback method for `domain_size(d)` that return `length(d)`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L46-L49) + + + +```julia +domain_size(itv::Intervals) +``` + + +Return the difference between the highest and lowest values in `itv`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L61-L64) + + + +```julia +domain_size(d::D) where D <: DiscreteDomain +``` + + +Return the maximum distance between two points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L64-L67) + +
+
+
+# ConstraintDomains.get_domainFunction. + + + + +```julia +get_domain(::AbstractDomain) +``` + + +Access the internal structure of any domain type. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L52-L55) + +
+
+
+# ConstraintDomains.to_domainsFunction. + + + + +```julia +to_domains(args...) +``` + + +Convert various arguments into valid domains format. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L58-L62) + +
+
+ +### Extension to Base module {#Extension-to-Base-module} +
+# Base.inFunction. + + + + +```julia +x::Variable ∈ constraint +value ∈ x::Variable +``` + + +Check if a variable `x` is restricted by a `constraint::Int`, or if a `value` belongs to the domain of `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/variable.jl#L52-L56) + + + +```julia +var::Int ∈ c::Constraint +``` + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/constraint.jl#L43-L45) + + + +```julia +Base.in(value, d <: AbstractDomain) +``` + + +Fallback method for `value ∈ d` that returns `false`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L28-L31) + + + +```julia +Base.in(x, itv::Intervals) +``` + + +Return `true` if `x ∈ I` for any 'I ∈ itv`, false otherwise.`x ∈ I` is equivalent to +- `a < x < b` if `I = (a, b)` + +- `a < x ≤ b` if `I = (a, b]` + +- `a ≤ x < b` if `I = [a, b)` + +- `a ≤ x ≤ b` if `I = [a, b]` + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L51-L58) + + + +```julia +Base.in(value, d::D) where D <: DiscreteDomain +``` + + +Return `true` if `value` is a point of `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L58-L61) + +
+
+
+# Base.randFunction. + + + + +```julia +Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain} +``` + + +Extends `Base.rand` to (a collection of) domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L72-L76) + + + +```julia +Base.rand(itv::Intervals) +Base.rand(itv::Intervals, i) +``` + + +Return a random value from `itv`, specifically from the `i`th interval if `i` is specified. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L32-L36) + + + +```julia +Base.rand(d::D) where D <: DiscreteDomain +``` + + +Draw randomly a point in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L52-L55) + + + +```julia +Base.rand(fa::FakeAutomaton) +``` + + +Extends `Base.rand`. Currently simply returns `fa`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L135-L139) + +
+
+
+# Base.isemptyFunction. + + + + +```julia +Base.isempty(d <: AbstractDomain) +``` + + +Fallback method for `isempty(d)` that return `length(d) == 0` which default to `0`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L40-L43) + +
+
+
+# Base.randFunction. + + + + +```julia +Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain} +``` + + +Extends `Base.rand` to (a collection of) domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L72-L76) + + + +```julia +Base.rand(itv::Intervals) +Base.rand(itv::Intervals, i) +``` + + +Return a random value from `itv`, specifically from the `i`th interval if `i` is specified. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L32-L36) + + + +```julia +Base.rand(d::D) where D <: DiscreteDomain +``` + + +Draw randomly a point in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L52-L55) + + + +```julia +Base.rand(fa::FakeAutomaton) +``` + + +Extends `Base.rand`. Currently simply returns `fa`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L135-L139) + +
+
+
+# Base.stringFunction. + + + + +```julia +Base.string(D::Vector{<:AbstractDomain}) +Base.string(d<:AbstractDomain) +``` + + +Extends the `string` method to (a vector of) domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L87-L92) + +
+
+ +### Performances + +## Continuous +
+# ConstraintDomains.ContinuousDomainType. + + + + +```julia +ContinuousDomain{T <: Real} <: AbstractDomain +``` + + +An abstract supertype for all continuous domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L1-L4) + +
+
+
+# ConstraintDomains.IntervalsType. + + + + +```julia +Intervals{T <: Real} <: ContinuousDomain{T} +``` + + +An encapsuler to store a vector of `PatternFolds.Interval`. Dynamic changes to `Intervals` are not handled yet. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L7-L10) + +
+
+
+# ConstraintDomains.domainFunction. + + + + +```julia +domain() +``` + + +Construct an `EmptyDomain`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L20-L23) + + + +```julia +domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real} +domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real} +``` + + +Construct a domain of continuous interval(s). + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L15-L19) + + + +```julia +domain(values) +domain(range::R) where {T <: Real, R <: AbstractRange{T}} +``` + + +Construct either a `SetDomain` or a `RangeDomain``. + +```julia +d1 = domain(1:5) +d2 = domain([53.69, 89.2, 0.12]) +d3 = domain([2//3, 89//123]) +d4 = domain(4.3) +d5 = domain(1,42,86.9) +``` + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L31-L42) + +
+
+
+# ConstraintDomains.domain_sizeFunction. + + + + +```julia +domain_size(d <: AbstractDomain) +``` + + +Fallback method for `domain_size(d)` that return `length(d)`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L46-L49) + + + +```julia +domain_size(itv::Intervals) +``` + + +Return the difference between the highest and lowest values in `itv`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L61-L64) + + + +```julia +domain_size(d::D) where D <: DiscreteDomain +``` + + +Return the maximum distance between two points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L64-L67) + +
+
+
+# ConstraintDomains.merge_domainsFunction. + + + + +```julia +merge_domains(d₁::AbstractDomain, d₂::AbstractDomain) +``` + + +Merge two domains of same nature (discrete/contiuous). + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L83-L87) + +
+
+
+# ConstraintDomains.intersect_domainsFunction. + + + + +```julia +intersect_domains(d₁, d₂) +``` + + +Compute the intersections of two domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L72-L76) + +
+
+
+# ConstraintDomains.intersect_domains!Function. + + + + +```julia +intersect_domains!(is, i, new_itvls) +``` + + +Compute the intersections of a domain with an interval and store the results in `new_itvls`. + +**Arguments** +- `is::IS`: a collection of intervals. + +- `i::I`: an interval. + +- `new_itvls::Vector{I}`: a vector to store the results. + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L89-L98) + +
+
+
+# ConstraintDomains.sizeFunction. + + + + +```julia +Base.size(i::I) where {I <: Interval} +``` + + +Defines the size of an interval as its `span`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L118-L122) + +
+
+ +### Extension to Base module {#Extension-to-Base-module-2} +
+# Base.lengthFunction. + + + + +```julia +length(layer) +``` + + +Return the number of operations in a layer. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L17-L20) + + + +```julia +Base.length(icn) +``` + + +Return the total number of operations of an ICN. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L37-L40) + + + +```julia +Base.rand(d <: AbstractDomain) +``` + + +Fallback method for `length(d)` that return `0`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L34-L37) + + + +```julia +Base.length(itv::Intervals) +``` + + +Return the sum of the length of each interval in `itv`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L26-L29) + + + +```julia +Base.length(d::D) where D <: DiscreteDomain +``` + + +Return the number of points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L46-L49) + +
+
+
+# Base.randFunction. + + + + +```julia +Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain} +``` + + +Extends `Base.rand` to (a collection of) domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L72-L76) + + + +```julia +Base.rand(itv::Intervals) +Base.rand(itv::Intervals, i) +``` + + +Return a random value from `itv`, specifically from the `i`th interval if `i` is specified. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L32-L36) + + + +```julia +Base.rand(d::D) where D <: DiscreteDomain +``` + + +Draw randomly a point in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L52-L55) + + + +```julia +Base.rand(fa::FakeAutomaton) +``` + + +Extends `Base.rand`. Currently simply returns `fa`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L135-L139) + +
+
+
+# Base.inFunction. + + + + +```julia +x::Variable ∈ constraint +value ∈ x::Variable +``` + + +Check if a variable `x` is restricted by a `constraint::Int`, or if a `value` belongs to the domain of `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/variable.jl#L52-L56) + + + +```julia +var::Int ∈ c::Constraint +``` + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/constraint.jl#L43-L45) + + + +```julia +Base.in(value, d <: AbstractDomain) +``` + + +Fallback method for `value ∈ d` that returns `false`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L28-L31) + + + +```julia +Base.in(x, itv::Intervals) +``` + + +Return `true` if `x ∈ I` for any 'I ∈ itv`, false otherwise.`x ∈ I` is equivalent to +- `a < x < b` if `I = (a, b)` + +- `a < x ≤ b` if `I = (a, b]` + +- `a ≤ x < b` if `I = [a, b)` + +- `a ≤ x ≤ b` if `I = [a, b]` + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L51-L58) + + + +```julia +Base.in(value, d::D) where D <: DiscreteDomain +``` + + +Return `true` if `value` is a point of `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L58-L61) + +
+
+
+# Base.stringFunction. + + + + +```julia +Base.string(D::Vector{<:AbstractDomain}) +Base.string(d<:AbstractDomain) +``` + + +Extends the `string` method to (a vector of) domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L87-L92) + +
+
+ +## Discrete +
+# ConstraintDomains.DiscreteDomainType. + + + + +```julia +DiscreteDomain{T <: Number} <: AbstractDomain +``` + + +An abstract supertype for discrete domains (set, range). + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L1-L4) + +
+
+
+# ConstraintDomains.SetDomainType. + + + + +```julia +SetDomain{T <: Number} <: DiscreteDomain{T} +``` + + +Domain that stores discrete values as a set of (unordered) points. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L7-L10) + +
+
+
+# ConstraintDomains.RangeDomainType. + + + + +```julia +RangeDomain +``` + + +A discrete domain defined by a `range <: AbstractRange{Real}`. As ranges are immutable in Julia, changes in `RangeDomain` must use `set_domain!`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L16-L19) + +
+
+
+# ConstraintDomains.ArbitraryDomainFunction. + + + + +```julia +ArbitraryDomain{T} <: DiscreteDomain{T} +``` + + +A domain type that stores arbitrary values, possibly non numeric, of type `T`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L24-L28) + +
+
+
+# ConstraintDomains.domainFunction. + + + + +```julia +domain() +``` + + +Construct an `EmptyDomain`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L20-L23) + + + +```julia +domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real} +domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real} +``` + + +Construct a domain of continuous interval(s). + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L15-L19) + + + +```julia +domain(values) +domain(range::R) where {T <: Real, R <: AbstractRange{T}} +``` + + +Construct either a `SetDomain` or a `RangeDomain``. + +```julia +d1 = domain(1:5) +d2 = domain([53.69, 89.2, 0.12]) +d3 = domain([2//3, 89//123]) +d4 = domain(4.3) +d5 = domain(1,42,86.9) +``` + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L31-L42) + +
+
+
+# ConstraintDomains.domain_sizeFunction. + + + + +```julia +domain_size(d <: AbstractDomain) +``` + + +Fallback method for `domain_size(d)` that return `length(d)`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L46-L49) + + + +```julia +domain_size(itv::Intervals) +``` + + +Return the difference between the highest and lowest values in `itv`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L61-L64) + + + +```julia +domain_size(d::D) where D <: DiscreteDomain +``` + + +Return the maximum distance between two points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L64-L67) + +
+
+
+# ConstraintDomains.add!Function. + + + + +```julia +add!(d::SetDomain, value) +``` + + +Add `value` to the list of points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L70-L73) + +
+
+
+# ConstraintDomains.merge_domainsFunction. + + + + +```julia +merge_domains(d₁::AbstractDomain, d₂::AbstractDomain) +``` + + +Merge two domains of same nature (discrete/contiuous). + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L83-L87) + +
+
+
+# ConstraintDomains.intersect_domainsFunction. + + + + +```julia +intersect_domains(d₁, d₂) +``` + + +Compute the intersections of two domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L72-L76) + +
+
+
+# ConstraintDomains.sizeFunction. + + + + +```julia +Base.size(i::I) where {I <: Interval} +``` + + +Defines the size of an interval as its `span`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L118-L122) + +
+
+ +### Extension to Base module {#Extension-to-Base-module-3} +
+# Base.delete!Function. + + + + +```julia +Base.delete!(d::SetDomain, value)(d::SetDomain, value) +``` + + +Delete `value` from the list of points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L76-L79) + +
+
+
+# Base.lengthFunction. + + + + +```julia +length(layer) +``` + + +Return the number of operations in a layer. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L17-L20) + + + +```julia +Base.length(icn) +``` + + +Return the total number of operations of an ICN. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L37-L40) + + + +```julia +Base.rand(d <: AbstractDomain) +``` + + +Fallback method for `length(d)` that return `0`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L34-L37) + + + +```julia +Base.length(itv::Intervals) +``` + + +Return the sum of the length of each interval in `itv`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L26-L29) + + + +```julia +Base.length(d::D) where D <: DiscreteDomain +``` + + +Return the number of points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L46-L49) + +
+
+
+# Base.randFunction. + + + + +```julia +Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain} +``` + + +Extends `Base.rand` to (a collection of) domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L72-L76) + + + +```julia +Base.rand(itv::Intervals) +Base.rand(itv::Intervals, i) +``` + + +Return a random value from `itv`, specifically from the `i`th interval if `i` is specified. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L32-L36) + + + +```julia +Base.rand(d::D) where D <: DiscreteDomain +``` + + +Draw randomly a point in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L52-L55) + + + +```julia +Base.rand(fa::FakeAutomaton) +``` + + +Extends `Base.rand`. Currently simply returns `fa`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L135-L139) + +
+
+
+# Base.inFunction. + + + + +```julia +x::Variable ∈ constraint +value ∈ x::Variable +``` + + +Check if a variable `x` is restricted by a `constraint::Int`, or if a `value` belongs to the domain of `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/variable.jl#L52-L56) + + + +```julia +var::Int ∈ c::Constraint +``` + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/constraint.jl#L43-L45) + + + +```julia +Base.in(value, d <: AbstractDomain) +``` + + +Fallback method for `value ∈ d` that returns `false`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L28-L31) + + + +```julia +Base.in(x, itv::Intervals) +``` + + +Return `true` if `x ∈ I` for any 'I ∈ itv`, false otherwise.`x ∈ I` is equivalent to +- `a < x < b` if `I = (a, b)` + +- `a < x ≤ b` if `I = (a, b]` + +- `a ≤ x < b` if `I = [a, b)` + +- `a ≤ x ≤ b` if `I = [a, b]` + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L51-L58) + + + +```julia +Base.in(value, d::D) where D <: DiscreteDomain +``` + + +Return `true` if `value` is a point of `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L58-L61) + +
+
+
+# Base.stringFunction. + + + + +```julia +Base.string(D::Vector{<:AbstractDomain}) +Base.string(d<:AbstractDomain) +``` + + +Extends the `string` method to (a vector of) domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L87-L92) + +
+
+ +## General +
+# Base.eltypeFunction. + + + + +```julia +Base.eltype(::AbstractDomain) +``` + + +Extend `eltype` for domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/general.jl#L1-L5) + +
+
+
+# Base.convertFunction. + + + + +```julia +Base.convert(::Type{Union{Intervals, RangeDomain}}, d::Union{Intervals, RangeDomain}) +``` + + +Extends `Base.convert` for domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/general.jl#L9-L13) + +
+
+ +## Exploration +
+# ConstraintDomains.ExploreSettingsType. + + + + +```julia +ExploreSettings( + domains; + complete_search_limit = 10^6, + max_samplings = sum(domain_size, domains), + search = :flexible, + solutions_limit = floor(Int, sqrt(max_samplings)), +) +``` + + +Settings for the exploration of a search space composed by a collection of domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/explore.jl#L8-L18) + +
+
+
+# ConstraintDomains._exploreFunction. + + + + +```julia +_explore(args...) +``` + + +Internals of the `explore` function. Behavior is automatically adjusted on the kind of exploration: `:flexible`, `:complete`, `:partial`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/explore.jl#L29-L33) + +
+
+
+# ConstraintDomains.exploreFunction. + + + + +```julia +explore(domains, concept, param = nothing; search_limit = 1000, solutions_limit = 100) +``` + + +Search (a part of) a search space and returns a pair of vector of configurations: `(solutions, non_solutions)`. If the search space size is over `search_limit`, then both `solutions` and `non_solutions` are limited to `solutions_limit`. + +Beware that if the density of the solutions in the search space is low, `solutions_limit` needs to be reduced. This process will be automatic in the future (simple reinforcement learning). + +**Arguments:** +- `domains`: a collection of domains + +- `concept`: the concept of the targeted constraint + +- `param`: an optional parameter of the constraint + +- `sol_number`: the required number of solutions (half of the number of configurations), default to `100` + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/explore.jl#L66-L78) + +
+
+ +## Parameters +
+# ConstraintDomains.BoolParameterDomainType. + + + + +```julia +BoolParameterDomain <: AbstractDomain +``` + + +A domain to store boolean values. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L1-L5) + +
+
+
+# ConstraintDomains.DimParameterDomainType. + + + + +```julia +DimParameterDomain <: AbstractDomain +``` + + +A domain to store dimensions. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L10-L14) + +
+
+
+# ConstraintDomains.IdParameterDomainType. + + + + +```julia +IdParameterDomain <: AbstractDomain +``` + + +A domain to store ids. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L21-L25) + +
+
+
+# ConstraintDomains.FakeAutomatonType. + + + + +```julia +FakeAutomaton{T} <: ConstraintCommons.AbstractAutomaton +``` + + +A structure to generate pseudo automaton enough for parameter exploration. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L32-L36) + +
+
+
+# ConstraintCommons.acceptFunction. + + + + +```julia +accept(a::Union{Automaton, MDD}, w) +``` + + +Return `true` if `a` accepts the word `w` and `false` otherwise. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/automata.jl#L29-L33) + + + +```julia +ConstraintCommons.accept(fa::FakeAutomaton, word) +``` + + +Implement the `accept` methods for `FakeAutomaton`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L41-L45) + +
+
+
+# ConstraintDomains.fake_automatonFunction. + + + + +```julia +fake_automaton(d) +``` + + +Construct a `FakeAutomaton`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L48-L52) + +
+
+
+# ConstraintDomains.LanguageParameterDomainType. + + + + +```julia +LanguageParameterDomain <: AbstractDomain +``` + + +A domain to store languages. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L62-L66) + +
+
+
+# ConstraintDomains.OpParameterDomainType. + + + + +```julia +OpParameterDomain{T} <: AbstractDomain +``` + + +A domain to store operators. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L75-L79) + +
+
+
+# ConstraintDomains.PairVarsParameterDomainType. + + + + +```julia +PairVarsParameterDomain{T} <: AbstractDomain +``` + + +A domain to store values paired with variables. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L86-L90) + +
+
+
+# ConstraintDomains.ValParameterDomainType. + + + + +```julia +ValParameterDomain{T} <: AbstractDomain +``` + + +A domain to store one value. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L99-L103) + +
+
+
+# ConstraintDomains.ValsParameterDomainType. + + + + +```julia +ValsParameterDomain{T} <: AbstractDomain +``` + + +A domain to store values. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L110-L114) + +
+
+
+# Base.randFunction. + + + + +```julia +Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain} +``` + + +Extends `Base.rand` to (a collection of) domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L72-L76) + + + +```julia +Base.rand(itv::Intervals) +Base.rand(itv::Intervals, i) +``` + + +Return a random value from `itv`, specifically from the `i`th interval if `i` is specified. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L32-L36) + + + +```julia +Base.rand(d::D) where D <: DiscreteDomain +``` + + +Draw randomly a point in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L52-L55) + + + +```julia +Base.rand(fa::FakeAutomaton) +``` + + +Extends `Base.rand`. Currently simply returns `fa`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L135-L139) + +
+
+
+# ConstraintDomains.generate_parametersFunction. + + + + +```julia +generate_parameters(d<:AbstractDomain, param) +``` + + +Generates random parameters based on the domain `d` and the kind of parameters `param`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L128-L132) + +
+
diff --git a/dev/.documenter/constraints/constraint_models.md b/dev/.documenter/constraints/constraint_models.md new file mode 100644 index 0000000..fc1891a --- /dev/null +++ b/dev/.documenter/constraints/constraint_models.md @@ -0,0 +1,425 @@ + +# ConstraintModels.jl + +Documentation for `ConstraintModels.jl`. +
+# ConstraintModels.SudokuInstanceType. + + + + +```julia +mutable struct SudokuInstance{T <: Integer} <: AbstractMatrix{T} +``` + + +**A `struct` for SudokuInstances, which is a subtype of `AbstractMatrix`.** + +```julia +SudokuInstance(A::AbstractMatrix{T}) +SudokuInstance(::Type{T}, n::Int) # fill in blank sudoku of type T +SudokuInstance(n::Int) # fill in blank sudoku of type Int +SudokuInstance(::Type{T}) # fill in "standard" 9×9 sudoku of type T +SudokuInstance() # fill in "standard" 9×9 sudoku of type Int +SudokuInstance(n::Int, P::Pair{Tuple{Int, Int}, T}...) where {T <: Integer} # construct a sudoku given pairs of coordinates and values +SudokuInstance(P::Pair{Tuple{Int, Int}, T}...) # again, default to 9×9 sudoku, constructing given pairs +``` + + +Constructor functions for the `SudokuInstance` `struct`. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L124-L140) + +
+
+
+# ConstraintModels.SudokuInstanceMethod. + + + + +```julia +SudokuInstance(X::Dictionary) +``` + + +Construct a `SudokuInstance` with the values `X` of a solver as input. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L167-L171) + +
+
+
+# Base.Multimedia.displayMethod. + + + + +```julia +display(io::IO, S::SudokuInstance) +display(S::SudokuInstance) # default to stdout +``` + + +Displays an $n\times n$ SudokuInstance. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L314-L320) + +
+
+
+# Base.Multimedia.displayMethod. + + + + +```julia +Base.display(X, Val(:sudoku)) +``` + + +Extends `Base.display` to a sudoku configuration. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L350-L354) + +
+
+
+# Base.Multimedia.displayMethod. + + + + +```julia +Base.display(S::SudokuInstance) +``` + + +Extends `Base.display` to `SudokuInstance`. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L336-L340) + +
+
+
+# Base.Multimedia.displayMethod. + + + + +```julia +Base.display(X::Dictionary) +``` + + +Extends `Base.display` to a sudoku configuration. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L343-L347) + +
+
+
+# Base.sizeMethod. + + + + +```julia +Base.size(S::SudokuInstance) +``` + + +Extends `Base.size` for `SudokuInstance`. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L183-L187) + +
+
+
+# ConstraintModels._format_lineMethod. + + + + +```julia +_format_line(r, M) +``` + + +Format line of a sudoku grid. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L251-L255) + +
+
+
+# ConstraintModels._format_line_segmentMethod. + + + + +```julia +_format_line_segment(r, col_pos, M) +``` + + +Format line segment of a sudoku grid. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L230-L234) + +
+
+
+# ConstraintModels._format_valMethod. + + + + +```julia +_format_val(a) +``` + + +Format an integer `a` into a string for SudokuInstance. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L223-L227) + +
+
+
+# ConstraintModels._get_sep_lineMethod. + + + + +```julia +_get_sep_line(s, pos_row, M) +``` + + +Return a line separator. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L268-L272) + +
+
+
+# ConstraintModels.chemical_equilibriumMethod. + + + + +```julia +chemical_equilibrium(atoms_compounds, elements_weights, standard_free_energy; modeler = :JuMP) +``` + + +::: warning Warning + +Even the structure to model problems with continuous domains is available, the default solver is not yet equiped to solve such problems efficiently. + +::: + +**From Wikipedia** + +In a chemical reaction, chemical equilibrium is the state in which both the reactants and products are present in concentrations which have no further tendency to change with time, so that there is no observable change in the properties of the system. This state results when the forward reaction proceeds at the same rate as the reverse reaction. The reaction rates of the forward and backward reactions are generally not zero, but they are equal. Thus, there are no net changes in the concentrations of the reactants and products. Such a state is known as dynamic equilibrium. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/chemical_equilibrium.jl#L30-L40) + +
+
+
+# ConstraintModels.golombFunction. + + + + +```julia +golomb(n, L=n²) +``` + + +Model the Golomb problem of `n` marks on the ruler `0:L`. The `modeler` argument accepts :raw, and :JuMP (default), which refer respectively to the solver internal model, the MathOptInterface model, and the JuMP model. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/golomb.jl#L53-L57) + +
+
+
+# ConstraintModels.magic_squareMethod. + + + + +```julia +magic_square(n; modeler = :JuMP) +``` + + +Create a model for the magic square problem of order `n`. The `modeler` argument accepts :JuMP (default), which refer to the solver the JuMP model. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/magic_square.jl#L19-L23) + +
+
+
+# ConstraintModels.mincutMethod. + + + + +```julia +mincut(graph; source, sink, interdiction =0, modeler = :JuMP) +``` + + +Compute the minimum cut of a graph. + +**Arguments:** +- `graph`: Any matrix <: AbstractMatrix that describes the capacities of the graph + +- `source`: Id of the source node; must be set + +- `sink`: Id of the sink node; must be set + +- `interdiction`: indicates the number of forbidden links + +- `modeler`: Default to `:JuMP`. + + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/cut.jl#L47-L58) + +
+
+
+# ConstraintModels.n_queensMethod. + + + + +```julia +n_queens(n; modeler = :JuMP) +``` + + +Create a model for the n-queens problem with `n` queens. The `modeler` argument accepts :JuMP (default), which refer to the JuMP model. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/n_queens.jl#L16-L20) + +
+
+
+# ConstraintModels.qapMethod. + + + + +```julia +qap(n, weigths, distances; modeler = :JuMP) +``` + + +Modelize an instance of the Quadractic Assignment Problem with +- `n`: number of both facilities and locations + +- `weights`: `Matrix` of the weights of each pair of facilities + +- `distances`: `Matrix` of distances between locations + +- `modeler`: Default to `:JuMP`. No other modeler available for now. + + +**From Wikipedia** + +There are a set of `n` facilities and a set of `n` locations. For each pair of locations, a distance is specified and for each pair of facilities a `weight` or flow is specified (e.g., the amount of supplies transported between the two facilities). The problem is to assign all facilities to different locations with the goal of minimizing the sum of the `distances` multiplied by the corresponding flows. + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/assignment.jl#L14-L25) + +
+
+
+# ConstraintModels.schedulingMethod. + + + + +```julia +scheduling(processing_time, due_date; modeler=:JuMP) +``` + + +Create a model for the n-queens problem with `n` queens. The `modeler` argument accepts :JuMP (default), which refer to the JuMP model. + +::: warning Warning + +The model seems to have a flaw. Needs to be investigated. + +::: + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/scheduling.jl#L46-L55) + +
+
+
+# ConstraintModels.sudokuMethod. + + + + +```julia +sudoku(n; start= Dictionary{Int, Int}(), modeler = :JuMP) +``` + + +Create a model for the sudoku problem of domain `1:n²` with optional starting values. The `modeler` argument accepts :raw, :MOI, and :JuMP (default), which refer respectively to the solver internal model, the MathOptInterface model, and the JuMP model. + +```julia +# Construct a JuMP model `m` and its associated matrix `grid` for sudoku 9×9 +m, grid = sudoku(3) + +# Same with a starting instance +instance = [ + 9 3 0 0 0 0 0 4 0 + 0 0 0 0 4 2 0 9 0 + 8 0 0 1 9 6 7 0 0 + 0 0 0 4 7 0 0 0 0 + 0 2 0 0 0 0 0 6 0 + 0 0 0 0 2 3 0 0 0 + 0 0 8 5 3 1 0 0 2 + 0 9 0 2 8 0 0 0 0 + 0 7 0 0 0 0 0 5 3 +] +m, grid = sudoku(3, start = instance) + +# Run the solver +optimize!(m) + +# Retrieve and display the values +solution = value.(grid) +display(solution, Val(:sudoku)) +``` + + + +[source](https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L92-L121) + +
+
diff --git a/dev/.documenter/constraints/constraints.md b/dev/.documenter/constraints/constraints.md new file mode 100644 index 0000000..0d876f8 --- /dev/null +++ b/dev/.documenter/constraints/constraints.md @@ -0,0 +1,528 @@ + +# Constraints.jl: Streamlining Constraint Definition and Integration in Julia {#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia} + + + +_Constraints.jl_ is a pivotal package within the JuliaConstraints ecosystem, designed to facilitate the definition, manipulation, and application of constraints in constraint programming (CP). This package is central to handling both standard and complex constraints, making it an indispensable tool for developers and researchers working in CP. + +## Key Features and Functionalities {#Key-Features-and-Functionalities} +- **Integration of XCSP3-core Constraints**: One of the standout features of Constraints.jl is its incorporation of the XCSP3-core constraints as usual constraints within Julia. This integration ensures that users can define and work with a wide range of standard constraints, following the specifications outlined in the XCSP3-core, directly in Julia. The use of `USUAL_CONSTRAINTS` dictionary allows for straightforward addition and manipulation of these constraints, enhancing the package's utility and flexibility. + +- **Learning Package Integration**: Constraints.jl goes beyond traditional constraint handling by offering the capability to include results from various learning packages within the JuliaConstraints organization. This feature allows for the enhancement of usual constraints and those from the Global Constraints Catalog with learned parameters and behaviors, significantly improving constraint applicability and performance in complex CP problems. + +- **Constraint Definition and Symmetry Handling**: The package provides a simple yet powerful syntax for defining new constraints (`@usual`) and managing their symmetries through the `USUAL_SYMMETRIES` dictionary. This approach simplifies the creation of new constraints and the optimization of constraint search spaces by avoiding redundant explorations. + +- **Advanced Constraint Functionalities**: At the core of Constraints.jl is the `Constraint` type, encapsulating the essential elements of a constraint, including its concept (a Boolean function determining satisfaction) and an error function (providing a preference measure over invalid assignments). These components are crucial for defining how constraints behave and are evaluated within a CP model. + +- **Flexible Constraint Application**: The package supports a range of methods for interacting with constraints, such as `args`, `concept`, `error_f`, `params_length`, `symmetries`, and `xcsp_intension`. These methods offer users the ability to examine constraint properties, apply constraints to variable assignments, and work with intensional constraints defined by predicates. Such flexibility is vital for tailoring constraint behavior to specific problems and contexts. + + +## Enabling Advanced Modeling in Constraint Programming {#Enabling-Advanced-Modeling-in-Constraint-Programming} + +Constraints.jl embodies the JuliaConstraints ecosystem's commitment to providing robust, flexible tools for constraint programming. By integrating standard constraints, facilitating the incorporation of learned behaviors, and offering comprehensive tools for constraint definition and application, Constraints.jl significantly enhances the modeling capabilities available to CP practitioners. Whether for educational purposes, research, or solving practical CP problems, Constraints.jl offers a sophisticated, user-friendly platform for working with constraints in Julia. + +## Basic tools {#Basic-tools} +
+# Constraints.USUAL_SYMMETRIESConstant. + + + + +```julia +USUAL_SYMMETRIES +``` + + +A Dictionary that contains the function to apply for each symmetry to avoid searching a whole space. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L1-L4) + +
+
+
+# Constraints.ConstraintType. + + + + +```julia +Constraint +``` + + +Parametric structure with the following fields. +- `concept`: a Boolean function that, given an assignment `x`, outputs `true` if `x` satisfies the constraint, and `false` otherwise. + +- `error`: a positive function that works as preferences over invalid assignments. Return `0.0` if the constraint is satisfied, and a strictly positive real otherwise. + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L7-L12) + +
+
+
+# Constraints.conceptFunction. + + + + +```julia +concept(c::Constraint) +``` + + +Return the concept (function) of constraint `c`. concept(c::Constraint, x...; param = nothing) Apply the concept of `c` to values `x` and optionally `param`. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L40-L45) + + + +```julia +concept(s::Symbol, args...; kargs...) +``` + + +Return the concept of the constraint `s` applied to `args` and `kargs`. This is a shortcut for `concept(USUAL_CONSTRAINTS[s])(args...; kargs...)`. + +**Arguments** +- `s::Symbol`: the constraint name. + +- `args...`: the arguments to apply the concept to. + +- `kargs...`: the keyword arguments to apply the concept to. + + +**Example** + +```julia +concept(:all_different, [1, 2, 3]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L221-L235) + +
+
+
+# Constraints.error_fFunction. + + + + +```julia +error_f(c::Constraint) +``` + + +Return the error function of constraint `c`. error_f(c::Constraint, x; param = nothing) Apply the error function of `c` to values `x` and optionally `param`. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L51-L56) + +
+
+
+# Constraints.argsFunction. + + + + +```julia +args(c::Constraint) +``` + + +Return the expected length restriction of the arguments in a constraint `c`. The value `nothing` indicates that any strictly positive number of value is accepted. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L62-L65) + +
+
+
+# Constraints.params_lengthFunction. + + + + +```julia +params_length(c::Constraint) +``` + + +Return the expected length restriction of the arguments in a constraint `c`. The value `nothing` indicates that any strictly positive number of parameters is accepted. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L68-L71) + +
+
+
+# Constraints.symmetriesFunction. + + + + +```julia +symmetries(c::Constraint) +``` + + +Return the list of symmetries of `c`. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L74-L77) + +
+
+
+# Constraints.make_errorFunction. + + + + +```julia +make_error(symb::Symbol) +``` + + +Create a function that returns an error based on the predicate of the constraint identified by the symbol provided. + +**Arguments** +- `symb::Symbol`: The symbol used to determine the error function to be returned. The function first checks if a predicate with the prefix "icn_" exists in the Constraints module. If it does, it returns that function. If it doesn't, it checks for a predicate with the prefix "error_". If that exists, it returns that function. If neither exists, it returns a function that evaluates the predicate with the prefix "concept_" and returns the negation of its result cast to Float64. + + +**Returns** +- Function: A function that takes in a variable `x` and an arbitrary number of parameters `params`. The function returns a Float64. + + +**Examples** + +```julia +e = make_error(:all_different) +e([1, 2, 3]) # Returns 0.0 +e([1, 1, 3]) # Returns 1.0 +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L80-L97) + +
+
+
+# Constraints.shrink_conceptFunction. + + + + +```julia +shrink_concept(s) +``` + + +Simply delete the `concept_` part of symbol or string starting with it. TODO: add a check with a warning if `s` starts with something different. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L104-L108) + +
+
+
+# Constraints.concept_vs_errorFunction. + + + + +```julia +concept_vs_error(c, e, args...; kargs...) +``` + + +Compare the results of a concept function and an error function for the same inputs. It is mainly used for testing purposes. + +**Arguments** +- `c`: The concept function. + +- `e`: The error function. + +- `args...`: Positional arguments to be passed to both the concept and error functions. + +- `kargs...`: Keyword arguments to be passed to both the concept and error functions. + + +**Returns** +- Boolean: Returns true if the result of the concept function is not equal to whether the result of the error function is greater than 0.0. Otherwise, it returns false. + + +**Examples** + +```julia +concept_vs_error(all_different, make_error(:all_different), [1, 2, 3]) # Returns false +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L111-L129) + +
+
+ +## Usual constraints (based on and including XCSP3-core categories) {#Usual-constraints-(based-on-and-including-XCSP3-core-categories)} +
+# Constraints.USUAL_CONSTRAINTSConstant. + + + + +```julia +USUAL_CONSTRAINTS::Dict +``` + + +Dictionary that contains all the usual constraints defined in Constraint.jl. It is based on XCSP3-core specifications available at https://arxiv.org/abs/2009.00514 + +Adding a new constraint is as simple as defining a new function with the same name as the constraint and using the `@usual` macro to define it. The macro will take care of adding the new constraint to the `USUAL_CONSTRAINTS` dictionary. + +**Example** + +```julia +@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L1-L11) + +
+
+
+# Constraints.describeFunction. + + + + +```julia +describe(constraints::Dict{Symbol,Constraint}=USUAL_CONSTRAINTS; width=150) +``` + + +Return a pretty table with the description of the constraints in `constraints`. + +**Arguments** +- `constraints::Dict{Symbol,Constraint}`: dictionary of constraints to describe. Default is `USUAL_CONSTRAINTS`. + +- `width::Int`: width of the table. + + +**Example** + +```julia +describe() +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L14-L27) + +
+
+
+# ConstraintCommons.extract_parametersFunction. + + + + +```julia +extract_parameters(m::Union{Method, Function}; parameters) +``` + + +Extracts the intersection between the `kargs` of `m` and `parameters` (defaults to `USUAL_CONSTRAINT_PARAMETERS`). + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/parameters.jl#L21-L25) + + + +```julia +extract_parameters(s::Symbol, constraints_dict=USUAL_CONSTRAINTS; parameters=ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS) +``` + + +Return the parameters of the constraint `s` in `constraints_dict`. + +**Arguments** +- `s::Symbol`: the constraint name. + +- `constraints_dict::Dict{Symbol,Constraint}`: dictionary of constraints. Default is `USUAL_CONSTRAINTS`. + +- `parameters::Vector{Symbol}`: vector of parameters. Default is `ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS`. + + +**Example** + +```julia +extract_parameters(:all_different) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L44-L58) + +
+
+
+# Constraints.@usualMacro. + + + + +```julia +usual(ex::Expr) +``` + + +This macro is used to define a new constraint or update an existing one in the USUAL_CONSTRAINTS dictionary. It takes an expression ex as input, which represents the definition of a constraint. + +Here's a step-by-step explanation of what the macro does: +1. It first extracts the symbol of the concept from the input expression. This symbol is expected to be the first argument of the first argument of the expression. For example, if the expression is @usual all_different(x; y=1), the symbol would be :all_different. + +2. It then calls the shrink_concept function on the symbol to get a simplified version of the concept symbol. + +3. It initializes a dictionary defaults to store whether each keyword argument of the concept has a default value or not. + +4. It checks if the expression has more than two arguments. If it does, it means that there are keyword arguments present. It then loops over these keyword arguments. If a keyword argument is a symbol, it means it doesn't have a default value, so it adds an entry to the defaults dictionary with the keyword argument as the key and false as the value. If a keyword argument is not a symbol, it means it has a default value, so it adds an entry to the defaults dictionary with the keyword argument as the key and true as the value. + +5. It calls the make_error function on the simplified concept symbol to generate an error function for the constraint. + +6. It evaluates the input expression to get the concept function. + +7. It checks if the USUAL_CONSTRAINTS dictionary already contains an entry for the simplified concept symbol. If it does, it adds the defaults dictionary to the parameters of the existing constraint. If it doesn't, it creates a new constraint with the concept function, a description, the error function, and the defaults dictionary as the parameters, and adds it to the USUAL_CONSTRAINTS dictionary. + + +This macro is used to make it easier to define and update constraints in a consistent and possibly automated way. + +**Arguments** +- `ex::Expr`: expression to parse. + + +**Example** + +```julia +@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L67-L90) + +
+
+
+# Constraints.constraints_parametersFunction. + + + + +```julia +constraints_parameters(C=USUAL_CONSTRAINTS) +``` + + +Return a pretty table with the parameters of the constraints in `C`. + +**Arguments** +- `C::Dict{Symbol,Constraint}`: dictionary of constraints. Default is `USUAL_CONSTRAINTS`. + + +**Example** + +```julia +constraints_parameters() +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L127-L139) + +
+
+
+# Constraints.constraints_descriptionsFunction. + + + + +```julia +constraints_descriptions(C=USUAL_CONSTRAINTS) +``` + + +Return a pretty table with the descriptions of the constraints in `C`. + +**Arguments** +- `C::Dict{Symbol,Constraint}`: dictionary of constraints. Default is `USUAL_CONSTRAINTS`. + + +**Example** + +```julia +constraints_descriptions() +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L180-L192) + +
+
+
+# Constraints.conceptFunction. + + + + +```julia +concept(c::Constraint) +``` + + +Return the concept (function) of constraint `c`. concept(c::Constraint, x...; param = nothing) Apply the concept of `c` to values `x` and optionally `param`. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L40-L45) + + + +```julia +concept(s::Symbol, args...; kargs...) +``` + + +Return the concept of the constraint `s` applied to `args` and `kargs`. This is a shortcut for `concept(USUAL_CONSTRAINTS[s])(args...; kargs...)`. + +**Arguments** +- `s::Symbol`: the constraint name. + +- `args...`: the arguments to apply the concept to. + +- `kargs...`: the keyword arguments to apply the concept to. + + +**Example** + +```julia +concept(:all_different, [1, 2, 3]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L221-L235) + +
+
diff --git a/dev/.documenter/constraints/counting_summing_constraints.md b/dev/.documenter/constraints/counting_summing_constraints.md new file mode 100644 index 0000000..0c48299 --- /dev/null +++ b/dev/.documenter/constraints/counting_summing_constraints.md @@ -0,0 +1,249 @@ + +# Constraints.jl: Streamlining Constraint Definition and Integration in Julia {#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia} + + + +### Counting and Summing Constraints {#Counting-and-Summing-Constraints} +
+# Constraints.xcsp_sumFunction. + + + + +```julia +xcsp_sum(list, coeffs, condition) +``` + + +Return `true` if the sum of the variables in `list` satisfies the given condition, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `coeffs::Vector{Int}`: list of coefficients to use. + +- `condition`: condition to satisfy. + + +**Variants** +- `:sum`: Global constraint ensuring that the sum of the variables in `x` satisfies a given condition. + + +```julia +concept(:sum, x; op===, pair_vars=ones(x), val) +concept(:sum)(x; op===, pair_vars=ones(x), val) +``` + + +**Examples** + +```julia +c = concept(:sum) + +c([1, 2, 3, 4, 5]; op===, val=15) +c([1, 2, 3, 4, 5]; op===, val=2) +c([1, 2, 3, 4, 3]; op=≤, val=15) +c([1, 2, 3, 4, 3]; op=≤, val=3) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/sum.jl#L5-L31) + +
+
+
+# Constraints.xcsp_countFunction. + + + + +```julia +xcsp_count(list, values, condition) +``` + + +Return `true` if the number of occurrences of the values in `values` in `list` satisfies the given condition, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `values::Vector{Int}`: list of values to check. + +- `condition`: condition to satisfy. + + +**Variants** +- `:count`: Constraint ensuring that the number of occurrences of the values in `vals` in `x` satisfies the given condition. + + +```julia +concept(:count, x; vals, op, val) +concept(:count)(x; vals, op, val) +``` + +- `:at_least`: Constraint ensuring that the number of occurrences of the values in `vals` in `x` is at least `val`. + + +```julia +concept(:at_least, x; vals, val) +concept(:at_least)(x; vals, val) +``` + +- `:at_most`: Constraint ensuring that the number of occurrences of the values in `vals` in `x` is at most `val`. + + +```julia +concept(:at_most, x; vals, val) +concept(:at_most)(x; vals, val) +``` + +- `:exactly`: Constraint ensuring that the number of occurrences of the values in `vals` in `x` is exactly `val`. + + +```julia +concept(:exactly, x; vals, val) +concept(:exactly)(x; vals, val) +``` + + +**Examples** + +```julia +c = concept(:count) + +c([2, 1, 4, 3]; vals=[1, 2, 3, 4], op=≥, val=2) +c([1, 2, 3, 4]; vals=[1, 2], op==, val=2) +c([2, 1, 4, 3]; vals=[1, 2], op=≤, val=1) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/count.jl#L17-L57) + +
+
+
+# Constraints.xcsp_nvaluesFunction. + + + + +```julia +xcsp_nvalues(list, condition, except) +``` + + +Return `true` if the number of distinct values in `list` satisfies the given condition, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `condition`: condition to satisfy. + +- `except::Union{Nothing, Vector{Int}}`: list of values to exclude. Default is `nothing`. + + +**Variants** +- `:nvalues`: The nValues constraint specifies that the number of distinct values in the list of variables x is equal to a given value. The constraint is defined by the following expression: nValues(x, op, val) where x is a list of variables, op is a comparison operator, and val is an integer value. + + +```julia +concept(:nvalues, x; op, val) +concept(:nvalues)(x; op, val) +``` + + +**Examples** + +```julia +c = concept(:nvalues) + +c([1, 2, 3, 4, 5]; op = ==, val = 5) +c([1, 2, 3, 4, 5]; op = ==, val = 2) +c([1, 2, 3, 4, 3]; op = <=, val = 5) +c([1, 2, 3, 4, 3]; op = <=, val = 3) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/n_values.jl#L7-L33) + +
+
+
+# Constraints.xcsp_cardinalityFunction. + + + + +```julia +xcsp_cardinality(list, values, occurs, closed) +``` + + +Return `true` if the number of occurrences of the values in `values` in `list` satisfies the given condition, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `values::Vector{Int}`: list of values to check. + +- `occurs::Vector{Int}`: list of occurrences to check. + +- `closed::Bool`: whether the constraint is closed or not. + + +**Variants** +- `:cardinality`: The cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. + + +```julia +concept(:cardinality, x; bool=false, vals) +concept(:cardinality)(x; bool=false, vals) +``` + +- `:cardinality_closed`: The closed cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. It is closed, meaning that all values in the domain of the variables must be considered. + + +```julia +concept(:cardinality_closed, x; vals) +concept(:cardinality_closed)(x; vals) +``` + +- `:cardinality_open`: The open cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. It is open, meaning that only the values in the list of values must be considered. + + +```julia +concept(:cardinality_open, x; vals) +concept(:cardinality_open)(x; vals) +``` + + +**Examples** + +```julia +c = concept(:cardinality) + +c([2, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) +c([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=false) +c([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=true) +c([2, 5, 10, 10]; vals=[2 1; 5 1; 10 2]) +c([2, 5, 10, 10]; vals=[2 0 1 42; 5 1 3 7; 10 2 3 -4]) +c([2, 5, 5, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) +c([2, 5, 10, 8]; vals=[2 1; 5 1; 10 2]) +c([5, 5, 5, 10]; vals=[2 0 1 42; 5 1 3 7; 10 2 3 -4]) + +cc = concept(:cardinality_closed) +cc([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) + +co = concept(:cardinality_open) +co([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/cardinality.jl#L14-L61) + +
+
diff --git a/dev/.documenter/constraints/elementary_constraints.md b/dev/.documenter/constraints/elementary_constraints.md new file mode 100644 index 0000000..76f13e7 --- /dev/null +++ b/dev/.documenter/constraints/elementary_constraints.md @@ -0,0 +1,50 @@ + +# Constraints.jl: Streamlining Constraint Definition and Integration in Julia {#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia} + + + +### Elementary Constraints {#Elementary-Constraints} +
+# Constraints.xcsp_instantiationFunction. + + + + +```julia +xcsp_instantiation(; list, values) +``` + + +Return `true` if the instantiation constraint is satisfied, `false` otherwise. The instantiation constraint is a global constraint used in constraint programming that ensures that a list of variables takes on a specific set of values in a specific order. + +**Arguments** +- `list::AbstractVector`: list of values to check. + +- `values::AbstractVector`: list of values to check against. + + +**Variants** +- `:instantiation`: The instantiation constraint is a global constraint used in constraint programming that ensures that a list of variables takes on a specific set of values in a specific order. + + +```julia +concept(:instantiation, x; pair_vars) +concept(:instantiation)(x; pair_vars) +``` + + +**Examples** + +```julia +c = concept(:instantiation) + +c([1, 2, 3, 4, 5]; pair_vars=[1, 2, 3, 4, 5]) +c([1, 2, 3, 4, 5]; pair_vars=[1, 2, 3, 4, 6]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/instantiation.jl#L5-L28) + +
+
diff --git a/dev/.documenter/constraints/generic_constraints.md b/dev/.documenter/constraints/generic_constraints.md new file mode 100644 index 0000000..a63589e --- /dev/null +++ b/dev/.documenter/constraints/generic_constraints.md @@ -0,0 +1,244 @@ + +# Generic Constraints {#Generic-Constraints} + + + +In the [XCSP³-core](https://arxiv.org/abs/2009.00514) standard, generic constraints are categorized into two main types: _intention_ and _extension_ constraints. + +## Intention Constraints {#Intention-Constraints} + +These are constraints that are defined by a logical expression or a function. They are called intentional because they are defined by the property they satisfy. For example, a constraint that specifies that a variable $x$ must be less than a variable $y$ could be defined intentionally as $x < y$. + +Note that the _intention_ constraint is not directly available through the JC-API in Constraints.jl. It is designed as such since defining a constraint through a _predicate_ is the natural way. + +We provide a straightforward example through the `:dist_different` constraint on how to define and add such a constraint in the `USUAL_CONSTRAINTS` collection. + +Higher level modeling language such as `JuMP` should provide a `Intention` interface. + +### Defining an intention constraint in JC-API {#Defining-an-intention-constraint-in-JC-API} + +We use the `dist_different` constraint to illustrate how to define an intention constraint in _Constraints.jl_. The `dist_different` constraint ensures that the distances between marks $x$ on a ruler are unique. + +$$|x[1] - x[2]| \ne |x[3] - x[4]|$$ + +The constraint is then added to the usual constraints collection. + +```julia +const description_dist_different = """ +Ensures that the distances between marks on the ruler are unique. +""" + +# Define the predicate +predicate_dist_different(x) = abs(x[1] - x[2]) ≠ abs(x[3] - x[4]) + +# Add it to usual constraints +@usual concept_dist_different(x) = xcsp_intension( + list = x, + predicate = predicate_dist_different +) +``` + + +Please check the section dedicated to the Golomb Ruler problem to see a use for this constraint. <!– TODO: Golomb Ruler –> + +### APIs + +Note that the _intension_ constraint is not directly available through the JC-API in Constraints.jl. It is designed as such since defining a constraint through a _predicate_ is the natural way. + +We provide here a usage example for the `:dist_different` constraint, previously added to the `USUAL_CONSTRAINTS` collection. + +Higher level modeling language such as `JuMP` should provide an `Intension` interface. + +::: code-group + +```julia [JC-API] +concept(:dist_different, x) +concept(:dist_different)(x) +``` + + +```julia [XCSP] +# Defines the DistDifferent constraint +c = x -> xcsp_intension( + list = x, + predicate = y -> abs(y[1] - y[2]) ≠ abs(y[3] - y[4]) +) + +c([1, 2, 3, 3]) # true +c([1, 2, 3, 4]) # false +``` + + +```julia [JuMP] +# TODO: How to handle intention in JuMP/MOI +``` + + +```julia [MOI] +# TODO: How to handle intention in JuMP/MOI +``` + + +::: + +### Test for DocumenterVitePress Issue {#Test-for-DocumenterVitePress-Issue} + +```julia +c = concept(:dist_different) +c([1, 2, 3, 3]) && !c([1, 2, 3, 4]) +``` + + +``` +true +``` + + +```julia +c = concept(:dist_different) +c([1, 2, 3, 3]) && !c([1, 2, 3, 4]) +``` + + +``` +true +``` + + +### Specific documentation {#Specific-documentation} +
+# Constraints.xcsp_intensionFunction. + + + + +```julia +xcsp_intension(list, predicate) +``` + + +An intensional constraint is usually defined from a `predicate` over `list`. As such it encompass any generic constraint. + +**Arguments** +- `list::Vector{Int}`: A list of variables + +- `predicate::Function`: A predicate over `list` + + +**Variants** +- `:dist_different`: A constraint ensuring that the distances between marks on the ruler are unique. Specifically, it checks that the distance between `x[1]` and `x[2]`, and the distance between `x[3]` and `x[4]`, are different. This constraint is fundamental in ensuring the validity of a Golomb ruler, where no two pairs of marks should have the same distance between them. + + +```julia +concept(:dist_different, x) +concept(:dist_different)(x) +``` + + +**Examples** + +```@example debug2 +2 + 2 +``` + + +```@example debug1 +2 + 2 +``` + + +```@example intention1 +using Constraints # hide +c = concept(:dist_different) +c([1, 2, 3, 3]) && !c([1, 2, 3, 4]) +``` + + +```@example intention2 +using Constraints # hide +c = concept(:dist_different) +c([1, 2, 3, 3]) && !c([1, 2, 3, 4]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/intention.jl#L9-L47) + +
+
+ +## Extension Constraints {#Extension-Constraints} + +These are constraints that are defined by explicitly listing all the tuples of values that satisfy the constraint. They are called extensional because they are defined by the set of values they allow. For example, a binary constraint that specifies that a variable X must be either 1 or 2 and a variable Y must be either 3 or 4 could be defined extensionally by the set of tuples {(1,3), (1,4), (2,3), (2,4)}. + +These two types of constraints provide a flexible way to define complex relationships between variables in constraint programming. + +### [XCSP](https://arxiv.org/abs/2009.00514) in Constraints.jl {#[XCSP](https://arxiv.org/abs/2009.00514)-in-Constraints.jl} +
+# Constraints.xcsp_extensionFunction. + + + + +```julia +xcsp_extension(; list, supports=nothing, conflicts=nothing) +``` + + +Global constraint enforcing that the tuple `x` matches a configuration within the supports set `pair_vars[1]` or does not match any configuration within the conflicts set `pair_vars[2]`. It embodies the logic: `x ∈ pair_vars[1] || x ∉ pair_vars[2]`, providing a comprehensive way to define valid (supported) and invalid (conflicted) tuples for constraint satisfaction problems. This constraint is versatile, allowing for the explicit delineation of both acceptable and unacceptable configurations. + +**Arguments** +- `list::Vector{Int}`: A list of variables + +- `supports::Vector{Vector{Int}}`: A set of supported tuples. Default to nothing. + +- `conflicts::Vector{Vector{Int}}`: A set of conflicted tuples. Default to nothing. + + +**Variants** +- `:extension`: Global constraint enforcing that the tuple `x` matches a configuration within the supports set `pair_vars[1]` or does not match any configuration within the conflicts set `pair_vars[2]`. It embodies the logic: `x ∈ pair_vars[1] || x ∉ pair_vars[2]`, providing a comprehensive way to define valid (supported) and invalid (conflicted) tuples for constraint satisfaction problems. This constraint is versatile, allowing for the explicit delineation of both acceptable and unacceptable configurations. + + +```julia +concept(:extension, x; pair_vars) +concept(:extension)(x; pair_vars) +``` + +- `:supports`: Global constraint ensuring that the tuple `x` matches a configuration listed within the support set `pair_vars`. This constraint is derived from the extension model, specifying that `x` must be one of the explicitly defined supported configurations: `x ∈ pair_vars`. It is utilized to directly declare the tuples that are valid and should be included in the solution space. + + +```julia +concept(:supports, x; pair_vars) +concept(:supports)(x; pair_vars) +``` + +- `:conflicts`: Global constraint ensuring that the tuple `x` does not match any configuration listed within the conflict set `pair_vars`. This constraint, originating from the extension model, stipulates that `x` must avoid all configurations defined as conflicts: `x ∉ pair_vars`. It is useful for specifying tuples that are explicitly forbidden and should be excluded from the solution space. + + +```julia +concept(:conflicts, x; pair_vars) +concept(:conflicts)(x; pair_vars) +``` + + +**Examples** + +```julia +c = concept(:extension) +c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 3, 4, 5]]) +c([1, 2, 3, 4, 5]; pair_vars=([[1, 2, 3, 4, 5]], [[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]])) +c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]]) + +c = concept(:supports) +c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 3, 4, 5]]) + +c = concept(:conflicts) +c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/extension.jl#L20-L60) + +
+
diff --git a/dev/.documenter/constraints/graph_constraints.md b/dev/.documenter/constraints/graph_constraints.md new file mode 100644 index 0000000..76b1459 --- /dev/null +++ b/dev/.documenter/constraints/graph_constraints.md @@ -0,0 +1,52 @@ + +# Constraints.jl: Streamlining Constraint Definition and Integration in Julia {#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia} + + + +### Constraints on Graphs {#Constraints-on-Graphs} +
+# Constraints.xcsp_circuitFunction. + + + + +```julia +xcsp_circuit(; list, size) +``` + + +Return `true` if the circuit constraint is satisfied, `false` otherwise. The circuit constraint is a global constraint used in constraint programming, often in routing problems. It ensures that the values of a list of variables form a circuit, i.e., a sequence where each value is the index of the next value in the sequence, and the sequence eventually loops back to the start. + +**Arguments** +- `list::AbstractVector`: list of values to check. + +- `size::Int`: size of the circuit. + + +**Variants** +- `:circuit`: The circuit constraint is a global constraint used in constraint programming, often in routing problems. It ensures that the values of a list of variables form a circuit, i.e., a sequence where each value is the index of the next value in the sequence, and the sequence eventually loops back to the start. + + +```julia +concept(:circuit, x; op, val) +concept(:circuit)(x; op, val) +``` + + +**Examples** + +```julia +c = concept(:circuit) + +c([1, 2, 3, 4]) +c([2, 3, 4, 1]) +c([2, 3, 1, 4]; op = ==, val = 3) +c([4, 3, 1, 3]; op = >, val = 0) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/circuit.jl#L5-L30) + +
+
diff --git a/dev/.documenter/constraints/intro.md b/dev/.documenter/constraints/intro.md new file mode 100644 index 0000000..57244b0 --- /dev/null +++ b/dev/.documenter/constraints/intro.md @@ -0,0 +1,4 @@ + +# Introduction to basics cosntraints related tools {#Introduction-to-basics-cosntraints-related-tools} + +About constraints. diff --git a/dev/.documenter/constraints/language_constraints.md b/dev/.documenter/constraints/language_constraints.md new file mode 100644 index 0000000..9206bc3 --- /dev/null +++ b/dev/.documenter/constraints/language_constraints.md @@ -0,0 +1,132 @@ + +# Constraints.jl: Streamlining Constraint Definition and Integration in Julia {#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia} + + + +### Constraints defined from Languages {#Constraints-defined-from-Languages} +
+# Constraints.xcsp_regularFunction. + + + + +```julia +xcsp_regular(; list, automaton) + +Ensures that a sequence `x` (interpreted as a word) is accepted by the regular language represented by a given automaton. This constraint verifies the compliance of `x` with the language rules encoded within the `automaton` parameter, which must be an instance of `<:AbstractAutomaton`. +``` + + +**Arguments** +- `list::Vector{Int}`: A list of variables + +- `automaton<:AbstractAutomaton`: An automaton representing the regular language + + +**Variants** +- `:regular`: Ensures that a sequence `x` (interpreted as a word) is accepted by the regular language represented by a given automaton. This constraint verifies the compliance of `x` with the language rules encoded within the `automaton` parameter, which must be an instance of `<:AbstractAutomaton`. + + +```julia +concept(:regular, x; language) +concept(:regular)(x; language) +``` + + +**Examples** + +```julia +c = concept(:regular) + +states = Dict( + (:a, 0) => :a, + (:a, 1) => :b, + (:b, 1) => :c, + (:c, 0) => :d, + (:d, 0) => :d, + (:d, 1) => :e, + (:e, 0) => :e, +) +start = :a +finish = :e + +a = Automaton(states, start, finish) + +c([0,0,1,1,0,0,1,0,0]; language = a) +c([1,1,1,0,1]; language = a) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/regular.jl#L5-L42) + +
+
+
+# Constraints.xcsp_mddFunction. + + + + +```julia +xcsp_mdd(; list, diagram) +``` + + +Return a function that checks if the list of values `list` satisfies the MDD `diagram`. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `diagram::MDD`: MDD to check. + + +**Variants** +- `:mdd`: Multi-valued Decision Diagram (MDD) constraint. + The MDD constraint is a constraint that can be used to model a wide range of problems. It is a directed graph where each node is labeled with a value and each edge is labeled with a value. The constraint is satisfied if there is a path from the first node to the last node such that the sequence of edge labels is a valid sequence of the value labels. + + +```julia +concept(:mdd, x; language) +concept(:mdd)(x; language) +``` + + +**Examples** + +```julia +c = concept(:mdd) + +states = [ + Dict( # level x1 + (:r, 0) => :n1, + (:r, 1) => :n2, + (:r, 2) => :n3, + ), + Dict( # level x2 + (:n1, 2) => :n4, + (:n2, 2) => :n4, + (:n3, 0) => :n5, + ), + Dict( # level x3 + (:n4, 0) => :t, + (:n5, 0) => :t, + ), +] + +a = MDD(states) + +c([0,2,0]; language = a) +c([1,2,0]; language = a) +c([2,0,0]; language = a) +c([2,1,2]; language = a) +c([1,0,2]; language = a) +c([0,1,2]; language = a) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/mdd.jl#L9-L55) + +
+
diff --git a/dev/.documenter/constraints/packing_scheduling_constraints.md b/dev/.documenter/constraints/packing_scheduling_constraints.md new file mode 100644 index 0000000..abd9669 --- /dev/null +++ b/dev/.documenter/constraints/packing_scheduling_constraints.md @@ -0,0 +1,123 @@ + +# Constraints.jl: Streamlining Constraint Definition and Integration in Julia {#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia} + + + +### Packing and Scheduling Constraints {#Packing-and-Scheduling-Constraints} +
+# Constraints.xcsp_cumulativeFunction. + + + + +```julia +xcsp_cumulative(; origins, lengths, heights, condition) +``` + + +Return `true` if the cumulative constraint is satisfied, `false` otherwise. The cumulative constraint is a global constraint used in constraint programming that is often used in scheduling problems. It ensures that for any point in time, the sum of the "heights" of tasks that are ongoing at that time does not exceed a certain limit. + +**Arguments** +- `origins::AbstractVector`: list of origins of the tasks. + +- `lengths::AbstractVector`: list of lengths of the tasks. + +- `heights::AbstractVector`: list of heights of the tasks. + +- `condition::Tuple`: condition to check. + + +**Variants** +- `:cumulative`: The cumulative constraint is a global constraint used in constraint programming that is often used in scheduling problems. It ensures that for any point in time, the sum of the "heights" of tasks that are ongoing at that time does not exceed a certain limit. + + +```julia +concept(:cumulative, x; pair_vars, op, val) +concept(:cumulative)(x; pair_vars, op, val) +``` + + +**Examples** + +```julia +c = concept(:cumulative) + +c([1, 2, 3, 4, 5]; val = 1) +c([1, 2, 2, 4, 5]; val = 1) +c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = ≤, val = 5) +c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/cumulative.jl#L5-L32) + +
+
+
+# Constraints.xcsp_no_overlapFunction. + + + + +```julia +xcsp_no_overlap(; origins, lengths, zero_ignored) +``` + + +Return `true` if the no_overlap constraint is satisfied, `false` otherwise. The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. + +**Arguments** +- `origins::AbstractVector`: list of origins of the tasks. + +- `lengths::AbstractVector`: list of lengths of the tasks. + +- `zero_ignored::Bool`: whether to ignore zero-length tasks. + + +**Variants** +- `:no_overlap`: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. + + +```julia +concept(:no_overlap, x; pair_vars, bool) +concept(:no_overlap)(x; pair_vars, bool) +``` + +- `:no_overlap_no_zero`: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant ignores zero-length tasks. + + +```julia +concept(:no_overlap_no_zero, x; pair_vars) +concept(:no_overlap_no_zero)(x; pair_vars) +``` + +- `:no_overlap_with_zero`: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant includes zero-length tasks. + + +```julia +concept(:no_overlap_with_zero, x; pair_vars) +concept(:no_overlap_with_zero)(x; pair_vars) +``` + + +**Examples** + +```julia +c = concept(:no_overlap) + +c([1, 2, 3, 4, 5]) +c([1, 2, 3, 4, 1]) +c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 1, 1]) +c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 3, 1]) +c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 3, 1, 1]) +c([1, 1, 1, 3, 5, 2, 7, 7, 5, 12, 8, 7]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3) +c([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/no_overlap.jl#L13-L52) + +
+
diff --git a/dev/.documenter/cp/advanced.md b/dev/.documenter/cp/advanced.md new file mode 100644 index 0000000..8eae20c --- /dev/null +++ b/dev/.documenter/cp/advanced.md @@ -0,0 +1,10 @@ + +# Advanced Constraint Programming Techniques {#Advanced-Constraint-Programming-Techniques} + +## Global Constraints and Their Uses {#Global-Constraints-and-Their-Uses} +- Dive deeper into global constraints and how they simplify complex problems. + + +## Search Strategies and Optimization {#Search-Strategies-and-Optimization} +- Discuss various search strategies and their impact on solving CP problems. + diff --git a/dev/.documenter/cp/applications.md b/dev/.documenter/cp/applications.md new file mode 100644 index 0000000..21c001b --- /dev/null +++ b/dev/.documenter/cp/applications.md @@ -0,0 +1,10 @@ + +# Applying Optimization Methods {#Applying-Optimization-Methods} + +## Case Studies and Real-World Applications {#Case-Studies-and-Real-World-Applications} +- Showcase studies where CP and optimization have been successfully applied. + + +## From Theory to Practice {#From-Theory-to-Practice} +- Guide readers through the process of formulating and solving an optimization problem from a real-world scenario. + diff --git a/dev/.documenter/cp/contribution.md b/dev/.documenter/cp/contribution.md new file mode 100644 index 0000000..f11f508 --- /dev/null +++ b/dev/.documenter/cp/contribution.md @@ -0,0 +1,10 @@ + +# Community and Contribution {#Community-and-Contribution} + +## Joining the JuliaConstraint Community {#Joining-the-JuliaConstraint-Community} +- Encourage readers to join the community, highlighting how they can contribute and collaborate. + + +## Future Directions {#Future-Directions} +- Share the vision for JuliaConstraint and upcoming projects or areas of research. + diff --git a/dev/.documenter/cp/cp101.md b/dev/.documenter/cp/cp101.md new file mode 100644 index 0000000..a8f15da --- /dev/null +++ b/dev/.documenter/cp/cp101.md @@ -0,0 +1,14 @@ + +# Constraint Programming 101 {#Constraint-Programming-101} + +## What is Constraint Programming? {#What-is-Constraint-Programming?} +- Define CP and its significance in solving combinatorial problems. + + +## Basic Concepts and Terminology {#Basic-Concepts-and-Terminology} +- Introduce key concepts such as constraints, domains, and variables. + + +## How CP differs from other optimization techniques {#How-CP-differs-from-other-optimization-techniques} +- Contrast with other methods like linear programming and metaheuristics. + diff --git a/dev/.documenter/cp/ecosystem.md b/dev/.documenter/cp/ecosystem.md new file mode 100644 index 0000000..a0cb216 --- /dev/null +++ b/dev/.documenter/cp/ecosystem.md @@ -0,0 +1,10 @@ + +# Exploring JuliaConstraint Packages {#Exploring-JuliaConstraint-Packages} + +## Package Overviews {#Package-Overviews} +- Introduce each package within the JuliaConstraint organization, its purpose, and primary features. + + +# Installation and Getting Started Guides {#Installation-and-Getting-Started-Guides} +- Provide step-by-step instructions for installing and getting started with each package. + diff --git a/dev/.documenter/cp/getting_started.md b/dev/.documenter/cp/getting_started.md new file mode 100644 index 0000000..e713381 --- /dev/null +++ b/dev/.documenter/cp/getting_started.md @@ -0,0 +1,141 @@ + +# Getting Started with Julia for CP and Optimization {#Getting-Started-with-Julia-for-CP-and-Optimization} + +## Why Julia? {#Why-Julia?} +- Discuss the advantages of Julia for computational science and optimization, highlighting its performance and ease of use. + + +## Setting Up Your Julia Environment {#Setting-Up-Your-Julia-Environment} + +We encourage users to install Julia through `juliaup`, a version manager for the Julia language. Please look at the official Julia language download page for further information. Once installed, Julia can be used through various editors (`Visual Studio Code`), notebooks (`Pluto.jl`), or command-line (`REPL`). + +Although a part of the CP solvers available within the Julia ecosystem have their own interface, we encourage users to use the JuMP modeling language if possible. + +Julia Constraints host several solvers(' interfaces). Due to its flexibility in modeling and solving, we will use LocalSearchSolvers.jl through its JuMP interface CBLS.jl as the basic example. Note that depending on the targeted instances, available hardware, and expectations, it is not necessarily the best choice. + +All along the documentation, we will try to provide syntax examples for different setup. + +::: code-group + +```julia [LocalSearchSolvers] +using LocalSearchSolvers +``` + + +```julia [CBLS] +using JuMP, CBLS +``` + + +```julia [TODO] +# TODO: Add other solvers +``` + + +::: + +## Your First Julia CP Model {#Your-First-Julia-CP-Model} + +We will start with a classic puzzle game and some of its not that simple variants: the Sudoku. + +(From Wikipedia) In classic Sudoku, the objective is to fill a 9 × 9 grid with digits so that each column, each row, and each of the nine 3 × 3 subgrids that compose the grid (also called "boxes", "blocks", or "regions") contains all of the digits from 1 to 9. The puzzle setter provides a partially completed grid, which for a well-posed puzzle has a single solution. + +Constraint Programming follows the _model-and-solve_ approach. We first need to model our Sudoku problem. + +::: code-group + +```julia [CBLS] +m = JuMP.Model(CBLS.Optimizer) +``` + + +```julia [TODO] +# TODO: Add other solvers +``` + + +::: + +But what are the basis of CP models? It is quite simple: +1. A collection $X = X_1, \cdots, X_n$ of variables with each an associated domain. + + +::: code-group + +```julia [CBLS] +@variable(m, 1 ≤ X[1:9, 1:9] ≤ 9, Int) +``` + + +```julia [TODO] +# TODO: Add other solvers +``` + + +::: +1. A collection of predicates (called constraints) $C = C_1, \cdots, C_n$ over (subsets of) $X$. + + +When modeling problems as CP, one might define and use their own predicates. However, a large collection of already defined constraints exists. One, if not the most, iconic global constraint is called AllDifferent. It ensures that all variables take distinct values. + +Sudoku puzzles can be defined using only this one constraint applied to different subsets of variables. + +::: code-group + +```julia [CBLS] +for i in 1:9 + @constraint(m, X[i,:] in AllDifferent()) # rows + @constraint(m, X[:,i] in AllDifferent()) # columns +end +``` + + +```julia [TODO] +# TODO: Add other solvers +``` + + +::: + +The last series of AllDifferent constraint is less straight forward. We need to ensure that each 3 × 3 subgrid (block) is filled with distinct values. + +::: code-group + +```julia [CBLS] +for i in 0:2, j in 0:2 # blocks + @constraint( + m, + vec(X[(3i+1):(3(i+1)), (3j+1):(3(j+1))]) in AllDifferent(), + ) +end +``` + + +```julia [TODO] +# TODO: Add other solvers +``` + + +::: + +We can now simply run our solver to look for a feasible solution. + +::: code-group + +```julia [CBLS] +optimize!(m) +``` + + +::: + +Note that this is heuristic solver, we might not get a feasible solution! Let's check it out. The value function print the value of a JuMP variable. We can cast it over a collection with the `value.` syntax. + +::: code-group + +```julia [CBLS] +value.(X) +``` + + +::: diff --git a/dev/.documenter/cp/intro.md b/dev/.documenter/cp/intro.md new file mode 100644 index 0000000..87348e1 --- /dev/null +++ b/dev/.documenter/cp/intro.md @@ -0,0 +1,4 @@ + +# Welcome to Julia Constraints {#Welcome-to-Julia-Constraints} + +An introductory post/chapter that provides an overview of the JuliaConstraint organization, its mission, and what readers can expect to learn from the content. Highlight the importance of Constraint Programming (CP) and optimization in solving real-world problems. diff --git a/dev/.documenter/cp/models.md b/dev/.documenter/cp/models.md new file mode 100644 index 0000000..5a5a707 --- /dev/null +++ b/dev/.documenter/cp/models.md @@ -0,0 +1,10 @@ + +# Building and Analyzing Models {#Building-and-Analyzing-Models} + +## Modeling Best Practices {#Modeling-Best-Practices} +- Share best practices and tips for building efficient CP and optimization models. + + +## Performance Analysis and Improvement {#Performance-Analysis-and-Improvement} +- Teach how to analyze and improve the performance of models. + diff --git a/dev/.documenter/cp/opt.md b/dev/.documenter/cp/opt.md new file mode 100644 index 0000000..5ad850c --- /dev/null +++ b/dev/.documenter/cp/opt.md @@ -0,0 +1,14 @@ + +# Dive into Optimization {#Dive-into-Optimization} + +## Understanding Optimization {#Understanding-Optimization} +- Explanation of optimization, types of optimization problems (e.g., linear, nonlinear, integer programming). + + +## Metaheuristics Overview {#Metaheuristics-Overview} +- Introduce concepts like Genetic Algorithms, Simulated Annealing, and Tabu Search. + + +## Mathematical Programming Basics {#Mathematical-Programming-Basics} +- Cover the fundamentals of mathematical programming and its role in optimization. + diff --git a/dev/.documenter/cp/tuto_xp.md b/dev/.documenter/cp/tuto_xp.md new file mode 100644 index 0000000..1a1f449 --- /dev/null +++ b/dev/.documenter/cp/tuto_xp.md @@ -0,0 +1,10 @@ + +# Tutorials and Experiments {#Tutorials-and-Experiments} + +## Hands-On Tutorials {#Hands-On-Tutorials} +- Provide step-by-step tutorials covering various topics and complexity levels. + + +## Experimental Analysis {#Experimental-Analysis} +- Discuss the importance of experimental analysis in CP and how to conduct meaningful experiments. + diff --git a/dev/.documenter/full_api.md b/dev/.documenter/full_api.md new file mode 100644 index 0000000..fdace88 --- /dev/null +++ b/dev/.documenter/full_api.md @@ -0,0 +1,4441 @@ + +# Full API {#Full-API} +
+# ConstraintCommons.USUAL_CONSTRAINT_PARAMETERSConstant. + + + + +```julia +const USUAL_CONSTRAINT_PARAMETERS +``` + + +List of usual constraints parameters (based on XCSP3-core constraints). + +```julia +const USUAL_CONSTRAINT_PARAMETERS = [ + :bool, + :dim, + :id, + :language, + :op, + :pair_vars, + :val, + :vals, +] +``` + + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/parameters.jl#L1-L17) + +
+
+
+# ConstraintCommons.AbstractAutomatonType. + + + + +```julia +AbstractAutomaton +``` + + +An abstract interface for automata used in Julia Constraints packages. Requirements: +- `accept(a<:AbstractAutomaton, word)`: return `true` if `a` accepts `word`. + + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/automata.jl#L1-L6) + +
+
+
+# ConstraintCommons.AbstractMultivaluedDecisionDiagramType. + + + + +```julia +AbstractMultivaluedDecisionDiagram +``` + + +An abstract interface for Multivalued Decision Diagrams (MDD) used in Julia Constraints packages. Requirements: +- `accept(a<:AbstractMultivaluedDecisionDiagram, word)`: return `true` if `a` accepts `word`. + + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/diagrams.jl#L1-L6) + +
+
+
+# ConstraintCommons.AutomatonType. + + + + +```julia +Automaton{S, T, F <: Union{S, Vector{S}, Set{S}}} <: AbstractAutomaton +``` + + +A minimal implementation of a deterministic automaton structure. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/automata.jl#L9-L13) + +
+
+
+# ConstraintCommons.MDDType. + + + + +```julia +MDD{S,T} <: AbstractMultivaluedDecisionDiagram +``` + + +A minimal implementation of a multivalued decision diagram structure. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/diagrams.jl#L9-L13) + +
+
+
+# ConstraintCommons.acceptMethod. + + + + +```julia +accept(a::Union{Automaton, MDD}, w) +``` + + +Return `true` if `a` accepts the word `w` and `false` otherwise. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/automata.jl#L29-L33) + +
+
+
+# ConstraintCommons.at_endMethod. + + + + +```julia +at_end(a::Automaton, s) +``` + + +Internal method used by `accept` with `Automaton`. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/automata.jl#L20-L24) + +
+
+
+# ConstraintCommons.consinMethod. + + + + +```julia +Base.in(::Any, ::Nothing) +``` + + +Extends `Base.in` (or `∈`) when the set is `nothing`. Returns `false`. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/nothing.jl#L1-L5) + +
+
+
+# ConstraintCommons.extract_parametersMethod. + + + + +```julia +extract_parameters(m::Union{Method, Function}; parameters) +``` + + +Extracts the intersection between the `kargs` of `m` and `parameters` (defaults to `USUAL_CONSTRAINT_PARAMETERS`). + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/parameters.jl#L21-L25) + +
+
+
+# ConstraintCommons.incsert!Function. + + + + +```julia +incsert!(d::Union{AbstractDict, AbstractDictionary}, ind, val = 1) +``` + + +Increase or insert a counter in a dictionary-based collection. The counter insertion defaults to `val = 1`. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/dictionaries.jl#L2-L6) + +
+
+
+# ConstraintCommons.oversampleMethod. + + + + +```julia +oversample(X, f) +``` + + +Oversample elements of `X` until the boolean function `f` has as many `true` and `false` configurations. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/sampling.jl#L1-L5) + +
+
+
+# ConstraintCommons.symconFunction. + + + + +```julia +Base.:*(s1::Symbol, s2::Symbol, connector::AbstractString="_") +``` + + +Extends `*` to `Symbol`s multiplication by connecting the symbols by an `_`. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/symbols.jl#L1-L5) + +
+
+
+# ConstraintCommons.δ_extremaMethod. + + + + +```julia +δ_extrema(X...) +``` + + +Compute both the difference between the maximum and the minimum of over all the collections of `X`. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/extrema.jl#L1-L4) + +
+
+
+# ConstraintDomains.AbstractDomainType. + + + + +```julia +AbstractDomain +``` + + +An abstract super type for any domain type. A domain type `D <: AbstractDomain` must implement the following methods to properly interface `AbstractDomain`. +- `Base.∈(val, ::D)` + +- `Base.rand(::D)` + +- `Base.length(::D)` that is the number of elements in a discrete domain, and the distance between bounds or similar for a continuous domain + + +Additionally, if the domain is used in a dynamic context, it can extend +- `add!(::D, args)` + +- `delete!(::D, args)` + + +where `args` depends on `D`'s structure + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L1-L11) + +
+
+
+# ConstraintDomains.BoolParameterDomainType. + + + + +```julia +BoolParameterDomain <: AbstractDomain +``` + + +A domain to store boolean values. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L1-L5) + +
+
+
+# ConstraintDomains.ContinuousDomainType. + + + + +```julia +ContinuousDomain{T <: Real} <: AbstractDomain +``` + + +An abstract supertype for all continuous domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L1-L4) + +
+
+
+# ConstraintDomains.DimParameterDomainType. + + + + +```julia +DimParameterDomain <: AbstractDomain +``` + + +A domain to store dimensions. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L10-L14) + +
+
+
+# ConstraintDomains.DiscreteDomainType. + + + + +```julia +DiscreteDomain{T <: Number} <: AbstractDomain +``` + + +An abstract supertype for discrete domains (set, range). + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L1-L4) + +
+
+
+# ConstraintDomains.EmptyDomainType. + + + + +```julia +EmptyDomain +``` + + +A struct to handle yet to be defined domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L14-L17) + +
+
+
+# ConstraintDomains.ExploreSettingsMethod. + + + + +```julia +ExploreSettings( + domains; + complete_search_limit = 10^6, + max_samplings = sum(domain_size, domains), + search = :flexible, + solutions_limit = floor(Int, sqrt(max_samplings)), +) +``` + + +Settings for the exploration of a search space composed by a collection of domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/explore.jl#L8-L18) + +
+
+
+# ConstraintDomains.FakeAutomatonType. + + + + +```julia +FakeAutomaton{T} <: ConstraintCommons.AbstractAutomaton +``` + + +A structure to generate pseudo automaton enough for parameter exploration. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L32-L36) + +
+
+
+# ConstraintDomains.IdParameterDomainType. + + + + +```julia +IdParameterDomain <: AbstractDomain +``` + + +A domain to store ids. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L21-L25) + +
+
+
+# ConstraintDomains.IntervalsType. + + + + +```julia +Intervals{T <: Real} <: ContinuousDomain{T} +``` + + +An encapsuler to store a vector of `PatternFolds.Interval`. Dynamic changes to `Intervals` are not handled yet. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L7-L10) + +
+
+
+# ConstraintDomains.LanguageParameterDomainType. + + + + +```julia +LanguageParameterDomain <: AbstractDomain +``` + + +A domain to store languages. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L62-L66) + +
+
+
+# ConstraintDomains.OpParameterDomainType. + + + + +```julia +OpParameterDomain{T} <: AbstractDomain +``` + + +A domain to store operators. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L75-L79) + +
+
+
+# ConstraintDomains.PairVarsParameterDomainType. + + + + +```julia +PairVarsParameterDomain{T} <: AbstractDomain +``` + + +A domain to store values paired with variables. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L86-L90) + +
+
+
+# ConstraintDomains.RangeDomainType. + + + + +```julia +RangeDomain +``` + + +A discrete domain defined by a `range <: AbstractRange{Real}`. As ranges are immutable in Julia, changes in `RangeDomain` must use `set_domain!`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L16-L19) + +
+
+
+# ConstraintDomains.SetDomainType. + + + + +```julia +SetDomain{T <: Number} <: DiscreteDomain{T} +``` + + +Domain that stores discrete values as a set of (unordered) points. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L7-L10) + +
+
+
+# ConstraintDomains.ValParameterDomainType. + + + + +```julia +ValParameterDomain{T} <: AbstractDomain +``` + + +A domain to store one value. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L99-L103) + +
+
+
+# ConstraintDomains.ValsParameterDomainType. + + + + +```julia +ValsParameterDomain{T} <: AbstractDomain +``` + + +A domain to store values. It is used to generate random parameters. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L110-L114) + +
+
+
+# Base.convertMethod. + + + + +```julia +Base.convert(::Type{Union{Intervals, RangeDomain}}, d::Union{Intervals, RangeDomain}) +``` + + +Extends `Base.convert` for domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/general.jl#L9-L13) + +
+
+
+# Base.delete!Method. + + + + +```julia +Base.delete!(d::SetDomain, value)(d::SetDomain, value) +``` + + +Delete `value` from the list of points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L76-L79) + +
+
+
+# Base.eltypeMethod. + + + + +```julia +Base.eltype(::AbstractDomain) +``` + + +Extend `eltype` for domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/general.jl#L1-L5) + +
+
+
+# Base.inMethod. + + + + +```julia +Base.in(x, itv::Intervals) +``` + + +Return `true` if `x ∈ I` for any 'I ∈ itv`, false otherwise.`x ∈ I` is equivalent to +- `a < x < b` if `I = (a, b)` + +- `a < x ≤ b` if `I = (a, b]` + +- `a ≤ x < b` if `I = [a, b)` + +- `a ≤ x ≤ b` if `I = [a, b]` + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L51-L58) + +
+
+
+# Base.inMethod. + + + + +```julia +Base.in(value, d <: AbstractDomain) +``` + + +Fallback method for `value ∈ d` that returns `false`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L28-L31) + +
+
+
+# Base.inMethod. + + + + +```julia +Base.in(value, d::D) where D <: DiscreteDomain +``` + + +Return `true` if `value` is a point of `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L58-L61) + +
+
+
+# Base.isemptyMethod. + + + + +```julia +Base.isempty(d <: AbstractDomain) +``` + + +Fallback method for `isempty(d)` that return `length(d) == 0` which default to `0`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L40-L43) + +
+
+
+# Base.lengthMethod. + + + + +```julia +Base.length(itv::Intervals) +``` + + +Return the sum of the length of each interval in `itv`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L26-L29) + +
+
+
+# Base.lengthMethod. + + + + +```julia +Base.rand(d <: AbstractDomain) +``` + + +Fallback method for `length(d)` that return `0`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L34-L37) + +
+
+
+# Base.lengthMethod. + + + + +```julia +Base.length(d::D) where D <: DiscreteDomain +``` + + +Return the number of points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L46-L49) + +
+
+
+# Base.randMethod. + + + + +```julia +Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain} +``` + + +Extends `Base.rand` to (a collection of) domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L72-L76) + +
+
+
+# Base.randMethod. + + + + +```julia +Base.rand(fa::FakeAutomaton) +``` + + +Extends `Base.rand`. Currently simply returns `fa`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L135-L139) + +
+
+
+# Base.randMethod. + + + + +```julia +Base.rand(itv::Intervals) +Base.rand(itv::Intervals, i) +``` + + +Return a random value from `itv`, specifically from the `i`th interval if `i` is specified. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L32-L36) + +
+
+
+# Base.randMethod. + + + + +```julia +Base.rand(d::D) where D <: DiscreteDomain +``` + + +Draw randomly a point in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L52-L55) + +
+
+
+# Base.stringMethod. + + + + +```julia +Base.string(D::Vector{<:AbstractDomain}) +Base.string(d<:AbstractDomain) +``` + + +Extends the `string` method to (a vector of) domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L87-L92) + +
+
+
+# ConstraintCommons.acceptMethod. + + + + +```julia +ConstraintCommons.accept(fa::FakeAutomaton, word) +``` + + +Implement the `accept` methods for `FakeAutomaton`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L41-L45) + +
+
+
+# ConstraintDomains.ArbitraryDomainMethod. + + + + +```julia +ArbitraryDomain{T} <: DiscreteDomain{T} +``` + + +A domain type that stores arbitrary values, possibly non numeric, of type `T`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L24-L28) + +
+
+
+# ConstraintDomains._exploreMethod. + + + + +```julia +_explore(args...) +``` + + +Internals of the `explore` function. Behavior is automatically adjusted on the kind of exploration: `:flexible`, `:complete`, `:partial`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/explore.jl#L29-L33) + +
+
+
+# ConstraintDomains.add!Method. + + + + +```julia +add!(d::SetDomain, value) +``` + + +Add `value` to the list of points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L70-L73) + +
+
+
+# ConstraintDomains.domainMethod. + + + + +```julia +domain(values) +domain(range::R) where {T <: Real, R <: AbstractRange{T}} +``` + + +Construct either a `SetDomain` or a `RangeDomain``. + +```julia +d1 = domain(1:5) +d2 = domain([53.69, 89.2, 0.12]) +d3 = domain([2//3, 89//123]) +d4 = domain(4.3) +d5 = domain(1,42,86.9) +``` + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L31-L42) + +
+
+
+# ConstraintDomains.domainMethod. + + + + +```julia +domain() +``` + + +Construct an `EmptyDomain`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L20-L23) + +
+
+
+# ConstraintDomains.domainMethod. + + + + +```julia +domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real} +domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real} +``` + + +Construct a domain of continuous interval(s). + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L15-L19) + +
+
+
+# ConstraintDomains.domain_sizeMethod. + + + + +```julia +domain_size(itv::Intervals) +``` + + +Return the difference between the highest and lowest values in `itv`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L61-L64) + +
+
+
+# ConstraintDomains.domain_sizeMethod. + + + + +```julia +domain_size(d <: AbstractDomain) +``` + + +Fallback method for `domain_size(d)` that return `length(d)`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L46-L49) + +
+
+
+# ConstraintDomains.domain_sizeMethod. + + + + +```julia +domain_size(d::D) where D <: DiscreteDomain +``` + + +Return the maximum distance between two points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L64-L67) + +
+
+
+# ConstraintDomains.exploreMethod. + + + + +```julia +explore(domains, concept, param = nothing; search_limit = 1000, solutions_limit = 100) +``` + + +Search (a part of) a search space and returns a pair of vector of configurations: `(solutions, non_solutions)`. If the search space size is over `search_limit`, then both `solutions` and `non_solutions` are limited to `solutions_limit`. + +Beware that if the density of the solutions in the search space is low, `solutions_limit` needs to be reduced. This process will be automatic in the future (simple reinforcement learning). + +**Arguments:** +- `domains`: a collection of domains + +- `concept`: the concept of the targeted constraint + +- `param`: an optional parameter of the constraint + +- `sol_number`: the required number of solutions (half of the number of configurations), default to `100` + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/explore.jl#L66-L78) + +
+
+
+# ConstraintDomains.fake_automatonMethod. + + + + +```julia +fake_automaton(d) +``` + + +Construct a `FakeAutomaton`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L48-L52) + +
+
+
+# ConstraintDomains.generate_parametersMethod. + + + + +```julia +generate_parameters(d<:AbstractDomain, param) +``` + + +Generates random parameters based on the domain `d` and the kind of parameters `param`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L128-L132) + +
+
+
+# ConstraintDomains.get_domainMethod. + + + + +```julia +get_domain(::AbstractDomain) +``` + + +Access the internal structure of any domain type. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L52-L55) + +
+
+
+# ConstraintDomains.intersect_domains!Method. + + + + +```julia +intersect_domains!(is, i, new_itvls) +``` + + +Compute the intersections of a domain with an interval and store the results in `new_itvls`. + +**Arguments** +- `is::IS`: a collection of intervals. + +- `i::I`: an interval. + +- `new_itvls::Vector{I}`: a vector to store the results. + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L89-L98) + +
+
+
+# ConstraintDomains.intersect_domainsMethod. + + + + +```julia +intersect_domains(d₁, d₂) +``` + + +Compute the intersections of two domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L72-L76) + +
+
+
+# ConstraintDomains.merge_domainsMethod. + + + + +```julia +merge_domains(d₁::AbstractDomain, d₂::AbstractDomain) +``` + + +Merge two domains of same nature (discrete/contiuous). + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L83-L87) + +
+
+
+# ConstraintDomains.sizeMethod. + + + + +```julia +Base.size(i::I) where {I <: Interval} +``` + + +Defines the size of an interval as its `span`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L118-L122) + +
+
+
+# ConstraintDomains.to_domainsMethod. + + + + +```julia +to_domains(args...) +``` + + +Convert various arguments into valid domains format. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L58-L62) + +
+
+
+# Constraints.USUAL_CONSTRAINTSConstant. + + + + +```julia +USUAL_CONSTRAINTS::Dict +``` + + +Dictionary that contains all the usual constraints defined in Constraint.jl. It is based on XCSP3-core specifications available at https://arxiv.org/abs/2009.00514 + +Adding a new constraint is as simple as defining a new function with the same name as the constraint and using the `@usual` macro to define it. The macro will take care of adding the new constraint to the `USUAL_CONSTRAINTS` dictionary. + +**Example** + +```julia +@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L1-L11) + +
+
+
+# Constraints.USUAL_SYMMETRIESConstant. + + + + +```julia +USUAL_SYMMETRIES +``` + + +A Dictionary that contains the function to apply for each symmetry to avoid searching a whole space. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L1-L4) + +
+
+
+# Constraints.ConstraintType. + + + + +```julia +Constraint +``` + + +Parametric structure with the following fields. +- `concept`: a Boolean function that, given an assignment `x`, outputs `true` if `x` satisfies the constraint, and `false` otherwise. + +- `error`: a positive function that works as preferences over invalid assignments. Return `0.0` if the constraint is satisfied, and a strictly positive real otherwise. + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L7-L12) + +
+
+
+# ConstraintCommons.extract_parametersFunction. + + + + +```julia +extract_parameters(s::Symbol, constraints_dict=USUAL_CONSTRAINTS; parameters=ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS) +``` + + +Return the parameters of the constraint `s` in `constraints_dict`. + +**Arguments** +- `s::Symbol`: the constraint name. + +- `constraints_dict::Dict{Symbol,Constraint}`: dictionary of constraints. Default is `USUAL_CONSTRAINTS`. + +- `parameters::Vector{Symbol}`: vector of parameters. Default is `ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS`. + + +**Example** + +```julia +extract_parameters(:all_different) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L44-L58) + +
+
+
+# Constraints.argsMethod. + + + + +```julia +args(c::Constraint) +``` + + +Return the expected length restriction of the arguments in a constraint `c`. The value `nothing` indicates that any strictly positive number of value is accepted. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L62-L65) + +
+
+
+# Constraints.conceptMethod. + + + + +```julia +concept(c::Constraint) +``` + + +Return the concept (function) of constraint `c`. concept(c::Constraint, x...; param = nothing) Apply the concept of `c` to values `x` and optionally `param`. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L40-L45) + +
+
+
+# Constraints.conceptMethod. + + + + +```julia +concept(s::Symbol, args...; kargs...) +``` + + +Return the concept of the constraint `s` applied to `args` and `kargs`. This is a shortcut for `concept(USUAL_CONSTRAINTS[s])(args...; kargs...)`. + +**Arguments** +- `s::Symbol`: the constraint name. + +- `args...`: the arguments to apply the concept to. + +- `kargs...`: the keyword arguments to apply the concept to. + + +**Example** + +```julia +concept(:all_different, [1, 2, 3]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L221-L235) + +
+
+
+# Constraints.concept_vs_errorMethod. + + + + +```julia +concept_vs_error(c, e, args...; kargs...) +``` + + +Compare the results of a concept function and an error function for the same inputs. It is mainly used for testing purposes. + +**Arguments** +- `c`: The concept function. + +- `e`: The error function. + +- `args...`: Positional arguments to be passed to both the concept and error functions. + +- `kargs...`: Keyword arguments to be passed to both the concept and error functions. + + +**Returns** +- Boolean: Returns true if the result of the concept function is not equal to whether the result of the error function is greater than 0.0. Otherwise, it returns false. + + +**Examples** + +```julia +concept_vs_error(all_different, make_error(:all_different), [1, 2, 3]) # Returns false +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L111-L129) + +
+
+
+# Constraints.constraints_descriptionsFunction. + + + + +```julia +constraints_descriptions(C=USUAL_CONSTRAINTS) +``` + + +Return a pretty table with the descriptions of the constraints in `C`. + +**Arguments** +- `C::Dict{Symbol,Constraint}`: dictionary of constraints. Default is `USUAL_CONSTRAINTS`. + + +**Example** + +```julia +constraints_descriptions() +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L180-L192) + +
+
+
+# Constraints.constraints_parametersFunction. + + + + +```julia +constraints_parameters(C=USUAL_CONSTRAINTS) +``` + + +Return a pretty table with the parameters of the constraints in `C`. + +**Arguments** +- `C::Dict{Symbol,Constraint}`: dictionary of constraints. Default is `USUAL_CONSTRAINTS`. + + +**Example** + +```julia +constraints_parameters() +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L127-L139) + +
+
+
+# Constraints.describeFunction. + + + + +```julia +describe(constraints::Dict{Symbol,Constraint}=USUAL_CONSTRAINTS; width=150) +``` + + +Return a pretty table with the description of the constraints in `constraints`. + +**Arguments** +- `constraints::Dict{Symbol,Constraint}`: dictionary of constraints to describe. Default is `USUAL_CONSTRAINTS`. + +- `width::Int`: width of the table. + + +**Example** + +```julia +describe() +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L14-L27) + +
+
+
+# Constraints.error_fMethod. + + + + +```julia +error_f(c::Constraint) +``` + + +Return the error function of constraint `c`. error_f(c::Constraint, x; param = nothing) Apply the error function of `c` to values `x` and optionally `param`. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L51-L56) + +
+
+
+# Constraints.make_errorMethod. + + + + +```julia +make_error(symb::Symbol) +``` + + +Create a function that returns an error based on the predicate of the constraint identified by the symbol provided. + +**Arguments** +- `symb::Symbol`: The symbol used to determine the error function to be returned. The function first checks if a predicate with the prefix "icn_" exists in the Constraints module. If it does, it returns that function. If it doesn't, it checks for a predicate with the prefix "error_". If that exists, it returns that function. If neither exists, it returns a function that evaluates the predicate with the prefix "concept_" and returns the negation of its result cast to Float64. + + +**Returns** +- Function: A function that takes in a variable `x` and an arbitrary number of parameters `params`. The function returns a Float64. + + +**Examples** + +```julia +e = make_error(:all_different) +e([1, 2, 3]) # Returns 0.0 +e([1, 1, 3]) # Returns 1.0 +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L80-L97) + +
+
+
+# Constraints.params_lengthMethod. + + + + +```julia +params_length(c::Constraint) +``` + + +Return the expected length restriction of the arguments in a constraint `c`. The value `nothing` indicates that any strictly positive number of parameters is accepted. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L68-L71) + +
+
+
+# Constraints.shrink_conceptMethod. + + + + +```julia +shrink_concept(s) +``` + + +Simply delete the `concept_` part of symbol or string starting with it. TODO: add a check with a warning if `s` starts with something different. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L104-L108) + +
+
+
+# Constraints.symmetriesMethod. + + + + +```julia +symmetries(c::Constraint) +``` + + +Return the list of symmetries of `c`. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L74-L77) + +
+
+
+# Constraints.xcsp_all_differentMethod. + + + + +```julia +xcsp_all_different(list::Vector{Int}) +``` + + +Return `true` if all the values of `list` are different, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + + +**Variants** +- `:all_different`: Global constraint ensuring that all the values of `x` are all different. + + +```julia +concept(:all_different, x; vals) +concept(:all_different)(x; vals) +``` + + +**Examples** + +```julia +c = concept(:all_different) + +c([1, 2, 3, 4]) +c([1, 2, 3, 1]) +c([1, 0, 0, 4]; vals=[0]) +c([1, 0, 0, 1]; vals=[0]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/all_different.jl#L7-L31) + +
+
+
+# Constraints.xcsp_all_equalMethod. + + + + +```julia +xcsp_all_equal(list::Vector{Int}, val::Int) +``` + + +Return `true` if all the values of `list` are equal to `val`, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `val::Int`: value to compare to. + + +**Variants** +- `:all_equal`: Global constraint ensuring that all the values of `x` are all equal. + + +```julia +concept(:all_equal, x; val=nothing, pair_vars=zeros(x), op=+) +concept(:all_equal)(x; val=nothing, pair_vars=zeros(x), op=+) +``` + + +**Examples** + +```julia +c = concept(:all_equal) + +c([0, 0, 0, 0]) +c([1, 2, 3, 4]) +c([3, 2, 1, 0]; pair_vars=[0, 1, 2, 3]) +c([0, 1, 2, 3]; pair_vars=[0, 1, 2, 3]) +c([1, 2, 3, 4]; op=/, val=1, pair_vars=[1, 2, 3, 4]) +c([1, 2, 3, 4]; op=*, val=1, pair_vars=[1, 2, 3, 4]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/all_equal.jl#L9-L36) + +
+
+
+# Constraints.xcsp_cardinalityMethod. + + + + +```julia +xcsp_cardinality(list, values, occurs, closed) +``` + + +Return `true` if the number of occurrences of the values in `values` in `list` satisfies the given condition, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `values::Vector{Int}`: list of values to check. + +- `occurs::Vector{Int}`: list of occurrences to check. + +- `closed::Bool`: whether the constraint is closed or not. + + +**Variants** +- `:cardinality`: The cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. + + +```julia +concept(:cardinality, x; bool=false, vals) +concept(:cardinality)(x; bool=false, vals) +``` + +- `:cardinality_closed`: The closed cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. It is closed, meaning that all values in the domain of the variables must be considered. + + +```julia +concept(:cardinality_closed, x; vals) +concept(:cardinality_closed)(x; vals) +``` + +- `:cardinality_open`: The open cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. It is open, meaning that only the values in the list of values must be considered. + + +```julia +concept(:cardinality_open, x; vals) +concept(:cardinality_open)(x; vals) +``` + + +**Examples** + +```julia +c = concept(:cardinality) + +c([2, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) +c([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=false) +c([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=true) +c([2, 5, 10, 10]; vals=[2 1; 5 1; 10 2]) +c([2, 5, 10, 10]; vals=[2 0 1 42; 5 1 3 7; 10 2 3 -4]) +c([2, 5, 5, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) +c([2, 5, 10, 8]; vals=[2 1; 5 1; 10 2]) +c([5, 5, 5, 10]; vals=[2 0 1 42; 5 1 3 7; 10 2 3 -4]) + +cc = concept(:cardinality_closed) +cc([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) + +co = concept(:cardinality_open) +co([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/cardinality.jl#L14-L61) + +
+
+
+# Constraints.xcsp_channelMethod. + + + + +```julia +xcsp_channel(; list) +``` + + +Return `true` if the channel constraint is satisfied, `false` otherwise. The channel constraint establishes a bijective correspondence between two sets of variables. This means that each value in the first set of variables corresponds to a unique value in the second set, and vice versa. + +**Arguments** +- `list::Union{AbstractVector, Tuple}`: list of values to check. + + +**Variants** +- `:channel`: The channel constraint establishes a bijective correspondence between two sets of variables. This means that each value in the first set of variables corresponds to a unique value in the second set, and vice versa. + + +```julia +concept(:channel, x; dim=1, id=nothing) +concept(:channel)(x; dim=1, id=nothing) +``` + + +**Examples** + +```julia +c = concept(:channel) + +c([2, 1, 4, 3]) +c([1, 2, 3, 4]) +c([2, 3, 1, 4]) +c([2, 1, 5, 3, 4, 2, 1, 4, 5, 3]; dim=2) +c([2, 1, 4, 3, 5, 2, 1, 4, 5, 3]; dim=2) +c([false, false, true, false]; id=3) +c([false, false, true, false]; id=1) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/channel.jl#L5-L32) + +
+
+
+# Constraints.xcsp_circuitMethod. + + + + +```julia +xcsp_circuit(; list, size) +``` + + +Return `true` if the circuit constraint is satisfied, `false` otherwise. The circuit constraint is a global constraint used in constraint programming, often in routing problems. It ensures that the values of a list of variables form a circuit, i.e., a sequence where each value is the index of the next value in the sequence, and the sequence eventually loops back to the start. + +**Arguments** +- `list::AbstractVector`: list of values to check. + +- `size::Int`: size of the circuit. + + +**Variants** +- `:circuit`: The circuit constraint is a global constraint used in constraint programming, often in routing problems. It ensures that the values of a list of variables form a circuit, i.e., a sequence where each value is the index of the next value in the sequence, and the sequence eventually loops back to the start. + + +```julia +concept(:circuit, x; op, val) +concept(:circuit)(x; op, val) +``` + + +**Examples** + +```julia +c = concept(:circuit) + +c([1, 2, 3, 4]) +c([2, 3, 4, 1]) +c([2, 3, 1, 4]; op = ==, val = 3) +c([4, 3, 1, 3]; op = >, val = 0) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/circuit.jl#L5-L30) + +
+
+
+# Constraints.xcsp_countMethod. + + + + +```julia +xcsp_count(list, values, condition) +``` + + +Return `true` if the number of occurrences of the values in `values` in `list` satisfies the given condition, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `values::Vector{Int}`: list of values to check. + +- `condition`: condition to satisfy. + + +**Variants** +- `:count`: Constraint ensuring that the number of occurrences of the values in `vals` in `x` satisfies the given condition. + + +```julia +concept(:count, x; vals, op, val) +concept(:count)(x; vals, op, val) +``` + +- `:at_least`: Constraint ensuring that the number of occurrences of the values in `vals` in `x` is at least `val`. + + +```julia +concept(:at_least, x; vals, val) +concept(:at_least)(x; vals, val) +``` + +- `:at_most`: Constraint ensuring that the number of occurrences of the values in `vals` in `x` is at most `val`. + + +```julia +concept(:at_most, x; vals, val) +concept(:at_most)(x; vals, val) +``` + +- `:exactly`: Constraint ensuring that the number of occurrences of the values in `vals` in `x` is exactly `val`. + + +```julia +concept(:exactly, x; vals, val) +concept(:exactly)(x; vals, val) +``` + + +**Examples** + +```julia +c = concept(:count) + +c([2, 1, 4, 3]; vals=[1, 2, 3, 4], op=≥, val=2) +c([1, 2, 3, 4]; vals=[1, 2], op==, val=2) +c([2, 1, 4, 3]; vals=[1, 2], op=≤, val=1) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/count.jl#L17-L57) + +
+
+
+# Constraints.xcsp_cumulativeMethod. + + + + +```julia +xcsp_cumulative(; origins, lengths, heights, condition) +``` + + +Return `true` if the cumulative constraint is satisfied, `false` otherwise. The cumulative constraint is a global constraint used in constraint programming that is often used in scheduling problems. It ensures that for any point in time, the sum of the "heights" of tasks that are ongoing at that time does not exceed a certain limit. + +**Arguments** +- `origins::AbstractVector`: list of origins of the tasks. + +- `lengths::AbstractVector`: list of lengths of the tasks. + +- `heights::AbstractVector`: list of heights of the tasks. + +- `condition::Tuple`: condition to check. + + +**Variants** +- `:cumulative`: The cumulative constraint is a global constraint used in constraint programming that is often used in scheduling problems. It ensures that for any point in time, the sum of the "heights" of tasks that are ongoing at that time does not exceed a certain limit. + + +```julia +concept(:cumulative, x; pair_vars, op, val) +concept(:cumulative)(x; pair_vars, op, val) +``` + + +**Examples** + +```julia +c = concept(:cumulative) + +c([1, 2, 3, 4, 5]; val = 1) +c([1, 2, 2, 4, 5]; val = 1) +c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = ≤, val = 5) +c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/cumulative.jl#L5-L32) + +
+
+
+# Constraints.xcsp_elementMethod. + + + + +```julia +xcsp_element(; list, index, condition) +``` + + +Return `true` if the element constraint is satisfied, `false` otherwise. The element constraint is a global constraint used in constraint programming that specifies that the value of a variable should be equal to the value of another variable indexed by a third variable. + +**Arguments** +- `list::Union{AbstractVector, Tuple}`: list of values to check. + +- `index::Int`: index of the value to check. + +- `condition::Tuple`: condition to check. + + +**Variants** +- `:element`: The element constraint is a global constraint used in constraint programming that specifies that the value of a variable should be equal to the value of another variable indexed by a third variable. + + +```julia +concept(:element, x; id=nothing, op===, val=nothing) +concept(:element)(x; id=nothing, op===, val=nothing) +``` + + +**Examples** + +```julia +c = concept(:element) + +c([1, 2, 3, 4, 5]; id=1, val=1) +c([1, 2, 3, 4, 5]; id=1, val=2) +c([1, 2, 3, 4, 2]) +c([1, 2, 3, 4, 1]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/element.jl#L5-L31) + +
+
+
+# Constraints.xcsp_extensionMethod. + + + + +```julia +xcsp_extension(; list, supports=nothing, conflicts=nothing) +``` + + +Global constraint enforcing that the tuple `x` matches a configuration within the supports set `pair_vars[1]` or does not match any configuration within the conflicts set `pair_vars[2]`. It embodies the logic: `x ∈ pair_vars[1] || x ∉ pair_vars[2]`, providing a comprehensive way to define valid (supported) and invalid (conflicted) tuples for constraint satisfaction problems. This constraint is versatile, allowing for the explicit delineation of both acceptable and unacceptable configurations. + +**Arguments** +- `list::Vector{Int}`: A list of variables + +- `supports::Vector{Vector{Int}}`: A set of supported tuples. Default to nothing. + +- `conflicts::Vector{Vector{Int}}`: A set of conflicted tuples. Default to nothing. + + +**Variants** +- `:extension`: Global constraint enforcing that the tuple `x` matches a configuration within the supports set `pair_vars[1]` or does not match any configuration within the conflicts set `pair_vars[2]`. It embodies the logic: `x ∈ pair_vars[1] || x ∉ pair_vars[2]`, providing a comprehensive way to define valid (supported) and invalid (conflicted) tuples for constraint satisfaction problems. This constraint is versatile, allowing for the explicit delineation of both acceptable and unacceptable configurations. + + +```julia +concept(:extension, x; pair_vars) +concept(:extension)(x; pair_vars) +``` + +- `:supports`: Global constraint ensuring that the tuple `x` matches a configuration listed within the support set `pair_vars`. This constraint is derived from the extension model, specifying that `x` must be one of the explicitly defined supported configurations: `x ∈ pair_vars`. It is utilized to directly declare the tuples that are valid and should be included in the solution space. + + +```julia +concept(:supports, x; pair_vars) +concept(:supports)(x; pair_vars) +``` + +- `:conflicts`: Global constraint ensuring that the tuple `x` does not match any configuration listed within the conflict set `pair_vars`. This constraint, originating from the extension model, stipulates that `x` must avoid all configurations defined as conflicts: `x ∉ pair_vars`. It is useful for specifying tuples that are explicitly forbidden and should be excluded from the solution space. + + +```julia +concept(:conflicts, x; pair_vars) +concept(:conflicts)(x; pair_vars) +``` + + +**Examples** + +```julia +c = concept(:extension) +c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 3, 4, 5]]) +c([1, 2, 3, 4, 5]; pair_vars=([[1, 2, 3, 4, 5]], [[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]])) +c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]]) + +c = concept(:supports) +c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 3, 4, 5]]) + +c = concept(:conflicts) +c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/extension.jl#L20-L60) + +
+
+
+# Constraints.xcsp_instantiationMethod. + + + + +```julia +xcsp_instantiation(; list, values) +``` + + +Return `true` if the instantiation constraint is satisfied, `false` otherwise. The instantiation constraint is a global constraint used in constraint programming that ensures that a list of variables takes on a specific set of values in a specific order. + +**Arguments** +- `list::AbstractVector`: list of values to check. + +- `values::AbstractVector`: list of values to check against. + + +**Variants** +- `:instantiation`: The instantiation constraint is a global constraint used in constraint programming that ensures that a list of variables takes on a specific set of values in a specific order. + + +```julia +concept(:instantiation, x; pair_vars) +concept(:instantiation)(x; pair_vars) +``` + + +**Examples** + +```julia +c = concept(:instantiation) + +c([1, 2, 3, 4, 5]; pair_vars=[1, 2, 3, 4, 5]) +c([1, 2, 3, 4, 5]; pair_vars=[1, 2, 3, 4, 6]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/instantiation.jl#L5-L28) + +
+
+
+# Constraints.xcsp_intensionMethod. + + + + +```julia +xcsp_intension(list, predicate) +``` + + +An intensional constraint is usually defined from a `predicate` over `list`. As such it encompass any generic constraint. + +**Arguments** +- `list::Vector{Int}`: A list of variables + +- `predicate::Function`: A predicate over `list` + + +**Variants** +- `:dist_different`: A constraint ensuring that the distances between marks on the ruler are unique. Specifically, it checks that the distance between `x[1]` and `x[2]`, and the distance between `x[3]` and `x[4]`, are different. This constraint is fundamental in ensuring the validity of a Golomb ruler, where no two pairs of marks should have the same distance between them. + + +```julia +concept(:dist_different, x) +concept(:dist_different)(x) +``` + + +**Examples** + +```@example debug2 +2 + 2 +``` + + +```@example debug1 +2 + 2 +``` + + +```@example intention1 +using Constraints # hide +c = concept(:dist_different) +c([1, 2, 3, 3]) && !c([1, 2, 3, 4]) +``` + + +```@example intention2 +using Constraints # hide +c = concept(:dist_different) +c([1, 2, 3, 3]) && !c([1, 2, 3, 4]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/intention.jl#L9-L47) + +
+
+
+# Constraints.xcsp_maximumMethod. + + + + +```julia +xcsp_maximum(; list, condition) +``` + + +Return `true` if the maximum constraint is satisfied, `false` otherwise. The maximum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the maximum value in a list of variables. + +**Arguments** +- `list::Union{AbstractVector, Tuple}`: list of values to check. + +- `condition::Tuple`: condition to check. + + +**Variants** +- `:maximum`: The maximum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the maximum value in a list of variables. + + +```julia +concept(:maximum, x; op, val) +concept(:maximum)(x; op, val) +``` + + +**Examples** + +```julia +c = concept(:maximum) + +c([1, 2, 3, 4, 5]; op = ==, val = 5) +c([1, 2, 3, 4, 5]; op = ==, val = 6) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/maximum.jl#L5-L28) + +
+
+
+# Constraints.xcsp_mddMethod. + + + + +```julia +xcsp_mdd(; list, diagram) +``` + + +Return a function that checks if the list of values `list` satisfies the MDD `diagram`. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `diagram::MDD`: MDD to check. + + +**Variants** +- `:mdd`: Multi-valued Decision Diagram (MDD) constraint. + The MDD constraint is a constraint that can be used to model a wide range of problems. It is a directed graph where each node is labeled with a value and each edge is labeled with a value. The constraint is satisfied if there is a path from the first node to the last node such that the sequence of edge labels is a valid sequence of the value labels. + + +```julia +concept(:mdd, x; language) +concept(:mdd)(x; language) +``` + + +**Examples** + +```julia +c = concept(:mdd) + +states = [ + Dict( # level x1 + (:r, 0) => :n1, + (:r, 1) => :n2, + (:r, 2) => :n3, + ), + Dict( # level x2 + (:n1, 2) => :n4, + (:n2, 2) => :n4, + (:n3, 0) => :n5, + ), + Dict( # level x3 + (:n4, 0) => :t, + (:n5, 0) => :t, + ), +] + +a = MDD(states) + +c([0,2,0]; language = a) +c([1,2,0]; language = a) +c([2,0,0]; language = a) +c([2,1,2]; language = a) +c([1,0,2]; language = a) +c([0,1,2]; language = a) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/mdd.jl#L9-L55) + +
+
+
+# Constraints.xcsp_minimumMethod. + + + + +```julia +xcsp_minimum(; list, condition) +``` + + +Return `true` if the minimum constraint is satisfied, `false` otherwise. The minimum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the minimum value in a list of variables. + +**Arguments** +- `list::Union{AbstractVector, Tuple}`: list of values to check. + +- `condition::Tuple`: condition to check. + + +**Variants** +- `:minimum`: The minimum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the minimum value in a list of variables. + + +```julia +concept(:minimum, x; op, val) +concept(:minimum)(x; op, val) +``` + + +**Examples** + +```julia +c = concept(:minimum) + +c([1, 2, 3, 4, 5]; op = ==, val = 1) +c([1, 2, 3, 4, 5]; op = ==, val = 0) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/minimum.jl#L5-L28) + +
+
+
+# Constraints.xcsp_no_overlapMethod. + + + + +```julia +xcsp_no_overlap(; origins, lengths, zero_ignored) +``` + + +Return `true` if the no_overlap constraint is satisfied, `false` otherwise. The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. + +**Arguments** +- `origins::AbstractVector`: list of origins of the tasks. + +- `lengths::AbstractVector`: list of lengths of the tasks. + +- `zero_ignored::Bool`: whether to ignore zero-length tasks. + + +**Variants** +- `:no_overlap`: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. + + +```julia +concept(:no_overlap, x; pair_vars, bool) +concept(:no_overlap)(x; pair_vars, bool) +``` + +- `:no_overlap_no_zero`: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant ignores zero-length tasks. + + +```julia +concept(:no_overlap_no_zero, x; pair_vars) +concept(:no_overlap_no_zero)(x; pair_vars) +``` + +- `:no_overlap_with_zero`: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant includes zero-length tasks. + + +```julia +concept(:no_overlap_with_zero, x; pair_vars) +concept(:no_overlap_with_zero)(x; pair_vars) +``` + + +**Examples** + +```julia +c = concept(:no_overlap) + +c([1, 2, 3, 4, 5]) +c([1, 2, 3, 4, 1]) +c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 1, 1]) +c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 3, 1]) +c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 3, 1, 1]) +c([1, 1, 1, 3, 5, 2, 7, 7, 5, 12, 8, 7]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3) +c([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/no_overlap.jl#L13-L52) + +
+
+
+# Constraints.xcsp_nvaluesMethod. + + + + +```julia +xcsp_nvalues(list, condition, except) +``` + + +Return `true` if the number of distinct values in `list` satisfies the given condition, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `condition`: condition to satisfy. + +- `except::Union{Nothing, Vector{Int}}`: list of values to exclude. Default is `nothing`. + + +**Variants** +- `:nvalues`: The nValues constraint specifies that the number of distinct values in the list of variables x is equal to a given value. The constraint is defined by the following expression: nValues(x, op, val) where x is a list of variables, op is a comparison operator, and val is an integer value. + + +```julia +concept(:nvalues, x; op, val) +concept(:nvalues)(x; op, val) +``` + + +**Examples** + +```julia +c = concept(:nvalues) + +c([1, 2, 3, 4, 5]; op = ==, val = 5) +c([1, 2, 3, 4, 5]; op = ==, val = 2) +c([1, 2, 3, 4, 3]; op = <=, val = 5) +c([1, 2, 3, 4, 3]; op = <=, val = 3) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/n_values.jl#L7-L33) + +
+
+
+# Constraints.xcsp_orderedMethod. + + + + +```julia +xcsp_ordered(list::Vector{Int}, operator, lengths) +``` + + +Return `true` if all the values of `list` are in an increasing order, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `operator`: comparison operator to use. + +- `lengths`: list of lengths to use. Defaults to `nothing`. + + +**Variants** +- `:ordered`: Global constraint ensuring that all the values of `x` are in an increasing order. + + +```julia +concept(:ordered, x; op=≤, pair_vars=nothing) +concept(:ordered)(x; op=≤, pair_vars=nothing) +``` + +- `:increasing`: Global constraint ensuring that all the values of `x` are in an increasing order. + + +```julia +concept(:increasing, x; op=≤, pair_vars=nothing) +concept(:increasing)(x; op=≤, pair_vars=nothing) +``` + +- `:decreasing`: Global constraint ensuring that all the values of `x` are in a decreasing order. + + +```julia +concept(:decreasing, x; op=≥, pair_vars=nothing) +concept(:decreasing)(x; op=≥, pair_vars=nothing) +``` + +- `:strictly_increasing`: Global constraint ensuring that all the values of `x` are in a strictly increasing order. + + +```julia +concept(:strictly_increasing, x; op=<, pair_vars=nothing) +concept(:strictly_increasing)(x; op=<, pair_vars=nothing) +``` + +- `:strictly_decreasing`: Global constraint ensuring that all the values of `x` are in a strictly decreasing order. + + +```julia +concept(:strictly_decreasing, x; op=>, pair_vars=nothing) +concept(:strictly_decreasing)(x; op=>, pair_vars=nothing) +``` + + +**Examples** + +```julia +c = concept(:ordered) + +c([1, 2, 3, 4, 4]; op=≤) +c([1, 2, 3, 4, 5]; op=<) +!c([1, 2, 3, 4, 3]; op=≤) +!c([1, 2, 3, 4, 3]; op=<) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/ordered.jl#L21-L67) + +
+
+
+# Constraints.xcsp_regularMethod. + + + + +```julia +xcsp_regular(; list, automaton) + +Ensures that a sequence `x` (interpreted as a word) is accepted by the regular language represented by a given automaton. This constraint verifies the compliance of `x` with the language rules encoded within the `automaton` parameter, which must be an instance of `<:AbstractAutomaton`. +``` + + +**Arguments** +- `list::Vector{Int}`: A list of variables + +- `automaton<:AbstractAutomaton`: An automaton representing the regular language + + +**Variants** +- `:regular`: Ensures that a sequence `x` (interpreted as a word) is accepted by the regular language represented by a given automaton. This constraint verifies the compliance of `x` with the language rules encoded within the `automaton` parameter, which must be an instance of `<:AbstractAutomaton`. + + +```julia +concept(:regular, x; language) +concept(:regular)(x; language) +``` + + +**Examples** + +```julia +c = concept(:regular) + +states = Dict( + (:a, 0) => :a, + (:a, 1) => :b, + (:b, 1) => :c, + (:c, 0) => :d, + (:d, 0) => :d, + (:d, 1) => :e, + (:e, 0) => :e, +) +start = :a +finish = :e + +a = Automaton(states, start, finish) + +c([0,0,1,1,0,0,1,0,0]; language = a) +c([1,1,1,0,1]; language = a) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/regular.jl#L5-L42) + +
+
+
+# Constraints.xcsp_sumMethod. + + + + +```julia +xcsp_sum(list, coeffs, condition) +``` + + +Return `true` if the sum of the variables in `list` satisfies the given condition, `false` otherwise. + +**Arguments** +- `list::Vector{Int}`: list of values to check. + +- `coeffs::Vector{Int}`: list of coefficients to use. + +- `condition`: condition to satisfy. + + +**Variants** +- `:sum`: Global constraint ensuring that the sum of the variables in `x` satisfies a given condition. + + +```julia +concept(:sum, x; op===, pair_vars=ones(x), val) +concept(:sum)(x; op===, pair_vars=ones(x), val) +``` + + +**Examples** + +```julia +c = concept(:sum) + +c([1, 2, 3, 4, 5]; op===, val=15) +c([1, 2, 3, 4, 5]; op===, val=2) +c([1, 2, 3, 4, 3]; op=≤, val=15) +c([1, 2, 3, 4, 3]; op=≤, val=3) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraints/sum.jl#L5-L31) + +
+
+
+# Constraints.@usualMacro. + + + + +```julia +usual(ex::Expr) +``` + + +This macro is used to define a new constraint or update an existing one in the USUAL_CONSTRAINTS dictionary. It takes an expression ex as input, which represents the definition of a constraint. + +Here's a step-by-step explanation of what the macro does: +1. It first extracts the symbol of the concept from the input expression. This symbol is expected to be the first argument of the first argument of the expression. For example, if the expression is @usual all_different(x; y=1), the symbol would be :all_different. + +2. It then calls the shrink_concept function on the symbol to get a simplified version of the concept symbol. + +3. It initializes a dictionary defaults to store whether each keyword argument of the concept has a default value or not. + +4. It checks if the expression has more than two arguments. If it does, it means that there are keyword arguments present. It then loops over these keyword arguments. If a keyword argument is a symbol, it means it doesn't have a default value, so it adds an entry to the defaults dictionary with the keyword argument as the key and false as the value. If a keyword argument is not a symbol, it means it has a default value, so it adds an entry to the defaults dictionary with the keyword argument as the key and true as the value. + +5. It calls the make_error function on the simplified concept symbol to generate an error function for the constraint. + +6. It evaluates the input expression to get the concept function. + +7. It checks if the USUAL_CONSTRAINTS dictionary already contains an entry for the simplified concept symbol. If it does, it adds the defaults dictionary to the parameters of the existing constraint. If it doesn't, it creates a new constraint with the concept function, a description, the error function, and the defaults dictionary as the parameters, and adds it to the USUAL_CONSTRAINTS dictionary. + + +This macro is used to make it easier to define and update constraints in a consistent and possibly automated way. + +**Arguments** +- `ex::Expr`: expression to parse. + + +**Example** + +```julia +@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L67-L90) + +
+
+
+# CompositionalNetworks.CompositionType. + + + + +```julia +struct Composition{F<:Function} +``` + + +Store the all the information of a composition learned by an ICN. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L1-L5) + +
+
+
+# CompositionalNetworks.CompositionMethod. + + + + +```julia +Composition(f::F, symbols) where {F<:Function} +``` + + +Construct a `Composition`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L12-L16) + +
+
+
+# CompositionalNetworks.ICNType. + + + + +```julia +ICN(; nvars, dom_size, param, transformation, arithmetic, aggregation, comparison) +``` + + +Construct an Interpretable Compositional Network, with the following arguments: +- `nvars`: number of variable in the constraint + +- `dom_size: maximum domain size of any variable in the constraint` + +- `param`: optional parameter (default to `nothing`) + +- `transformation`: a transformation layer (optional) + +- `arithmetic`: a arithmetic layer (optional) + +- `aggregation`: a aggregation layer (optional) + +- `comparison`: a comparison layer (optional) + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L1-L11) + +
+
+
+# CompositionalNetworks.LayerType. + + + + +```julia +Layer +``` + + +A structure to store a `LittleDict` of operations that can be selected during the learning phase of an ICN. If the layer is exclusive, only one operation can be selected at a time. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L1-L4) + +
+
+
+# Base.lengthMethod. + + + + +```julia +length(layer) +``` + + +Return the number of operations in a layer. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L17-L20) + +
+
+
+# Base.lengthMethod. + + + + +```julia +Base.length(icn) +``` + + +Return the total number of operations of an ICN. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L37-L40) + +
+
+
+# CompositionalNetworks._composeMethod. + + + + +```julia +_compose(icn) +``` + + +Internal function called by `compose` and `show_composition`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L112-L115) + +
+
+
+# CompositionalNetworks.ag_count_positiveMethod. + + + + +```julia +ag_count_positive(x) +``` + + +Count the number of strictly positive elements of `x`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/aggregation.jl#L7-L10) + +
+
+
+# CompositionalNetworks.ag_sumMethod. + + + + +```julia +ag_sum(x) +``` + + +Aggregate through `+` a vector into a single scalar. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/aggregation.jl#L1-L4) + +
+
+
+# CompositionalNetworks.aggregation_layerMethod. + + + + +```julia +aggregation_layer() +``` + + +Generate the layer of aggregations of the ICN. The operations are mutually exclusive, that is only one will be selected. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/aggregation.jl#L13-L16) + +
+
+
+# CompositionalNetworks.ar_prodMethod. + + + + +```julia +ar_prod(x) +``` + + +Reduce `k = length(x)` vectors through product to a single vector. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/arithmetic.jl#L7-L10) + +
+
+
+# CompositionalNetworks.ar_sumMethod. + + + + +```julia +ar_sum(x) +``` + + +Reduce `k = length(x)` vectors through sum to a single vector. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/arithmetic.jl#L1-L4) + +
+
+
+# CompositionalNetworks.arithmetic_layerMethod. + + + + +```julia +arithmetic_layer() +``` + + +Generate the layer of arithmetic operations of the ICN. The operations are mutually exclusive, that is only one will be selected. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/arithmetic.jl#L13-L16) + +
+
+
+# CompositionalNetworks.as_bitvectorFunction. + + + + +```julia +as_bitvector(n::Int, max_n::Int = n) +``` + + +Convert an Int to a BitVector of minimal size (relatively to `max_n`). + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L48-L51) + +
+
+
+# CompositionalNetworks.as_intMethod. + + + + +```julia +as_int(v::AbstractVector) +``` + + +Convert a `BitVector` into an `Int`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L65-L68) + +
+
+
+# CompositionalNetworks.co_abs_diff_val_paramMethod. + + + + +```julia +co_abs_diff_val_param(x; param) +``` + + +Return the absolute difference between `x` and `param`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L7-L10) + +
+
+
+# CompositionalNetworks.co_abs_diff_val_varsMethod. + + + + +```julia +co_abs_diff_val_vars(x; nvars) +``` + + +Return the absolute difference between `x` and the number of variables `nvars`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L41-L44) + +
+
+
+# CompositionalNetworks.co_euclideanMethod. + + + + +```julia +co_euclidean(x; dom_size) +``` + + +Compute an euclidean norm with domain size `dom_size` of a scalar. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L33-L36) + +
+
+
+# CompositionalNetworks.co_euclidean_paramMethod. + + + + +```julia +co_euclidean_param(x; param, dom_size) +``` + + +Compute an euclidean norm with domain size `dom_size`, weighted by `param`, of a scalar. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L25-L28) + +
+
+
+# CompositionalNetworks.co_identityMethod. + + + + +```julia +co_identity(x) +``` + + +Identity function. Already defined in Julia as `identity`, specialized for scalars in the `comparison` layer. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L1-L4) + +
+
+
+# CompositionalNetworks.co_param_minus_valMethod. + + + + +```julia +co_param_minus_val(x; param) +``` + + +Return the difference `param - x` if positive, `0.0` otherwise. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L19-L22) + +
+
+
+# CompositionalNetworks.co_val_minus_paramMethod. + + + + +```julia +co_val_minus_param(x; param) +``` + + +Return the difference `x - param` if positive, `0.0` otherwise. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L13-L16) + +
+
+
+# CompositionalNetworks.co_val_minus_varsMethod. + + + + +```julia +co_val_minus_vars(x; nvars) +``` + + +Return the difference `x - nvars` if positive, `0.0` otherwise, where `nvars` denotes the numbers of variables. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L47-L50) + +
+
+
+# CompositionalNetworks.co_vars_minus_valMethod. + + + + +```julia +co_vars_minus_val(x; nvars) +``` + + +Return the difference `nvars - x` if positive, `0.0` otherwise, where `nvars` denotes the numbers of variables. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L54-L57) + +
+
+
+# CompositionalNetworks.codeFunction. + + + + +```julia +code(c::Composition, lang=:maths; name="composition") +``` + + +Access the code of a composition `c` in a given language `lang`. The name of the generated method is optional. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L22-L26) + +
+
+
+# CompositionalNetworks.comparison_layerFunction. + + + + +```julia +comparison_layer(param = false) +``` + + +Generate the layer of transformations functions of the ICN. Iff `param` value is set, also includes all the parametric comparison with that value. The operations are mutually exclusive, that is only one will be selected. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L85-L88) + +
+
+
+# CompositionalNetworks.composeFunction. + + + + +```julia +compose(icn, weights=nothing) +``` + + +Return a function composed by some of the operations of a given ICN. Can be applied to any vector of variables. If `weights` are given, will assign to `icn`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L45-L48) + +
+
+
+# CompositionalNetworks.compose_to_file!Method. + + + + +```julia +compose_to_file!(concept, name, path; domains, param = nothing, language = :Julia, search = :complete, global_iter = 10, local_iter = 100, metric = hamming, popSize = 200) +``` + + +Explore, learn and compose a function and write it to a file. + +**Arguments:** +- `concept`: the concept to learn + +- `name`: the name to give to the constraint + +- `path`: path of the output file + + +**Keywords arguments:** +- `domains`: domains that defines the search space + +- `param`: an optional parameter of the constraint + +- `language`: the language to export to, default to `:julia` + +- `search`: either `:partial` or `:complete` search + +- `global_iter`: number of learning iteration + +- `local_iter`: number of generation in the genetic algorithm + +- `metric`: the metric to measure the distance between a configuration and known solutions + +- `popSize`: size of the population in the genetic algorithm + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/learn.jl#L77-L95) + +
+
+
+# CompositionalNetworks.compositionMethod. + + + + +```julia +composition(c::Composition) +``` + + +Access the actual method of an ICN composition `c`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L31-L35) + +
+
+
+# CompositionalNetworks.composition_to_file!Function. + + + + +```julia +composition_to_file!(c::Composition, path, name, language=:Julia) +``` + + +Write the composition code in a given `language` into a file at `path`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L97-L101) + +
+
+
+# CompositionalNetworks.excluMethod. + + + + +```julia +exclu(layer) +``` + + +Return `true` if the layer has mutually exclusive operations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L23-L26) + +
+
+
+# CompositionalNetworks.explore_learn_composeMethod. + + + + +```julia +explore_learn_compose(concept; domains, param = nothing, search = :complete, global_iter = 10, local_iter = 100, metric = hamming, popSize = 200, action = :composition) +``` + + +Explore a search space, learn a composition from an ICN, and compose an error function. + +**Arguments:** +- `concept`: the concept of the targeted constraint + +- `domains`: domains of the variables that define the training space + +- `param`: an optional parameter of the constraint + +- `search`: either `flexible`,`:partial` or `:complete` search. Flexible search will use `search_limit` and `solutions_limit` to determine if the search space needs to be partially or completely explored + +- `global_iter`: number of learning iteration + +- `local_iter`: number of generation in the genetic algorithm + +- `metric`: the metric to measure the distance between a configuration and known solutions + +- `popSize`: size of the population in the genetic algorithm + +- `action`: either `:symbols` to have a description of the composition or `:composition` to have the composed function itself + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/learn.jl#L35-L50) + +
+
+
+# CompositionalNetworks.functionsMethod. + + + + +```julia +functions(layer) +``` + + +Access the operations of a layer. The container is ordered. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L11-L14) + +
+
+
+# CompositionalNetworks.generateMethod. + + + + +```julia +generate(c::Composition, name, lang) +``` + + +Generates the code of `c` in a specific language `lang`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L55-L59) + +
+
+
+# CompositionalNetworks.generate_exclusive_operationMethod. + + + + +```julia +generate_exclusive_operation(max_op_number) +``` + + +Generates the operations (weigths) of a layer with exclusive operations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L75-L78) + +
+
+
+# CompositionalNetworks.generate_inclusive_operationsMethod. + + + + +```julia +generate_inclusive_operations(predicate, bits) +generate_exclusive_operation(max_op_number) +``` + + +Generates the operations (weights) of a layer with inclusive/exclusive operations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L61-L65) + +
+
+
+# CompositionalNetworks.generate_weightsMethod. + + + + +```julia +generate_weights(layers) +generate_weights(icn) +``` + + +Generate the weights of a collection of layers or of an ICN. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L84-L88) + +
+
+
+# CompositionalNetworks.hammingMethod. + + + + +```julia +hamming(x, X) +``` + + +Compute the hamming distance of `x` over a collection of solutions `X`, i.e. the minimal number of variables to switch in `x`to reach a solution. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/metrics.jl#L1-L4) + +
+
+
+# CompositionalNetworks.is_viableMethod. + + + + +```julia +is_viable(layer, w) +is_viable(icn) +is_viable(icn, w) +``` + + +Assert if a pair of layer/icn and weights compose a viable pattern. If no weights are given with an icn, it will check the current internal value. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L53-L58) + +
+
+
+# CompositionalNetworks.layersMethod. + + + + +```julia +layers(icn) +``` + + +Return the ordered layers of an ICN. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L31-L34) + +
+
+
+# CompositionalNetworks.lazyMethod. + + + + +```julia +lazy(funcs::Function...) +``` + + +Generate methods extended to a vector instead of one of its components. A function `f` should have the following signature: `f(i::Int, x::V)`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L22-L25) + +
+
+
+# CompositionalNetworks.lazy_paramMethod. + + + + +```julia +lazy_param(funcs::Function...) +``` + + +Generate methods extended to a vector instead of one of its components. A function `f` should have the following signature: `f(i::Int, x::V; param)`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L36-L39) + +
+
+
+# CompositionalNetworks.learn_composeMethod. + + + + +```julia +learn_compose(; + nvars, dom_size, param=nothing, icn=ICN(nvars, dom_size, param), + X, X_sols, global_iter=100, local_iter=100, metric=hamming, popSize=200 +) +``` + + +Create an ICN, optimize it, and return its composition. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/learn.jl#L7-L13) + +
+
+
+# CompositionalNetworks.make_transformationsMethod. + + + + +```julia +make_transformations(param::Symbol) +``` + + +Generates a dictionary of transformation functions based on the specified parameterization. This function facilitates the creation of parametric layers for constraint transformations, allowing for flexible and dynamic constraint manipulation according to the needs of different constraint programming models. + +**Parameters** +- `param::Symbol`: Specifies the type of transformations to generate. It can be `:none` for basic transformations that do not depend on external parameters, or `:val` for transformations that operate with respect to a specific value parameter. + + +**Returns** +- `LittleDict{Symbol, Function}`: A dictionary mapping transformation names (`Symbol`) to their corresponding functions (`Function`). The functions encapsulate various types of transformations, such as counting, comparison, and contiguous value processing. + + +**Transformation Types** +- When `param` is `:none`, the following transformations are available: + - `:identity`: No transformation is applied. + + - `:count_eq`, `:count_eq_left`, `:count_eq_right`: Count equalities under different conditions. + + - `:count_greater`, `:count_lesser`: Count values greater or lesser than a threshold. + + - `:count_g_left`, `:count_l_left`, `:count_g_right`, `:count_l_right`: Count values with greater or lesser comparisons from different directions. + + - `:contiguous_vals_minus`, `:contiguous_vals_minus_rev`: Process contiguous values with subtraction in normal and reverse order. + + +- When `param` is `:val`, the transformations relate to operations involving a parameter value: + - `:count_eq_param`, `:count_l_param`, `:count_g_param`: Count equalities or comparisons against a parameter value. + + - `:count_bounding_param`: Count values bounding a parameter value. + + - `:val_minus_param`, `:param_minus_val`: Subtract a parameter value from values or vice versa. + + + +The function delegates to a version that uses `Val(param)` for dispatch, ensuring compile-time selection of the appropriate transformation set. + +**Examples** + +```julia +# Get basic transformations +basic_transforms = make_transformations(:none) + +# Apply an identity transformation +identity_result = basic_transforms[:identity](data) + +# Get value-based transformations +val_transforms = make_transformations(:val) + +# Apply a count equal to parameter transformation +count_eq_param_result = val_transforms[:count_eq_param](data, param) +``` + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L216-L262) + +
+
+
+# CompositionalNetworks.manhattanMethod. + + + + +```julia +manhattan(x, X) +``` + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/metrics.jl#L12-L14) + +
+
+
+# CompositionalNetworks.map_tr!Method. + + + + +```julia +map_tr!(f, x, X, param) +``` + + +Return an anonymous function that applies `f` to all elements of `x` and store the result in `X`, with a parameter `param` (which is set to `nothing` for function with no parameter). + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L1-L4) + +
+
+
+# CompositionalNetworks.minkowskiMethod. + + + + +```julia +minkowski(x, X, p) +``` + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/metrics.jl#L7-L9) + +
+
+
+# CompositionalNetworks.nbitsMethod. + + + + +```julia +nbits(icn) +``` + + +Return the expected number of bits of a viable weight of an ICN. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L43-L46) + +
+
+
+# CompositionalNetworks.nbits_excluMethod. + + + + +```julia +nbits_exclu(layer) +``` + + +Convert the length of an exclusive layer into a number of bits. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L35-L38) + +
+
+
+# CompositionalNetworks.reduce_symbolsFunction. + + + + +```julia +reduce_symbols(symbols, sep) +``` + + +Produce a formatted string that separates the symbols by `sep`. Used internally for `show_composition`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L77-L80) + +
+
+
+# CompositionalNetworks.regularizationMethod. + + + + +```julia +regularization(icn) +``` + + +Return the regularization value of an ICN weights, which is proportional to the normalized number of operations selected in the icn layers. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L89-L92) + +
+
+
+# CompositionalNetworks.selected_sizeMethod. + + + + +```julia +selected_size(layer, layer_weights) +``` + + +Return the number of operations selected by `layer_weights` in `layer`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L47-L50) + +
+
+
+# CompositionalNetworks.show_layerMethod. + + + + +```julia +show_layer(layer) +``` + + +Return a string that contains the elements in a layer. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L41-L44) + +
+
+
+# CompositionalNetworks.show_layersMethod. + + + + +```julia +show_layers(icn) +``` + + +Return a formatted string with each layers in the icn. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L81-L84) + +
+
+
+# CompositionalNetworks.symbolMethod. + + + + +```julia +symbol(layer, i) +``` + + +Return the i-th symbols of the operations in a given layer. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L29-L32) + +
+
+
+# CompositionalNetworks.symbolsMethod. + + + + +```julia +symbols(c::Composition) +``` + + +Output the composition as a layered collection of `Symbol`s. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L38-L42) + +
+
+
+# CompositionalNetworks.tr_contiguous_vals_minusMethod. + + + + +```julia +tr_contiguous_vals_minus(i, x) +tr_contiguous_vals_minus(x) +tr_contiguous_vals_minus(x, X::AbstractVector) +``` + + +Return the difference `x[i] - x[i + 1]` if positive, `0.0` otherwise. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L190-L197) + +
+
+
+# CompositionalNetworks.tr_contiguous_vals_minus_revMethod. + + + + +```julia +tr_contiguous_vals_minus_rev(i, x) +tr_contiguous_vals_minus_rev(x) +tr_contiguous_vals_minus_rev(x, X::AbstractVector) +``` + + +Return the difference `x[i + 1] - x[i]` if positive, `0.0` otherwise. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L201-L208) + +
+
+
+# CompositionalNetworks.tr_count_bounding_paramMethod. + + + + +```julia +tr_count_bounding_param(i, x; param) +tr_count_bounding_param(x; param) +tr_count_bounding_param(x, X::AbstractVector; param) +``` + + +Count the number of elements bounded (not strictly) by `x[i]` and `x[i] + param`. An extended method to vector with sig `(x, param)` is generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L151-L158) + +
+
+
+# CompositionalNetworks.tr_count_eqMethod. + + + + +```julia +tr_count_eq(i, x) +tr_count_eq(x) +tr_count_eq(x, X::AbstractVector) +``` + + +Count the number of elements equal to `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L16-L23) + +
+
+
+# CompositionalNetworks.tr_count_eq_leftMethod. + + + + +```julia +tr_count_eq_left(i, x) +tr_count_eq_left(x) +tr_count_eq_left(x, X::AbstractVector) +``` + + +Count the number of elements to the left of and equal to `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L36-L43) + +
+
+
+# CompositionalNetworks.tr_count_eq_paramMethod. + + + + +```julia +tr_count_eq_param(i, x; param) +tr_count_eq_param(x; param) +tr_count_eq_param(x, X::AbstractVector; param) +``` + + +Count the number of elements equal to `x[i] + param`. Extended method to vector with sig `(x, param)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L116-L123) + +
+
+
+# CompositionalNetworks.tr_count_eq_rightMethod. + + + + +```julia +tr_count_eq_right(i, x) +tr_count_eq_right(x) +tr_count_eq_right(x, X::AbstractVector) +``` + + +Count the number of elements to the right of and equal to `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L26-L33) + +
+
+
+# CompositionalNetworks.tr_count_g_leftMethod. + + + + +```julia +tr_count_g_left(i, x) +tr_count_g_left(x) +tr_count_g_left(x, X::AbstractVector) +``` + + +Count the number of elements to the left of and greater than `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L71-L78) + +
+
+
+# CompositionalNetworks.tr_count_g_paramMethod. + + + + +```julia +tr_count_g_param(i, x; param) +tr_count_g_param(x; param) +tr_count_g_param(x, X::AbstractVector; param) +``` + + +Count the number of elements greater than `x[i] + param`. Extended method to vector with sig `(x, param)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L136-L143) + +
+
+
+# CompositionalNetworks.tr_count_g_rightMethod. + + + + +```julia +tr_count_g_right(i, x) +tr_count_g_right(x) +tr_count_g_right(x, X::AbstractVector) +``` + + +Count the number of elements to the right of and greater than `x[i]`. Extended method to vector with sig `(x)` are generated. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L91-L97) + +
+
+
+# CompositionalNetworks.tr_count_greaterMethod. + + + + +```julia +tr_count_greater(i, x) +tr_count_greater(x) +tr_count_greater(x, X::AbstractVector) +``` + + +Count the number of elements greater than `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L51-L58) + +
+
+
+# CompositionalNetworks.tr_count_l_leftMethod. + + + + +```julia +tr_count_l_left(i, x) +tr_count_l_left(x) +tr_count_l_left(x, X::AbstractVector) +``` + + +Count the number of elements to the left of and lesser than `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L81-L88) + +
+
+
+# CompositionalNetworks.tr_count_l_paramMethod. + + + + +```julia +tr_count_l_param(i, x; param) +tr_count_l_param(x; param) +tr_count_l_param(x, X::AbstractVector; param) +``` + + +Count the number of elements lesser than `x[i] + param`. Extended method to vector with sig `(x, param)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L126-L133) + +
+
+
+# CompositionalNetworks.tr_count_l_rightMethod. + + + + +```julia +tr_count_l_right(i, x) +tr_count_l_right(x) +tr_count_l_right(x, X::AbstractVector) +``` + + +Count the number of elements to the right of and lesser than `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L100-L107) + +
+
+
+# CompositionalNetworks.tr_count_lesserMethod. + + + + +```julia +tr_count_lesser(i, x) +tr_count_lesser(x) +tr_count_lesser(x, X::AbstractVector) +``` + + +Count the number of elements lesser than `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L61-L68) + +
+
+
+# CompositionalNetworks.tr_identityMethod. + + + + +```julia +tr_identity(i, x) +tr_identity(x) +tr_identity(x, X::AbstractVector) +``` + + +Identity function. Already defined in Julia as `identity`, specialized for vectors. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L3-L10) + +
+
+
+# CompositionalNetworks.tr_in_unrolled_expansion_##225Method. + + + + +```julia +tr_in(tr, X, x, param) +``` + + +Application of an operation from the transformation layer. Used to generate more efficient code for all compositions. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L86-L90) + +
+
+
+# CompositionalNetworks.tr_param_minus_valMethod. + + + + +```julia +tr_param_minus_val(i, x; param) +tr_param_minus_val(x; param) +tr_param_minus_val(x, X::AbstractVector; param) +``` + + +Return the difference `param - x[i]` if positive, `0.0` otherwise. Extended method to vector with sig `(x, param)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L176-L183) + +
+
+
+# CompositionalNetworks.tr_val_minus_paramMethod. + + + + +```julia +tr_val_minus_param(i, x; param) +tr_val_minus_param(x; param) +tr_val_minus_param(x, X::AbstractVector; param) +``` + + +Return the difference `x[i] - param` if positive, `0.0` otherwise. Extended method to vector with sig `(x, param)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L166-L173) + +
+
+
+# CompositionalNetworks.transformation_layerFunction. + + + + +```julia +transformation_layer(param = false) +``` + + +Generate the layer of transformations functions of the ICN. Iff `param` value is true, also includes all the parametric transformations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L298-L301) + +
+
+
+# CompositionalNetworks.weights!Method. + + + + +```julia +weights!(icn, weights) +``` + + +Set the weights of an ICN with a `BitVector`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L71-L74) + +
+
+
+# CompositionalNetworks.weightsMethod. + + + + +```julia +weights(icn) +``` + + +Access the current set of weights of an ICN. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L49-L52) + +
+
+
+# CompositionalNetworks.weights_biasMethod. + + + + +```julia +weights_bias(x) +``` + + +A metric that bias `x` towards operations with a lower bit. Do not affect the main metric. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/metrics.jl#L17-L20) + +
+
+
+# QUBOConstraints.AbstractOptimizerType. + + + + +```julia +AbstractOptimizer +``` + + +An abstract type (interface) used to learn QUBO matrices from constraints. Only a `train` method is required. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/learn.jl#L1-L5) + +
+
+
+# QUBOConstraints.QUBO_baseFunction. + + + + +```julia +QUBO_base(n, weight = 1) +``` + + +A basic QUBO matrix to ensure that binarized variables keep a valid encoding. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/base.jl#L1-L5) + +
+
+
+# QUBOConstraints.QUBO_linear_sumMethod. + + + + +```julia +QUBO_linear_sum(n, σ) +``` + + +One valid QUBO matrix given `n` variables and parameter `σ` for the linear sum constraint. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/handmade/linear_sum.jl#L1-L5) + +
+
+
+# QUBOConstraints.binarizeMethod. + + + + +```julia +binarize(x[, domain]; binarization = :one_hot) +``` + + +Binarize `x` following the `binarization` encoding. If `x` is a vector (instead of a number per say), `domain` is optional. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/encoding/conversion.jl#L12-L16) + +
+
+
+# QUBOConstraints.debinarizeMethod. + + + + +```julia +debinarize(x[, domain]; binarization = :one_hot) +``` + + +Transform a binary vector into a number or a set of number. If `domain` is not given, it will compute a default value based on `binarization` and `x`. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/encoding/conversion.jl#L35-L39) + +
+
+
+# QUBOConstraints.is_validFunction. + + + + +```julia +is_valid(x, encoding::Symbol = :none) +``` + + +Check if `x` has a valid format for `encoding`. + +For instance, if `encoding == :one_hot`, at most one bit of `x` can be set to 1. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/encoding/conversion.jl#L1-L7) + +
+
+
+# QUBOConstraints.trainMethod. + + + + +```julia +train(args...) +``` + + +Default `train` method for any AbstractOptimizer. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/learn.jl#L8-L12) + +
+
diff --git a/dev/.documenter/index-old.md b/dev/.documenter/index-old.md new file mode 100644 index 0000000..9186c45 --- /dev/null +++ b/dev/.documenter/index-old.md @@ -0,0 +1,54 @@ + +## JuliaConstraints + +JuliaConstraints is a collection of packages that help you solve constraint programming problems in Julia. Constraint programming involves modeling problems with constraints, such as "x > 5" or "x + y = 10", and finding solutions that satisfy all of the constraints. It is a part of the [JuMP ecosystem](https://jump.dev/) that focuses on constraint programming in Julia. + +The goal of packages in JuliaConstraints are two-fold: some of them provide a generic interface, others are solvers for CP models (either purely in Julia or wrapping). They make it easy to solve constraint-satisfaction problems (CSPs) and constraint-optimisation problems (COPs) in Julia using industry-standard solvers and mixed-integer solvers. +- [CBLS.jl](https://github.com/JuliaConstraints/CBLS.jl) is a high-level interface for CBLS solvers + +- [ConstraintProgrammingExtensions.jl](https://github.com/JuliaConstraints/ConstraintProgrammingExtensions.jl/) is a common low-level interface for CP solvers. + +- JuliaConstraints hosts several pure-Julia solvers: + +- JuliaConstraints provides wrappers for existing CP solvers: + - [Chuffed](https://github.com/JuliaConstraints/Chuffed.jl) + + - [CPLEX CP Optimizer](https://github.com/JuliaConstraints/CPLEXCP.jl) + + - [JaCoP](https://github.com/JuliaConstraints/JaCoP.jl) + + +- JuliaConstraints makes available packages to help write new CP solvers: + - [Constraints.jl](https://github.com/JuliaConstraints/Constraints.jl) supplies metadata about constraints + + - [ConstraintDomains.jl](https://github.com/JuliaConstraints/ConstraintDomains.jl) helps with storing the domain of variables + + - [LocalSearchSolvers.jl](https://github.com/JuliaConstraints/LocalSearchSolvers.jl) is a framework to build CBLS solvers + + +- JuliaConstraints holds repositories of CP models: + - [ConstraintModels.jl](https://github.com/JuliaConstraints/ConstraintModels.jl) + + + +Other packages for CP in Julia include: +- [ConstraintSolver.jl](https://github.com/Wikunia/ConstraintSolver.jl/), another pure-Julia CP solvers + +- [SeaPerl.jl](https://github.com/corail-research/SeaPearl.jl), a research CP solver implemented with reinforcement learning, in pure Julia + + +### Operational Research vs Constraint Programming {#Operational-Research-vs-Constraint-Programming} + +Operational research (OR) is a problem-solving approach that uses mathematical models, statistical analysis, and optimization techniques to help organizations make better decisions. OR is concerned with understanding and optimizing complex systems, such as supply chains, transportation networks, and manufacturing processes, to improve efficiency and reduce costs. + +On the other hand, constraint programming (CP) is a programming paradigm that focuses on solving problems with constraints. Constraints are conditions that must be satisfied for a solution to be valid. CP is often used to solve combinatorial problems, such as scheduling, routing, and allocation, where the search space of possible solutions is very large. + +So, while both OR and CP are concerned with solving complex problems, they approach the problem-solving process from different angles. OR typically uses mathematical models and optimization techniques to analyze and optimize existing systems, while CP focuses on finding valid solutions that satisfy a set of constraints. + +### Constraint-Based Local Search {#Constraint-Based-Local-Search} + +Constraint-based local search (CBLS) is a type of constraint programming solver that uses a heuristic search algorithm to find solutions to problems. It starts with an initial solution and tries to improve it by making small changes that satisfy the constraints. CBLS is especially useful for large and complex problems where finding an exact solution may take too much time or be impossible. + +In contrast, other constraint programming solvers use a variety of algorithms and techniques to find exact solutions to problems. These solvers try to find a solution that satisfies all of the constraints in the problem. They can be useful for smaller problems where finding an exact solution is feasible, or for problems that have a clear mathematical structure. + +In summary, CBLS is a type of constraint programming solver that uses a heuristic search algorithm to find good solutions, while other constraint programming solvers use various techniques to find exact solutions to problems. diff --git a/dev/.documenter/index.md b/dev/.documenter/index.md new file mode 100644 index 0000000..977d185 --- /dev/null +++ b/dev/.documenter/index.md @@ -0,0 +1,58 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: "Julia Constraints" + text: "Model Smoothly Decide Wisely" + tagline: A Toolkit for Constraint Programming + image: + src: /logo.png + alt: JuliaConstraints + actions: + - theme: brand + text: Constraint Programming ?! + link: /cp/intro + - theme: alt + text: View on Github + link: https://github.com/JuliaConstraints/JuliaConstraints.github.io + +features: + - icon: JuMP.jl + title: JuMP.jl + details: Model optimization problems via JuMP.jl! + link: "https://jump.dev/" + - icon: ToQUBO.jl + title: ToQUBO.jl + details: Convert and send optimization models to QUBO solvers! + link: "https://github.com/psrenergy/ToQUBO.jl" + - icon: Pluto.jl + title: Pluto.jl + details: Simple, reactive programming environment via Julia notebooks + link: "https://plutojl.org/" +--- + + +<p style="margin-bottom:2cm"></p> + +<div class="vp-doc" style="width:80%; margin:auto"> + +<h1>What is Julia Constraints? (chatGPTed atm)</h1> + +<p>The Julia Constraints organization is dedicated to advancing Constraint Programming within the Julia ecosystem, serving as a hub for resources that facilitate the creation, understanding, and solution of constraint programming problems. Our goal is to make Constraint Programming accessible and efficient for users at all levels of expertise, by providing a comprehensive suite of tools that integrate seamlessly with JuMP.jl, a popular Julia package for mathematical optimization.</p> + +<h2>Our offerings include:</h2> + +<h3>Core Packages:</h3> <p>A foundation of common packages (ConstraintCommons, ConstraintDomains, Constraints, ConstraintModels) that supply essential features for constraint programming, ensuring users have the basic tools necessary for their projects.</p> + +<h3>Learning and Translation Tools:</h3> <p>Advanced packages like CompositionalNetworks, QUBOConstraints, and ConstraintsTranslator bridge the gap between ease of modeling and computational efficiency. These tools learn from constraints and convert natural language problems into constraint programming solutions, requiring minimal input from the user beyond the model itself.</p> + +<h3>Solvers:</h3> <p>We provide a range of solvers, from native Julia solvers (LocalSearchSolvers) to interfaces with JuMP for external CP solvers, catering to various problem-solving needs.</p> + +<h3>MetaStrategist (Emerging Technology):</h3> <p>In its formative stages, MetaStrategist embodies our pioneering spirit. As a burgeoning meta-solving package, it aims to harness the strengths of CP and JuMP. Its vision is to formulate tailored strategies that consider the unique hardware and software resources at hand, offering a new horizon in problem-solving efficiency and adaptability.</p> + +<h3>Performance Checker (Community Resource):</h3> <p>PerfChecker.jl transcends its role within Julia Constraints, offering its capabilities to the broader Julia package ecosystem. This indispensable tool for cross-version performance checking not only safeguards the high efficiency and reliability of our packages but also serves the wider community. By facilitating clear and simple performance evaluations, PerfChecker.jl enhances both development and maintenance, contributing to the overall health and progress of Julia's growing library of resources.</p> + +<p>At Julia Constraints, our mission is to democratize Constraint Programming by providing robust, user-friendly tools that simplify the modeling process, enhance efficiency, and empower users to solve complex problems with ease.</p> + +</div> diff --git a/dev/.documenter/learning/aggregation.md b/dev/.documenter/learning/aggregation.md new file mode 100644 index 0000000..34359a2 --- /dev/null +++ b/dev/.documenter/learning/aggregation.md @@ -0,0 +1,64 @@ + +# Aggregation Layer {#Aggregation-Layer} + + + +Some text to describe the aggragation layer within usual ICNs. + +## List of aggregations {#List-of-aggregations} +
+# CompositionalNetworks.ag_sumFunction. + + + + +```julia +ag_sum(x) +``` + + +Aggregate through `+` a vector into a single scalar. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/aggregation.jl#L1-L4) + +
+
+
+# CompositionalNetworks.ag_count_positiveFunction. + + + + +```julia +ag_count_positive(x) +``` + + +Count the number of strictly positive elements of `x`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/aggregation.jl#L7-L10) + +
+
+ +## Layer generation {#Layer-generation} +
+# CompositionalNetworks.aggregation_layerFunction. + + + + +```julia +aggregation_layer() +``` + + +Generate the layer of aggregations of the ICN. The operations are mutually exclusive, that is only one will be selected. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/aggregation.jl#L13-L16) + +
+
diff --git a/dev/.documenter/learning/arithmetic.md b/dev/.documenter/learning/arithmetic.md new file mode 100644 index 0000000..114919b --- /dev/null +++ b/dev/.documenter/learning/arithmetic.md @@ -0,0 +1,64 @@ + +# Arithmetic Layer {#Arithmetic-Layer} + + + +Some text to describe the arithmetic layer within usual ICNs. + +## List of arithmetic operations {#List-of-arithmetic-operations} +
+# CompositionalNetworks.ar_sumFunction. + + + + +```julia +ar_sum(x) +``` + + +Reduce `k = length(x)` vectors through sum to a single vector. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/arithmetic.jl#L1-L4) + +
+
+
+# CompositionalNetworks.ar_prodFunction. + + + + +```julia +ar_prod(x) +``` + + +Reduce `k = length(x)` vectors through product to a single vector. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/arithmetic.jl#L7-L10) + +
+
+ +## Layer generation {#Layer-generation} +
+# CompositionalNetworks.arithmetic_layerFunction. + + + + +```julia +arithmetic_layer() +``` + + +Generate the layer of arithmetic operations of the ICN. The operations are mutually exclusive, that is only one will be selected. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/arithmetic.jl#L13-L16) + +
+
diff --git a/dev/.documenter/learning/comparison.md b/dev/.documenter/learning/comparison.md new file mode 100644 index 0000000..2c0152e --- /dev/null +++ b/dev/.documenter/learning/comparison.md @@ -0,0 +1,178 @@ + +# Comparison Layer {#Comparison-Layer} + + + +Some text to describe the comparison layer within usual ICNs. + +## List of comparisons {#List-of-comparisons} + +List the possible parameters and how it affects the comparison. + +### Non-parametric +
+# CompositionalNetworks.co_identityFunction. + + + + +```julia +co_identity(x) +``` + + +Identity function. Already defined in Julia as `identity`, specialized for scalars in the `comparison` layer. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L1-L4) + +
+
+ +::: warning Missing docstring. + +Missing docstring for `co_euclidian`. Check Documenter's build log for details. + +::: +
+# CompositionalNetworks.co_abs_diff_val_varsFunction. + + + + +```julia +co_abs_diff_val_vars(x; nvars) +``` + + +Return the absolute difference between `x` and the number of variables `nvars`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L41-L44) + +
+
+
+# CompositionalNetworks.co_val_minus_varsFunction. + + + + +```julia +co_val_minus_vars(x; nvars) +``` + + +Return the difference `x - nvars` if positive, `0.0` otherwise, where `nvars` denotes the numbers of variables. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L47-L50) + +
+
+
+# CompositionalNetworks.co_vars_minus_valFunction. + + + + +```julia +co_vars_minus_val(x; nvars) +``` + + +Return the difference `nvars - x` if positive, `0.0` otherwise, where `nvars` denotes the numbers of variables. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L54-L57) + +
+
+ +### Param: `:val` {#Param:-:val} +
+# CompositionalNetworks.co_abs_diff_val_paramFunction. + + + + +```julia +co_abs_diff_val_param(x; param) +``` + + +Return the absolute difference between `x` and `param`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L7-L10) + +
+
+
+# CompositionalNetworks.co_val_minus_paramFunction. + + + + +```julia +co_val_minus_param(x; param) +``` + + +Return the difference `x - param` if positive, `0.0` otherwise. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L13-L16) + +
+
+
+# CompositionalNetworks.co_param_minus_valFunction. + + + + +```julia +co_param_minus_val(x; param) +``` + + +Return the difference `param - x` if positive, `0.0` otherwise. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L19-L22) + +
+
+ +::: warning Missing docstring. + +Missing docstring for `co_euclidian_param`. Check Documenter's build log for details. + +::: + +### Layer generation {#Layer-generation} + +::: warning Missing docstring. + +Missing docstring for `make_comparisons`. Check Documenter's build log for details. + +::: +
+# CompositionalNetworks.comparison_layerFunction. + + + + +```julia +comparison_layer(param = false) +``` + + +Generate the layer of transformations functions of the ICN. Iff `param` value is set, also includes all the parametric comparison with that value. The operations are mutually exclusive, that is only one will be selected. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L85-L88) + +
+
diff --git a/dev/.documenter/learning/compositional_networks.md b/dev/.documenter/learning/compositional_networks.md new file mode 100644 index 0000000..0bbb57c --- /dev/null +++ b/dev/.documenter/learning/compositional_networks.md @@ -0,0 +1,180 @@ + +# CompositionalNetworks.jl + + + +Documentation for `CompositionalNetworks.jl`. + +## Utilities +
+# CompositionalNetworks.map_tr!Function. + + + + +```julia +map_tr!(f, x, X, param) +``` + + +Return an anonymous function that applies `f` to all elements of `x` and store the result in `X`, with a parameter `param` (which is set to `nothing` for function with no parameter). + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L1-L4) + +
+
+
+# CompositionalNetworks.lazyFunction. + + + + +```julia +lazy(funcs::Function...) +``` + + +Generate methods extended to a vector instead of one of its components. A function `f` should have the following signature: `f(i::Int, x::V)`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L22-L25) + +
+
+
+# CompositionalNetworks.lazy_paramFunction. + + + + +```julia +lazy_param(funcs::Function...) +``` + + +Generate methods extended to a vector instead of one of its components. A function `f` should have the following signature: `f(i::Int, x::V; param)`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L36-L39) + +
+
+
+# CompositionalNetworks.as_bitvectorFunction. + + + + +```julia +as_bitvector(n::Int, max_n::Int = n) +``` + + +Convert an Int to a BitVector of minimal size (relatively to `max_n`). + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L48-L51) + +
+
+
+# CompositionalNetworks.as_intFunction. + + + + +```julia +as_int(v::AbstractVector) +``` + + +Convert a `BitVector` into an `Int`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L65-L68) + +
+
+
+# CompositionalNetworks.reduce_symbolsFunction. + + + + +```julia +reduce_symbols(symbols, sep) +``` + + +Produce a formatted string that separates the symbols by `sep`. Used internally for `show_composition`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L77-L80) + +
+
+ +::: warning Missing docstring. + +Missing docstring for `CompositionalNeworks.tr_in`. Check Documenter's build log for details. + +::: + +## Metrics +
+# CompositionalNetworks.hammingFunction. + + + + +```julia +hamming(x, X) +``` + + +Compute the hamming distance of `x` over a collection of solutions `X`, i.e. the minimal number of variables to switch in `x`to reach a solution. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/metrics.jl#L1-L4) + +
+
+
+# CompositionalNetworks.minkowskiFunction. + + + + +```julia +minkowski(x, X, p) +``` + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/metrics.jl#L7-L9) + +
+
+
+# CompositionalNetworks.manhattanFunction. + + + + +```julia +manhattan(x, X) +``` + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/metrics.jl#L12-L14) + +
+
+ +::: warning Missing docstring. + +Missing docstring for `weigths_bias`. Check Documenter's build log for details. + +::: diff --git a/dev/.documenter/learning/constraint_learning.md b/dev/.documenter/learning/constraint_learning.md new file mode 100644 index 0000000..94c64a6 --- /dev/null +++ b/dev/.documenter/learning/constraint_learning.md @@ -0,0 +1,508 @@ + +# ConstraintLearning.jl + +Documentation for `ConstraintLearning.jl`. +
+# ConstraintLearning.ICNConfigType. + + + + +```julia +struct ICNConfig{O <: ICNOptimizer} +``` + + +A structure to hold the metric and optimizer configurations used in learning the weights of an ICN. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/base.jl#L8-L12) + +
+
+
+# ConstraintLearning.ICNConfigMethod. + + + + +```julia +ICNConfig(; metric = :hamming, optimizer = ICNGeneticOptimizer()) +``` + + +Constructor for `ICNConfig`. Defaults to hamming metric using a genetic algorithm. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/genetic.jl#L150-L154) + +
+
+
+# ConstraintLearning.ICNGeneticOptimizerMethod. + + + + +```julia +ICNGeneticOptimizer(; kargs...) +``` + + +Default constructor to learn an ICN through a Genetic Algorithm. Default `kargs` TBW. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/genetic.jl#L111-L115) + +
+
+
+# ConstraintLearning.ICNLocalSearchOptimizerType. + + + + +```julia +ICNLocalSearchOptimizer(options = LocalSearchSolvers.Options()) +``` + + +Default constructor to learn an ICN through a CBLS solver. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/cbls.jl#L1-L5) + +
+
+
+# ConstraintLearning.ICNOptimizerType. + + + + +```julia +const ICNOptimizer = CompositionalNetworks.AbstractOptimizer +``` + + +An abstract type for optmizers defined to learn ICNs. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/base.jl#L1-L5) + +
+
+
+# ConstraintLearning.QUBOGradientOptimizerMethod. + + + + +```julia +QUBOGradientOptimizer(; kargs...) +``` + + +A QUBO optimizer based on gradient descent. Defaults TBW + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/qubo/gradient.jl#L8-L12) + +
+
+
+# ConstraintLearning.QUBOOptimizerType. + + + + +```julia +const QUBOOptimizer = QUBOConstraints.AbstractOptimizer +``` + + +An abstract type for optimizers used to learn QUBO matrices from constraints. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/qubo/base.jl#L1-L5) + +
+
+
+# CompositionalNetworks.optimize!Method. + + + + +```julia +CompositionalNetworks.optimize!(icn, solutions, non_sltns, dom_size, metric, optimizer::ICNGeneticOptimizer; parameters...) +``` + + +Extends the `optimize!` method to `ICNGeneticOptimizer`. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/genetic.jl#L126-L130) + +
+
+
+# CompositionalNetworks.optimize!Method. + + + + +```julia +CompositionalNetworks.optimize!(icn, solutions, non_sltns, dom_size, metric, optimizer::ICNLocalSearchOptimizer; parameters...) +``` + + +Extends the `optimize!` method to `ICNLocalSearchOptimizer`. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/cbls.jl#L37-L41) + +
+
+
+# ConstraintLearning._optimize!Method. + + + + +```julia +_optimize!(icn, X, X_sols; metric = hamming, pop_size = 200) +``` + + +Optimize and set the weights of an ICN with a given set of configuration `X` and solutions `X_sols`. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/genetic.jl#L11-L14) + +
+
+
+# ConstraintLearning.domain_sizeMethod. + + + + +```julia +domain_size(ds::Number) +``` + + +Extends the domain_size function when `ds` is number (for dispatch purposes). + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/common.jl#L24-L28) + +
+
+
+# ConstraintLearning.generate_populationMethod. + + + + +```julia +generate_population(icn, pop_size +``` + + +Generate a pôpulation of weights (individuals) for the genetic algorithm weighting `icn`. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/genetic.jl#L1-L4) + +
+
+
+# ConstraintLearning.icnMethod. + + + + +```julia +icn(X,X̅; kargs..., parameters...) +``` + + +TBW + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn.jl#L1-L5) + +
+
+
+# ConstraintLearning.lossMethod. + + + + +```julia +loss(x, y, Q) +``` + + +Loss of the prediction given by `Q`, a training set `y`, and a given configuration `x`. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/qubo/gradient.jl#L29-L33) + +
+
+
+# ConstraintLearning.make_dfMethod. + + + + +```julia +make_df(X, Q, penalty, binarization, domains) +``` + + +DataFrame arrangement to output some basic evaluation of a matrix `Q`. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/qubo/gradient.jl#L36-L40) + +
+
+
+# ConstraintLearning.make_set_penaltyMethod. + + + + +```julia +make_set_penalty(X, X̅, args...; kargs) +``` + + +Return a penalty function when the training set is already split into a pair of solutions `X` and non solutions `X̅`. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/common.jl#L63-L67) + +
+
+
+# ConstraintLearning.make_training_setsMethod. + + + + +```julia +make_training_sets(X, penalty, args...) +``` + + +Return a pair of solutions and non solutions sets based on `X` and `penalty`. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/common.jl#L31-L35) + +
+
+
+# ConstraintLearning.mutually_exclusiveMethod. + + + + +```julia +mutually_exclusive(layer, w) +``` + + +Constraint ensuring that `w` encode exclusive operations in `layer`. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/cbls.jl#L12-L16) + +
+
+
+# ConstraintLearning.no_empty_layerMethod. + + + + +```julia +no_empty_layer(x; X = nothing) +``` + + +Constraint ensuring that at least one operation is selected. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/cbls.jl#L23-L27) + +
+
+
+# ConstraintLearning.optimize!Method. + + + + +```julia +optimize!(icn, X, X_sols, global_iter, local_iter; metric=hamming, popSize=100) +``` + + +Optimize and set the weights of an ICN with a given set of configuration `X` and solutions `X_sols`. The best weights among `global_iter` will be set. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/genetic.jl#L57-L60) + +
+
+
+# ConstraintLearning.parameter_specific_operationsMethod. + + + + +```julia +parameter_specific_operations(x; X = nothing) +``` + + +Constraint ensuring that at least one operation related to parameters is selected if the error function to be learned is parametric. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/icn/cbls.jl#L30-L34) + +
+
+
+# ConstraintLearning.predictMethod. + + + + +```julia +predict(x, Q) +``` + + +Return the predictions given by `Q` for a given configuration `x`. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/qubo/gradient.jl#L22-L26) + +
+
+
+# ConstraintLearning.preliminariesMethod. + + + + +```julia +preliminaries(args) +``` + + +Preliminaries to the training process in a `QUBOGradientOptimizer` run. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/qubo/gradient.jl#L77-L81) + +
+
+
+# ConstraintLearning.quboFunction. + + + + +```julia +qubo(X,X̅; kargs..., parameters...) +``` + + +TBW + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/qubo.jl#L1-L5) + +
+
+
+# ConstraintLearning.sub_eltypeMethod. + + + + +```julia +sub_eltype(X) +``` + + +Return the element type of of the first element of a collection. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/common.jl#L17-L21) + +
+
+
+# ConstraintLearning.train!Method. + + + + +```julia +train!(Q, X, penalty, η, precision, X_test, oversampling, binarization, domains) +``` + + +Training inner method. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/qubo/gradient.jl#L98-L102) + +
+
+
+# ConstraintLearning.trainMethod. + + + + +```julia +train(X, penalty[, d]; optimizer = QUBOGradientOptimizer(), X_test = X) +``` + + +Learn a QUBO matrix on training set `X` for a constraint defined by `penalty` with optional domain information `d`. By default, it uses a `QUBOGradientOptimizer` and `X` as a testing set. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/qubo/gradient.jl#L127-L131) + +
+
+
+# ConstraintLearning.δMethod. + + + + +```julia +δ(X[, Y]; discrete = true) +``` + + +Compute the extrema over a collection `X``or a pair of collection`(X, Y)`. + + +[source](https://github.com/JuliaConstraints/ConstraintLearning.jl/blob/v0.1.7/src/common.jl#L1-L5) + +
+
diff --git a/dev/.documenter/learning/intro.md b/dev/.documenter/learning/intro.md new file mode 100644 index 0000000..b5e853e --- /dev/null +++ b/dev/.documenter/learning/intro.md @@ -0,0 +1,4 @@ + +# Learning about Constraints {#Learning-about-Constraints} + +About learning constraints related matters. diff --git a/dev/.documenter/learning/layers.md b/dev/.documenter/learning/layers.md new file mode 100644 index 0000000..e9875fa --- /dev/null +++ b/dev/.documenter/learning/layers.md @@ -0,0 +1,215 @@ + +# A layer structure for any ICN {#A-layer-structure-for-any-ICN} + + + +The `layer.jl` file defines a `Layer` structure and several associated functions for manipulating and interacting with this structure in the context of an Interpretable Compositional Network (ICN). + +The `Layer` structure is used to store a `LittleDict` of operations that can be selected during the learning phase of an ICN. Each layer can be exclusive, meaning only one operation can be selected at a time. This is particularly useful in the context of ICNs, which are used to learn alternative expressions for highly combinatorial functions, such as those found in Constraint-based Local Search solvers. +
+# CompositionalNetworks.LayerType. + + + + +```julia +Layer +``` + + +A structure to store a `LittleDict` of operations that can be selected during the learning phase of an ICN. If the layer is exclusive, only one operation can be selected at a time. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L1-L4) + +
+
+
+# CompositionalNetworks.functionsFunction. + + + + +```julia +functions(layer) +``` + + +Access the operations of a layer. The container is ordered. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L11-L14) + +
+
+
+# Base.lengthMethod. + + + + +```julia +length(layer) +``` + + +Return the number of operations in a layer. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L17-L20) + +
+
+
+# CompositionalNetworks.excluFunction. + + + + +```julia +exclu(layer) +``` + + +Return `true` if the layer has mutually exclusive operations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L23-L26) + +
+
+
+# CompositionalNetworks.symbolFunction. + + + + +```julia +symbol(layer, i) +``` + + +Return the i-th symbols of the operations in a given layer. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L29-L32) + +
+
+
+# CompositionalNetworks.nbits_excluFunction. + + + + +```julia +nbits_exclu(layer) +``` + + +Convert the length of an exclusive layer into a number of bits. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L35-L38) + +
+
+
+# CompositionalNetworks.show_layerFunction. + + + + +```julia +show_layer(layer) +``` + + +Return a string that contains the elements in a layer. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L41-L44) + +
+
+
+# CompositionalNetworks.selected_sizeFunction. + + + + +```julia +selected_size(layer, layer_weights) +``` + + +Return the number of operations selected by `layer_weights` in `layer`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L47-L50) + +
+
+
+# CompositionalNetworks.is_viableFunction. + + + + +```julia +is_viable(layer, w) +is_viable(icn) +is_viable(icn, w) +``` + + +Assert if a pair of layer/icn and weights compose a viable pattern. If no weights are given with an icn, it will check the current internal value. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L53-L58) + +
+
+
+# CompositionalNetworks.generate_inclusive_operationsFunction. + + + + +```julia +generate_inclusive_operations(predicate, bits) +generate_exclusive_operation(max_op_number) +``` + + +Generates the operations (weights) of a layer with inclusive/exclusive operations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L61-L65) + +
+
+
+# CompositionalNetworks.generate_exclusive_operationFunction. + + + + +```julia +generate_exclusive_operation(max_op_number) +``` + + +Generates the operations (weigths) of a layer with exclusive operations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layer.jl#L75-L78) + +
+
+ +::: warning Missing docstring. + +Missing docstring for `generate_weigths`. Check Documenter's build log for details. + +::: diff --git a/dev/.documenter/learning/qubo_constraints.md b/dev/.documenter/learning/qubo_constraints.md new file mode 100644 index 0000000..178fffe --- /dev/null +++ b/dev/.documenter/learning/qubo_constraints.md @@ -0,0 +1,44 @@ + +# Introduction to QUBOConstraints.jl {#Introduction-to-QUBOConstraints.jl} + +Introduction to `QUBOConstraints.jl`. + + + +## Basic features {#Basic-features} +
+# QUBOConstraints.QUBO_baseFunction. + + + + +```julia +QUBO_base(n, weight = 1) +``` + + +A basic QUBO matrix to ensure that binarized variables keep a valid encoding. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/base.jl#L1-L5) + +
+
+
+# QUBOConstraints.QUBO_linear_sumFunction. + + + + +```julia +QUBO_linear_sum(n, σ) +``` + + +One valid QUBO matrix given `n` variables and parameter `σ` for the linear sum constraint. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/handmade/linear_sum.jl#L1-L5) + +
+
diff --git a/dev/.documenter/learning/qubo_encoding.md b/dev/.documenter/learning/qubo_encoding.md new file mode 100644 index 0000000..49b3c19 --- /dev/null +++ b/dev/.documenter/learning/qubo_encoding.md @@ -0,0 +1,60 @@ + +# Encoding for QUBO programs {#Encoding-for-QUBO-programs} + + +
+# QUBOConstraints.is_validFunction. + + + + +```julia +is_valid(x, encoding::Symbol = :none) +``` + + +Check if `x` has a valid format for `encoding`. + +For instance, if `encoding == :one_hot`, at most one bit of `x` can be set to 1. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/encoding/conversion.jl#L1-L7) + +
+
+
+# QUBOConstraints.binarizeFunction. + + + + +```julia +binarize(x[, domain]; binarization = :one_hot) +``` + + +Binarize `x` following the `binarization` encoding. If `x` is a vector (instead of a number per say), `domain` is optional. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/encoding/conversion.jl#L12-L16) + +
+
+
+# QUBOConstraints.debinarizeFunction. + + + + +```julia +debinarize(x[, domain]; binarization = :one_hot) +``` + + +Transform a binary vector into a number or a set of number. If `domain` is not given, it will compute a default value based on `binarization` and `x`. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/encoding/conversion.jl#L35-L39) + +
+
diff --git a/dev/.documenter/learning/qubo_learning.md b/dev/.documenter/learning/qubo_learning.md new file mode 100644 index 0000000..b6bd1f9 --- /dev/null +++ b/dev/.documenter/learning/qubo_learning.md @@ -0,0 +1,171 @@ + +# Learning QUBO matrices {#Learning-QUBO-matrices} + + + +## Interface +
+# QUBOConstraints.AbstractOptimizerType. + + + + +```julia +AbstractOptimizer +``` + + +An abstract type (interface) used to learn QUBO matrices from constraints. Only a `train` method is required. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/learn.jl#L1-L5) + +
+
+
+# QUBOConstraints.trainFunction. + + + + +```julia +train(args...) +``` + + +Default `train` method for any AbstractOptimizer. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/learn.jl#L8-L12) + +
+
+ +## Examples with various optimizers {#Examples-with-various-optimizers} + +### Gradient Descent {#Gradient-Descent} + +```julia +struct GradientDescentOptimizer <: QUBOConstraints.AbstractOptimizer + binarization::Symbol + η::Float64 + precision::Int + oversampling::Bool +end + +function GradientDescentOptimizer(; + binarization = :one_hot, + η = .001, + precision = 5, + oversampling = false, +) + return GradientDescentOptimizer(binarization, η, precision, oversampling) +end + + +predict(x, Q) = transpose(x) * Q * x + +loss(x, y, Q) = (predict(x, Q) .-y).^2 + +function make_df(X, Q, penalty, binarization, domains) + df = DataFrame() + for (i,x) in enumerate(X) + if i == 1 + df = DataFrame(transpose(x), :auto) + else + push!(df, transpose(x)) + end + end + + dim = length(df[1,:]) + + if binarization == :none + df[!,:penalty] = map(r -> penalty(Vector(r)), eachrow(df)) + df[!,:predict] = map(r -> predict(Vector(r), Q), eachrow(df[:, 1:dim])) + else + df[!,:penalty] = map( + r -> penalty(binarize(Vector(r), domains; binarization)), + eachrow(df) + ) + df[!,:predict] = map( + r -> predict(binarize(Vector(r), domains; binarization), Q), + eachrow(df[:, 1:dim]) + ) + end + + min_false = minimum( + filter(:penalty => >(minimum(df[:,:penalty])), df)[:,:predict]; + init = typemax(Int) + ) + df[!,:shifted] = df[:,:predict] .- min_false + df[!,:accurate] = df[:, :penalty] .* df[:,:shifted] .≥ 0. + + return df +end + +function preliminaries(X, domains, binarization) + if binarization==:none + n = length(first(X)) + return X, zeros(n,n) + else + Y = map(x -> collect(binarize(x, domains; binarization)), X) + n = length(first(Y)) + return Y, zeros(n,n) + end +end + +function preliminaries(X, _) + n = length(first(X)) + return X, zeros(n,n) +end + +function train!(Q, X, penalty, η, precision, X_test, oversampling, binarization, domains) + θ = params(Q) + try + penalty(first(X)) + catch e + if isa(e, UndefKeywordError) + penalty = (x; dom_size = δ_extrema(Iterators.flatten(X)))-> penalty(x; dom_size) + else + throw(e) + end + end + for x in (oversampling ? oversample(X, penalty) : X) + grads = gradient(() -> loss(x, penalty(x), Q), θ) + Q .-= η * grads[Q] + end + + Q[:,:] = round.(precision*Q) + + df = make_df(X_test, Q, penalty, binarization, domains) + return pretty_table(describe(df[!, [:penalty, :predict, :shifted, :accurate]])) +end + +function train( + X, + penalty, + domains::Vector{D}; + optimizer = GradientDescentOptimizer(), + X_test = X, +) where {D <: DiscreteDomain} + Y, Q = preliminaries(X, domains, optimizer.binarization) + train!( + Q, Y, penalty, optimizer.η, optimizer.precision, X_test, + optimizer.oversampling, optimizer.binarization, domains + ) + return Q +end + +function train( + X, + penalty, + dom_stuff = nothing; + optimizer = GradientDescentOptimizer(), + X_test = X, +) + return train(X, penalty, to_domains(X, dom_stuff); optimizer, X_test) +end +``` + + +### Constraint-based Local Search {#Constraint-based-Local-Search} diff --git a/dev/.documenter/learning/transformation.md b/dev/.documenter/learning/transformation.md new file mode 100644 index 0000000..8276b65 --- /dev/null +++ b/dev/.documenter/learning/transformation.md @@ -0,0 +1,443 @@ + +# Transformations Layer {#Transformations-Layer} + + + +Some text to describe the transformation layer within usual ICNs. + +The implementation of the transformation relies heavily on the use of the lazy function (make a ref, open an issue to make `@lazy` macro in front of each transformation). + +## List of transformations {#List-of-transformations} + +List the possible parameters and how it affects the transformations. + +### Non-parametric +
+# CompositionalNetworks.tr_identityFunction. + + + + +```julia +tr_identity(i, x) +tr_identity(x) +tr_identity(x, X::AbstractVector) +``` + + +Identity function. Already defined in Julia as `identity`, specialized for vectors. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L3-L10) + +
+
+
+# CompositionalNetworks.tr_count_eqFunction. + + + + +```julia +tr_count_eq(i, x) +tr_count_eq(x) +tr_count_eq(x, X::AbstractVector) +``` + + +Count the number of elements equal to `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L16-L23) + +
+
+
+# CompositionalNetworks.tr_count_eq_rightFunction. + + + + +```julia +tr_count_eq_right(i, x) +tr_count_eq_right(x) +tr_count_eq_right(x, X::AbstractVector) +``` + + +Count the number of elements to the right of and equal to `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L26-L33) + +
+
+
+# CompositionalNetworks.tr_count_eq_leftFunction. + + + + +```julia +tr_count_eq_left(i, x) +tr_count_eq_left(x) +tr_count_eq_left(x, X::AbstractVector) +``` + + +Count the number of elements to the left of and equal to `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L36-L43) + +
+
+
+# CompositionalNetworks.tr_count_greaterFunction. + + + + +```julia +tr_count_greater(i, x) +tr_count_greater(x) +tr_count_greater(x, X::AbstractVector) +``` + + +Count the number of elements greater than `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L51-L58) + +
+
+
+# CompositionalNetworks.tr_count_lesserFunction. + + + + +```julia +tr_count_lesser(i, x) +tr_count_lesser(x) +tr_count_lesser(x, X::AbstractVector) +``` + + +Count the number of elements lesser than `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L61-L68) + +
+
+
+# CompositionalNetworks.tr_count_g_leftFunction. + + + + +```julia +tr_count_g_left(i, x) +tr_count_g_left(x) +tr_count_g_left(x, X::AbstractVector) +``` + + +Count the number of elements to the left of and greater than `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L71-L78) + +
+
+
+# CompositionalNetworks.tr_count_g_rightFunction. + + + + +```julia +tr_count_g_right(i, x) +tr_count_g_right(x) +tr_count_g_right(x, X::AbstractVector) +``` + + +Count the number of elements to the right of and greater than `x[i]`. Extended method to vector with sig `(x)` are generated. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L91-L97) + +
+
+
+# CompositionalNetworks.tr_count_l_rightFunction. + + + + +```julia +tr_count_l_right(i, x) +tr_count_l_right(x) +tr_count_l_right(x, X::AbstractVector) +``` + + +Count the number of elements to the right of and lesser than `x[i]`. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L100-L107) + +
+
+
+# CompositionalNetworks.tr_contiguous_vals_minusFunction. + + + + +```julia +tr_contiguous_vals_minus(i, x) +tr_contiguous_vals_minus(x) +tr_contiguous_vals_minus(x, X::AbstractVector) +``` + + +Return the difference `x[i] - x[i + 1]` if positive, `0.0` otherwise. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L190-L197) + +
+
+
+# CompositionalNetworks.tr_contiguous_vals_minus_revFunction. + + + + +```julia +tr_contiguous_vals_minus_rev(i, x) +tr_contiguous_vals_minus_rev(x) +tr_contiguous_vals_minus_rev(x, X::AbstractVector) +``` + + +Return the difference `x[i + 1] - x[i]` if positive, `0.0` otherwise. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L201-L208) + +
+
+ +### Param: `:val` {#Param:-:val} +
+# CompositionalNetworks.tr_count_eq_paramFunction. + + + + +```julia +tr_count_eq_param(i, x; param) +tr_count_eq_param(x; param) +tr_count_eq_param(x, X::AbstractVector; param) +``` + + +Count the number of elements equal to `x[i] + param`. Extended method to vector with sig `(x, param)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L116-L123) + +
+
+
+# CompositionalNetworks.tr_count_l_paramFunction. + + + + +```julia +tr_count_l_param(i, x; param) +tr_count_l_param(x; param) +tr_count_l_param(x, X::AbstractVector; param) +``` + + +Count the number of elements lesser than `x[i] + param`. Extended method to vector with sig `(x, param)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L126-L133) + +
+
+
+# CompositionalNetworks.tr_count_g_paramFunction. + + + + +```julia +tr_count_g_param(i, x; param) +tr_count_g_param(x; param) +tr_count_g_param(x, X::AbstractVector; param) +``` + + +Count the number of elements greater than `x[i] + param`. Extended method to vector with sig `(x, param)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L136-L143) + +
+
+
+# CompositionalNetworks.tr_count_bounding_paramFunction. + + + + +```julia +tr_count_bounding_param(i, x; param) +tr_count_bounding_param(x; param) +tr_count_bounding_param(x, X::AbstractVector; param) +``` + + +Count the number of elements bounded (not strictly) by `x[i]` and `x[i] + param`. An extended method to vector with sig `(x, param)` is generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L151-L158) + +
+
+
+# CompositionalNetworks.tr_val_minus_paramFunction. + + + + +```julia +tr_val_minus_param(i, x; param) +tr_val_minus_param(x; param) +tr_val_minus_param(x, X::AbstractVector; param) +``` + + +Return the difference `x[i] - param` if positive, `0.0` otherwise. Extended method to vector with sig `(x, param)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L166-L173) + +
+
+
+# CompositionalNetworks.tr_param_minus_valFunction. + + + + +```julia +tr_param_minus_val(i, x; param) +tr_param_minus_val(x; param) +tr_param_minus_val(x, X::AbstractVector; param) +``` + + +Return the difference `param - x[i]` if positive, `0.0` otherwise. Extended method to vector with sig `(x, param)` are generated. When `X` is provided, the result is computed without allocations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L176-L183) + +
+
+ +### Layer generation {#Layer-generation} +
+# CompositionalNetworks.make_transformationsFunction. + + + + +```julia +make_transformations(param::Symbol) +``` + + +Generates a dictionary of transformation functions based on the specified parameterization. This function facilitates the creation of parametric layers for constraint transformations, allowing for flexible and dynamic constraint manipulation according to the needs of different constraint programming models. + +**Parameters** +- `param::Symbol`: Specifies the type of transformations to generate. It can be `:none` for basic transformations that do not depend on external parameters, or `:val` for transformations that operate with respect to a specific value parameter. + + +**Returns** +- `LittleDict{Symbol, Function}`: A dictionary mapping transformation names (`Symbol`) to their corresponding functions (`Function`). The functions encapsulate various types of transformations, such as counting, comparison, and contiguous value processing. + + +**Transformation Types** +- When `param` is `:none`, the following transformations are available: + - `:identity`: No transformation is applied. + + - `:count_eq`, `:count_eq_left`, `:count_eq_right`: Count equalities under different conditions. + + - `:count_greater`, `:count_lesser`: Count values greater or lesser than a threshold. + + - `:count_g_left`, `:count_l_left`, `:count_g_right`, `:count_l_right`: Count values with greater or lesser comparisons from different directions. + + - `:contiguous_vals_minus`, `:contiguous_vals_minus_rev`: Process contiguous values with subtraction in normal and reverse order. + + +- When `param` is `:val`, the transformations relate to operations involving a parameter value: + - `:count_eq_param`, `:count_l_param`, `:count_g_param`: Count equalities or comparisons against a parameter value. + + - `:count_bounding_param`: Count values bounding a parameter value. + + - `:val_minus_param`, `:param_minus_val`: Subtract a parameter value from values or vice versa. + + + +The function delegates to a version that uses `Val(param)` for dispatch, ensuring compile-time selection of the appropriate transformation set. + +**Examples** + +```julia +# Get basic transformations +basic_transforms = make_transformations(:none) + +# Apply an identity transformation +identity_result = basic_transforms[:identity](data) + +# Get value-based transformations +val_transforms = make_transformations(:val) + +# Apply a count equal to parameter transformation +count_eq_param_result = val_transforms[:count_eq_param](data, param) +``` + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L216-L262) + +
+
+
+# CompositionalNetworks.transformation_layerFunction. + + + + +```julia +transformation_layer(param = false) +``` + + +Generate the layer of transformations functions of the ICN. Iff `param` value is true, also includes all the parametric transformations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L298-L301) + +
+
diff --git a/dev/.documenter/meta/meta_strategist.md b/dev/.documenter/meta/meta_strategist.md new file mode 100644 index 0000000..bf12eab --- /dev/null +++ b/dev/.documenter/meta/meta_strategist.md @@ -0,0 +1,4 @@ + +# MetaStrategist.jl + +Documentation for `MetaStrategist.jl`. diff --git a/dev/.documenter/perf/api.md b/dev/.documenter/perf/api.md new file mode 100644 index 0000000..585274d --- /dev/null +++ b/dev/.documenter/perf/api.md @@ -0,0 +1,178 @@ + +# API + +Here's the API for PerfChecker.jl +
+# PerfChecker.arrange_breakingMethod. + + + + +Outputs the last breaking or next breaking version. + + +[source](https://github.com/JuliaConstraints/PerfChecker.jl/blob/v0.2.1/src/versions.jl#L56-L58) + +
+
+
+# PerfChecker.arrange_majorMethod. + + + + +Outputs the earlier or next major version. + + +[source](https://github.com/JuliaConstraints/PerfChecker.jl/blob/v0.2.1/src/versions.jl#L67-L69) + +
+
+
+# PerfChecker.arrange_patchesMethod. + + + + +Outputs the last patch or first patch of a version. + + +[source](https://github.com/JuliaConstraints/PerfChecker.jl/blob/v0.2.1/src/versions.jl#L35-L37) + +
+
+
+# PerfChecker.checkres_to_boxplotsFunction. + + + + +General Usage: Takes the output of a check macro, and creates a boxplot. + + +[source](https://github.com/JuliaConstraints/PerfChecker.jl/blob/v0.2.1/src/check.jl#L192-L195) + +
+
+
+# PerfChecker.checkres_to_pieFunction. + + + + +General Usage: Takes the output of a check macro as input, and creates a pie plot. Uses `table_to_pie` internally. + + +[source](https://github.com/JuliaConstraints/PerfChecker.jl/blob/v0.2.1/src/check.jl#L184-L187) + +
+
+
+# PerfChecker.checkres_to_scatterlinesFunction. + + + + +General Usage: Takes the output of a check macro as input, and creates a scatterlines plot. + + +[source](https://github.com/JuliaConstraints/PerfChecker.jl/blob/v0.2.1/src/check.jl#L178-L181) + +
+
+
+# PerfChecker.find_by_tagsMethod. + + + + +Usage: (Assuming you ran the 'Basic Example') + +``` +julia> find_by_tags([:example, :nice, :great], res) +``` + + + +[source](https://github.com/JuliaConstraints/PerfChecker.jl/blob/v0.2.1/src/checker_results.jl#L28-L34) + +
+
+
+# PerfChecker.get_pkg_versionsFunction. + + + + +Finds all versions of a package in all the installed registries and returns it as a vector. + +Example: + +```julia +julia> get_pkg_versions("ConstraintLearning") +7-element Vector{VersionNumber}: + v"0.1.4" + v"0.1.5" + v"0.1.0" + v"0.1.6" + v"0.1.1" + v"0.1.3" + v"0.1.2" +``` + + + +[source](https://github.com/JuliaConstraints/PerfChecker.jl/blob/v0.2.1/src/versions.jl#L1-L17) + +
+
+
+# PerfChecker.table_to_pieFunction. + + + + +General Usage: Takes a table generated via the check macro as input, and creates a pie plot. + + +[source](https://github.com/JuliaConstraints/PerfChecker.jl/blob/v0.2.1/src/check.jl#L172-L175) + +
+
+
+# PerfChecker.to_tableFunction. + + + + +General Usage: Returns a table from the output of the results of respective backends + + +[source](https://github.com/JuliaConstraints/PerfChecker.jl/blob/v0.2.1/src/check.jl#L198-L201) + +
+
+
+# PerfChecker.@checkMacro. + + + + +General usage: + +```julia +@check :name_of_backend config_dictionary begin + # the prelimnary code +end begin + # the actual code you want to do perf testing for +end +``` + + +Outputs a `CheckerResult` which can be used with other functions. + + +[source](https://github.com/JuliaConstraints/PerfChecker.jl/blob/v0.2.1/src/check.jl#L148-L158) + +
+
diff --git a/dev/.documenter/perf/benchmark_ext.md b/dev/.documenter/perf/benchmark_ext.md new file mode 100644 index 0000000..29fd4f2 --- /dev/null +++ b/dev/.documenter/perf/benchmark_ext.md @@ -0,0 +1,39 @@ + +# BenchmarkTools Extension {#BenchmarkTools-Extension} + +A benchmarking extension, based on `BenchmarkTools.jl`, has been interfaced with `PerfChecker.jl`. This section will provide some usage examples, documentation, and links to related notebooks. + +## Usage + +Like all other extensions, `BenchmarkTools` extension can be used in the following way: + +```julia +julia> using BenchmarkTools, PerfChecker + +julia> @check :benchmark Dict(:option1 => "value1", :option2 => "value2", :PATH => @__DIR__) begin + # the prelimnary code goes here + using Example +end begin + # the code you want to be benchmarked + Example.domath(10) # returns x + 5, 15 in this case. +end +``` + + +## Options + +Options specific to this backend with their default values are defined as: + +```julia +:threads => 1 +:track => "none" +:samples => BenchmarkTools.DEFAULT_PARAMETERS.samples +:seconds => BenchmarkTools.DEFAULT_PARAMETERS.seconds +:evals => BenchmarkTools.DEFAULT_PARAMETERS.evals +:overhead => BenchmarkTools.DEFAULT_PARAMETERS.overhead +:gctrial => BenchmarkTools.DEFAULT_PARAMETERS.gctrial +:gcsample => BenchmarkTools.DEFAULT_PARAMETERS.gcsample +:time_tolerance => BenchmarkTools.DEFAULT_PARAMETERS.time_tolerance +:memory_tolerance => BenchmarkTools.DEFAULT_PARAMETERS.memory_tolerance +``` + diff --git a/dev/.documenter/perf/chairmarks_ext.md b/dev/.documenter/perf/chairmarks_ext.md new file mode 100644 index 0000000..2f39f82 --- /dev/null +++ b/dev/.documenter/perf/chairmarks_ext.md @@ -0,0 +1,35 @@ + +# Chairmarks Extension {#Chairmarks-Extension} + +A benchmarking extension, based on `Chairmarks.jl`, has been interfaced with `PerfChecker.jl`. This section will provide some usage examples, documentation, and links to related notebooks. + +## Usage + +Like all other extensions, `BenchmarkTools` extension can be used in the following way: + +```julia +julia> using Chairmarks, PerfChecker + +julia> @check :chairmark Dict(:option1 => "value1", :option2 => "value2", :PATH => @__DIR__) begin + # the prelimnary code goes here + using Example +end begin + # the code you want to be benchmarked + Example.domath(10) # returns x + 5, 15 in this case. +end +``` + + +## Options + +Options specific to this backend with their default values are defined as: + +```julia +:threads => 1 +:track => "none" +:evals => nothing +:seconds => 1, +:samples => nothing +:gc => true +``` + diff --git a/dev/.documenter/perf/perf_checker.md b/dev/.documenter/perf/perf_checker.md new file mode 100644 index 0000000..e7fe938 --- /dev/null +++ b/dev/.documenter/perf/perf_checker.md @@ -0,0 +1,65 @@ + +# PerfChecker.jl + +PerfChecker.jl is a package designed for package authors to easily performance test their packages. To achieve that, it provides the follwing features: +- The main macro `@check`, which provides an easy-to-use interface over various interfaces, configurable for various backends via a dictionary. + +- (WIP) A CI for reproducible performance testing. + +- Visualization of different metrics from `@check` using Makie.jl + + +## Usage + +The primary usage of PerfChecker.jl looks like this: + +```julia + using PerfChecker + # optional using custom backend like BenchmarkTools, Chairmark etc + config = Dict(:option1 => "value1", :option2 => :value2) + + results = @check :name_of_backend config begin + # preparatory code goes here + end begin + # the code block to be performance tested goes here + end + + # Visualization of the results + using Makie + checkres_to_scatterlines(results) +``` + + +The config dictionary can take many options, depending on the backend. + +Some of the commonly used options are: +- `:PATH` => The path where to the default environment of julia when creating a new process. + +- `:pkgs` => A list of versions to test performance for. Its defined as the `Tuple`, `(name::String, option::Symbol, versions::Vector{VersionNumber}, last_or_first::Bool)` Can be given as follows: + - `name` is the name of the package. + + - `option` is one of the 5 symbols: + - `:patches`: last patch or first patch of a version + + - `:breaking`: last breaking or next breaking version + + - `:major`: previous or next major version + + - `:minor`: previous or next minor version + + - `:custom`: custom version numbers (provide any boolean value for `last_or_first` in this case as it doesn't matter) + + + - `versions`: The input for the provided `option` + + - `last_or_first`: Input for the provided `option` + + +- `:tags` => A list of tags (a vector of symbols) to easily tag performance tests. + +- `:devops` => Giving a custom input to `Pkg.develop`. Intended to be used to test performance of a local development branch of a pacakge with previous versions. Often can be used as simply as `:devops => "MyPackageName"` + +- `:threads` => An integer to select the number of threads to start Julia with. + + +Checkout the documentation of the other backends for more default options and the default values. diff --git a/dev/.documenter/perf/perf_interface.md b/dev/.documenter/perf/perf_interface.md new file mode 100644 index 0000000..9af3dc2 --- /dev/null +++ b/dev/.documenter/perf/perf_interface.md @@ -0,0 +1,118 @@ + +# Extending PerfChecker {#Extending-PerfChecker} + +PerfChecker was build as an easy to extend interface. A good reference example for this is the Chairmarks extension. + +Extending PerfChecker works via PkgExtensions feature in Julia. There are 6 essential functions that need to be extended inside the Pkg extension. Each extension has a keyword symbol for it, which users can input to use the extension. + +## The Default Options {#The-Default-Options} + +Method to be overloaded: `PerfChecker.default_options(::Val{:myperfextension})::Dict` + +PerfChecker works via a config dictionary. Users can populate this dictionary with options and provide it to the main `check` macro to customize the performance testing to their liking. + +For Chairmarks.jl, it looks like this: + +```julia +function PerfChecker.default_options(::Val{:chairmark}) + return Dict( + :threads => 1, + :track => "none", + :evals => nothing, + :seconds => 1, + :samples => nothing, + :gc => true + ) +end +``` + + +## Package initialization {#Package-initialization} + +Method to be overloaded: `PerfChecker.initpkgs(::Val{:myperfextension})::Expr` + +This method is plainly to load the main package(s) associated with the custom backend. In case of Chairmarks.jl, it looks like this: + +```julia +PerfChecker.initpkgs(::Val{:chairmark}) = quote + using Chairmarks +end +``` + + +## Preparatory Code: {#Preparatory-Code:} + +Method to be overloaded: `PerfChecker.prep(config_dict::Dict, block::Expr, ::Val{:myperfextension})::Expr` + +This method exists to run arbitrary "preparatory" code (represented by `block` parameter here) before running the code to be performance tested for. + +The output from here are stored inside the `:prep_result` key of the configuration dictionary. + +Example for Chairmarks.jl: + +```julia +PerfChecker.prep(::Dict, block::Expr, ::Val{:chairmark}) = quote + $block + nothing +end +``` + + +This just runs the code in `block` provided by the user. + +## Main Code to be Performance Tested {#Main-Code-to-be-Performance-Tested} + +Method to be overloaded: `PerfChecker.check(config_dict::Dict, block::Expr, ::Val{:myperfextension})::Expr`. + +Runs the appropriate code to run the performance testing on user's code. For Chairmarks.jl, it looks like this: + +```julia +function PerfChecker.check(d::Dict, block::Expr, ::Val{:chairmark}) + quote + d = $d + return @be $block evals=d[:evals] seconds=d[:seconds] samples=d[:samples] gc=d[:gc] + end +end +``` + + +The output from here are stored inside the `:check_result` key of the configuration dictionary. + +## Post Performance Testing Code {#Post-Performance-Testing-Code} + +Method to be overloaded: `PerfChecker.post(config_dict::Dict, ::Val{:myperfextension})` + +The code to be run after the performance testing is done. The output from here is converted into a table via the `to_table` method overloading. + +In the case of Chairmarks.jl: + +```julia +PerfChecker.post(d::Dict, ::Val{:chairmark}) = d[:check_result] +``` + + +## Converting the result into a Table {#Converting-the-result-into-a-Table} + +Method to be overloaded: `PerfChecker.to_table` + +Convert the output from `post` function into an appropriate table. + +In the case of Chairmarks.jl + +```julia +function PerfChecker.to_table(chair::Chairmarks.Benchmark) + l = length(chair.samples) + times = [chair.samples[i].time for i in 1:l] + gctimes = [chair.samples[i].gc_fraction for i in 1:l] + bytes = [chair.samples[i].bytes for i in 1:l] + allocs = [chair.samples[i].allocs for i in 1:l] + return Table(times = times, gctimes = gctimes, bytes = bytes, allocs = allocs) +end +``` + + + +--- + + +There are also other functions that can be overloaded, mostly related to plotting but these are the basic functions to extend PerfChecker for a custom backend. diff --git a/dev/.documenter/perf/tutorial.md b/dev/.documenter/perf/tutorial.md new file mode 100644 index 0000000..73c4a2a --- /dev/null +++ b/dev/.documenter/perf/tutorial.md @@ -0,0 +1,71 @@ + +# Tutorial + +Taken from PerfChecker.jl examples, this is a guide for performance testing of PatterFolds.jl package using Chairmarks.jl + +Using PerfChecker.jl requires an environment with the dependencies present in it. + +The actual script looks like this: + +```julia +using PerfChecker, Chairmarks, CairoMakie + +d = Dict(:path => @__DIR__, :evals => 10, :samples => 1000, + :seconds => 100, :tags => [:patterns, :intervals], + :pkgs => ( + "PatternFolds", :custom, [v"0.2.0", v"0.2.1", v"0.2.2", v"0.2.3", v"0.2.4"], true), + :devops => "PatternFolds") + +x = @check :chairmark d begin + using PatternFolds +end begin + # Intervals + itv = Interval{Open, Closed}(0.0, 1.0) + i = IntervalsFold(itv, 2.0, 1000) + + unfold(i) + collect(i) + reverse(collect(i)) + + # Vectors + vf = make_vector_fold([0, 1], 2, 1000) + + unfold(vf) + collect(vf) + reverse(collect(vf)) + + rand(vf, 1000) + + return nothing +end + +mkpath(joinpath(@__DIR__, "visuals")) + +c = checkres_to_scatterlines(x, Val(:chairmark)) +save(joinpath(@__DIR__, "visuals", "chair_evolution.png"), c) + +for kwarg in [:times, :gctimes, :bytes, :allocs] + c2 = checkres_to_boxplots(x, Val(:chairmark); kwarg) + save(joinpath(@__DIR__, "visuals", "chair_boxplots_$kwarg.png"), c2) +end +``` + + +`d` here is the configuration dictionary. `x` stores the results from performance testing + +The code below the macro call is for plotting and storing the plots. It creates the visuals folder and stores the following plots in the folder: + +Boxplots from Chairmarks for allocations: + +chair_boxplots + + +Boxplots from Chairmarks for times: + +chair_times + + +Evolution of different metrics across versions according to Chairmarks: + +chair_evolution + diff --git a/dev/.documenter/public/JuMP-logo-dark.png b/dev/.documenter/public/JuMP-logo-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..23a0862739ac7d2b789882396eb811530bd7b065 GIT binary patch literal 3318 zcmZ`*c`zI57FSwIDA%oB5K_0bwkSpITOx>O-?zjPv`T6XYVV@f&?QJ(wOqR!du_d{ z_E;0dT5VMkJ1Nrg^!@c_-hJnr^PQRB?|gI4H*@AU=dq=Q2^WVj2NM$$7ZhS>br#!x z`9;>Vy9?S~aTZv;U?zr4r@zjt_EIbp6K4g~P|qe}W}^U;X-xt4ve@7y3+=|za|fjL z?1THcS|bBrkc0Cbf&Q~Mu*e;Co2!&YU zTT%o0{bh^g8xxe|`uFgWzZ}lG z`X{?*GEwh|n_Q*TR|ie3L?2hab37-V`}0)+7;cSvPS!9F$V*Z_ZwAKLUwAyfkV>P@ zK*!zFl`oj;(F5h*QJIS+H7kI(5U*^IzM(w6Tsco@mD*h|S$@Grw=ie$;v3Y%>Mo)4 zS0pe~vF7W|e7-z=UEEg_WI-Q2*AHS6nYP#MrYm(yWvv#G8ybq~I$ZLOUwdm-sr%r+{Wk{EAD zM(gFns_4nn#M;20~_{TnjuL>?H(Uq^^r&@pz`w}XGURDaP z4~()U^M@F1z*`C%jjCU49F@P==-od;+789KFYlJAruqn_RAi_q`iyCo0`Xp=u+YyN zzq{U8SF7-v{0>=@vT+g%ja%aiC(|2tOLnuaGo#$z$qXOU@DbF@rrXb{L^WGzb3`VF#@KM((d2X+y;tpQrj7mdw4# zN~<}WnCb z^(`oe5!M7;!tDOYJ>)`oHoZbAq|!JiOJw7>gAnYg{r<9}`3WmJvfo#je+edO>YDTC@}f&(1-bea*@yH1_6L8Ksag(%~E z`JOh~km}4v82`6ZM`3E{l1?rHf?zZ}_7191@vxnn#8*vlrz?KslF6mL-PZKx!FL37 zo6EGSx`;bnEcoh^=_(N0E{cd)uk!)cwHm?Eb$!)vm;zRE=`%gfv3E1$N&Z)#Y*&F3 zPoX5jm|rWkl3kqVCW$1iY4BhWx-BF;EB5;X&pUaB`uV)_B+^w3KkghA)VzP-L%_Jp zSmE*<=})(VXTKZrcPROU<6I){AV;tkC#bt&RH0lh>l&Y$33i$2x?&p%s6XTxpN$Bl zQEe5So`rJbAo>RP(i9(Ei>Ar};%Ldzb>~&(!~d9`ppYEw#fZ-bE-we$cSiv@lV~4u zwS9hGIbH-|pnb#J9sc6*uAfT!{Unw%19Z}mx0>_Zk> zBs`~ou3sOFtMn2nYLT)Y@Bkv!fVKzT_8;Z`Bb7}5rH_3IMKn}rhxDtl8TqJk)Mw1Q0)rLk)y z@jo0jAA*mIKb&Zcx^p-LFjJi?fE;P0Q#X$>#mYKb4ePv(k$Hd5OoN(QQa0%V-_O%- z_zy{5KYitwmBfirgvH2Vs~^$bGQDaxWR|HrLZ>jJ3q|1XAY3t8K>e zoONs=a#^*<9UjE>+=xp=z_`eJT!&$fR^INBSTE7C>skp-t4?*tam}GmL3avK?i304 zSi1QZRIz(Z9KgNn=EFBgB!M)2sTkp|9A!xWTJ0tOvE-U>>)@gZ*6LCVaMTL>fs_FD$)gIm^r$$(H2IjrlD9HR)~ak=5FZ3b9qyzLxS zy;{UTsUXMeSx?37iBmaqw~9-TGPegonkJAEEvt)L=-b(dXFgcbt_lE1(|u_Qc0+zO zwE5Wl&_hW&ahrT%381!c5FCAt?=QiFcA|P$1jmQ4$Y&*@#J$T4>y=p^DLw(ilL@+A z3h~>F;%G*{86a=`Z3Y5b{$6S1??EL2#bwbpA^RQ5)T7I`hiH-*S_hVFf!wKK3&;93ZTBv6E z=fs@$v=VLiCn=L=&-T3h3-&;mliDlC(=O_1?e^ofNMH9FjQ&EHWO2>Tw!ZB($%)~pZtl(dRmMNbpcA3t&CBPX_)n%Sm)t} zyqI$Qgim}^aWU>m>6E1`0Pow2{b(loM zIsQASD77uWI97Xnde@yW^;2P9Mzr91?v&^&#(R{KvER?W0>SNS(GpP;r>9BH#0Ek3 zE+o(*j{^ba38w2?rHIjsVjF6=~d<>!qzr`l`H~dV8Uh{4QX7b96Cv(WyvBr)NnJ5j`Sl@9G;^G!i1CxCvo>c zD9lJAHJoID(V;N^-wtv<)d^;03DA;_J^_|9DC4PG+1}TFZNdZfUCYV9s1tg3v2r$; zJ?0Fna5jB+WS%X1mY?Z*Cyj-38F5FXUv+e`$yoO`g)w<0C~bJnb1_xSyjLq;ZFT*N zt`H?EYvp_dW3MchK-GZkwnVCtcZ)gyMv^TuL)^8kygc>UQb4n)nUY@vKV@S?NgKEo z(CC}zeS#&Unwi#bf5@C_b=!}Vg^TOU77JY@PK27Abp0rzC(38Q+^`>Zg;GRlwpNUF z+^tlqDO!h;u@X*F?Po^1W~Q_y;ZYD49ZZ3Sa`UC;^q$I?vC=*gP2lZrxw3bgm z73Ky&wVjW?5u1SeY=Sz(G;mfhVq@>qcs6^F>7A4n(^{2tABT)(wR32E# zICsrfPyUaf=vGcJo;)a4P@hA>itC|8mx=;=f?LFDgBDhDVWwy>;!rnsWkc*l5Bb|V ziexpYR8U_=O7HSaTvt3j)_gMNwmYm|P_Ok>xMm>yr7Pg3{m4})V)Evs>x|lO;$hTH z+K7NT>9#Bu`UmHY8n@h6L-4)oQazz}NP>{_kIxb$qN{goi;3(gbk`DU;^R~4Q1CdU z*GbQ>R|4C>ewsE}PRyx)|6(_wtKdP)be>;SZu}#-vu(v=oq4_U@LG1)59^pmA_G;0 z(D)x_IM@Lx`W$0~jS{^P|MPXx*P8^RRng>x{T=!O3 zx9cCU8iKkBVdY-;3<#6Wn*_(eq-rMi7v1XeP-U^yYl8(PuW3d;&MN(qrsz}zR5Gyd zKvpt5k+Q1XFKL1vML;9;N5;xRY5q(#;V6Z*tn=b-0wL$vEG9g0(jJ*{H z)QN#J9kOiqsviab>3IaG>M;O6^j^pl{ex=Sog(GD%JZRW(&9q;TEzo5;)JH1TKqDN z!OHkjwY$fZxW%trb)uyLs!r1E?-#+^9@V(V&&LteH_SR^v6)$V2Yb~^=8{}mE;lmG z{rlR0a_Gz~qs!SF#Uf3OgP0VV2xuMEIAg^n1$3Wv>^v=HNmZ>D??QBLH^N`vAG-RP~;rR9{C7|GyX!lIm1NRUJWd4(?d^l+}bA)T+=_Z6kED@+L z10of1GChlgKL`8Ol1Qu8CvJme$_0eNs)Kp6g*?5^bchXen6%fYlWFvFtIR3~SB=fG zas854s5GDel4o8sn#)!)^xv{IqyV(#USD6cUK2U7socoUA5eM6YmRaLQZ0fwW5@&I zh*}v!PRpwNhLn7Pg*-o6?`WsXX@`QiV4E4Hh;usC@JtUJa{t@RS`1H+EC&Xze=6Om z>DXj9h(Lqqq(pZF)~xBVhl^CGA{|M`Gie0?tr^nn@zU(s_>{gY_um**$fpWj{ke{5 z?Hz{|(NCQX7);9I(UY=vhjmt(uC=Fdj3;l2?zp4e1W?&LOPV!`>o5|$O-aZ(`p}t~ z#wg&y<ca<~qq8xbalnJu zy{R-0KPmanrd6BYHh%UdPe8TjrZ2S+t2)oW0jebm74xdqqq-#TOLU9iH$*lnpGVJF z*VLZuJuA?a&>T90b)S5#(A~0IsG|$E_-4!9J!7*rqNIM|@m8<3Vjy;w|8vn!=DUQN z5^r~=j%Vn5C&YH|W1EK)eJ(0i$gXeBn8Tw--XsUJf&ORb`Puzl8h;c%{vJ_znA6nr z>ta%vy|$v>RD*Iputn^gYUmDb`9-S9-Rt~t7yGz3DCryrAsvnoBGpBu+b){c2;1$j>FQzTfHAAh#s2 z(DQ%Hze%+o{PPkO=p~NLq#V*A4l1xSG;|cI$xQmG_VmDVe%?w9W%MEgbbFOD6*#FW zgMgC9{f?>?*-_FK+#z}l6tYPou?AOIU+%h`$Oms#Sc1RMb z(^cw~88JRMyU?<(TH~KWF%i&(NICL)Z?W686l?#%P%|(Ekk;HNYWhgLiuPGFBy;Vd zE*+mOBYU@8)BDOCD#Kxw$qBN??_8$$)nVR}?{$D@x;ciQk^ESbJ0e?7E1N}N1?RtIJ@}}1l$Y1$U0zZmU_?RQ z?zMK`ki_G+Z>&5N88b0walre(CiUWWo{m^H@M#B5W`%*+lXp0%6$sLWb_P!*D{3_X z)5@D{cqG0>Z(P8({IH^L`cQ)FSE&k!7E#;Zck0KR$mh*hL__$Bv_G{WjI!Q*MY1i# z-m9_x>~%k2UwN;;>EZXq=;^~wUye=jum}h7u{aUfBRQCM2~Fzm zO_g?!b4|JlOeBz7WoNrYYd^H_%_TPaE%bJcIG;H>`z}03D##5@8&DWI?#LeNd>at# z3BH+oA#K5j80hH2r1 z%K5kE9`TDO(%&e&*S>)%Tm<8S?i6S_M2A0l4BK(inR|r;VcWTaoXP~9x0Y|Ez1%-6 zb_}?kv|sdxV&yZxmd-UWp{0Fu%5cp+FIcW-%UwFSnhfb0Q3;Oezr`!h`^>U)rCkAb za;;%{ldDJTW&67+C*KNrRpVGq7q?-(C}-=xa=!Dv&2<31xajd{S5J335)Y2eYQymX zRLXOxd5*vLKqE)&&bwPuNZi9PI297F#Jq5Ybg literal 0 HcmV?d00001 diff --git a/dev/.documenter/public/logo.png b/dev/.documenter/public/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4a1302eacc6c702423c1d41d64283fb33c8e5646 GIT binary patch literal 60313 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 Ss?rev0000)L|G5#-?`f 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 taH7`j$<@}-cf@c31E# literal 0 HcmV?d00001 diff --git a/dev/.documenter/public_api.md b/dev/.documenter/public_api.md new file mode 100644 index 0000000..884078a --- /dev/null +++ b/dev/.documenter/public_api.md @@ -0,0 +1,1480 @@ + +# Public API {#Public-API} + +
+
+# ConstraintCommons.MDDType. + + + + +```julia +MDD{S,T} <: AbstractMultivaluedDecisionDiagram +``` + + +A minimal implementation of a multivalued decision diagram structure. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/diagrams.jl#L9-L13) + +
+
+
+# ConstraintCommons.acceptMethod. + + + + +```julia +accept(a::Union{Automaton, MDD}, w) +``` + + +Return `true` if `a` accepts the word `w` and `false` otherwise. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/automata.jl#L29-L33) + +
+
+
+# ConstraintCommons.consinMethod. + + + + +```julia +Base.in(::Any, ::Nothing) +``` + + +Extends `Base.in` (or `∈`) when the set is `nothing`. Returns `false`. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/nothing.jl#L1-L5) + +
+
+
+# ConstraintCommons.extract_parametersMethod. + + + + +```julia +extract_parameters(m::Union{Method, Function}; parameters) +``` + + +Extracts the intersection between the `kargs` of `m` and `parameters` (defaults to `USUAL_CONSTRAINT_PARAMETERS`). + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/parameters.jl#L21-L25) + +
+
+
+# ConstraintCommons.incsert!Function. + + + + +```julia +incsert!(d::Union{AbstractDict, AbstractDictionary}, ind, val = 1) +``` + + +Increase or insert a counter in a dictionary-based collection. The counter insertion defaults to `val = 1`. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/dictionaries.jl#L2-L6) + +
+
+
+# ConstraintCommons.oversampleMethod. + + + + +```julia +oversample(X, f) +``` + + +Oversample elements of `X` until the boolean function `f` has as many `true` and `false` configurations. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/sampling.jl#L1-L5) + +
+
+
+# ConstraintCommons.symconFunction. + + + + +```julia +Base.:*(s1::Symbol, s2::Symbol, connector::AbstractString="_") +``` + + +Extends `*` to `Symbol`s multiplication by connecting the symbols by an `_`. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/symbols.jl#L1-L5) + +
+
+
+# ConstraintCommons.δ_extremaMethod. + + + + +```julia +δ_extrema(X...) +``` + + +Compute both the difference between the maximum and the minimum of over all the collections of `X`. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/extrema.jl#L1-L4) + +
+
+
+# ConstraintDomains.AbstractDomainType. + + + + +```julia +AbstractDomain +``` + + +An abstract super type for any domain type. A domain type `D <: AbstractDomain` must implement the following methods to properly interface `AbstractDomain`. +- `Base.∈(val, ::D)` + +- `Base.rand(::D)` + +- `Base.length(::D)` that is the number of elements in a discrete domain, and the distance between bounds or similar for a continuous domain + + +Additionally, if the domain is used in a dynamic context, it can extend +- `add!(::D, args)` + +- `delete!(::D, args)` + + +where `args` depends on `D`'s structure + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L1-L11) + +
+
+
+# ConstraintDomains.ContinuousDomainType. + + + + +```julia +ContinuousDomain{T <: Real} <: AbstractDomain +``` + + +An abstract supertype for all continuous domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L1-L4) + +
+
+
+# ConstraintDomains.DiscreteDomainType. + + + + +```julia +DiscreteDomain{T <: Number} <: AbstractDomain +``` + + +An abstract supertype for discrete domains (set, range). + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L1-L4) + +
+
+
+# ConstraintDomains.ExploreSettingsMethod. + + + + +```julia +ExploreSettings( + domains; + complete_search_limit = 10^6, + max_samplings = sum(domain_size, domains), + search = :flexible, + solutions_limit = floor(Int, sqrt(max_samplings)), +) +``` + + +Settings for the exploration of a search space composed by a collection of domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/explore.jl#L8-L18) + +
+
+
+# ConstraintDomains.RangeDomainType. + + + + +```julia +RangeDomain +``` + + +A discrete domain defined by a `range <: AbstractRange{Real}`. As ranges are immutable in Julia, changes in `RangeDomain` must use `set_domain!`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L16-L19) + +
+
+
+# Base.delete!Method. + + + + +```julia +Base.delete!(d::SetDomain, value)(d::SetDomain, value) +``` + + +Delete `value` from the list of points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L76-L79) + +
+
+
+# ConstraintDomains.add!Method. + + + + +```julia +add!(d::SetDomain, value) +``` + + +Add `value` to the list of points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L70-L73) + +
+
+
+# ConstraintDomains.domainMethod. + + + + +```julia +domain(values) +domain(range::R) where {T <: Real, R <: AbstractRange{T}} +``` + + +Construct either a `SetDomain` or a `RangeDomain``. + +```julia +d1 = domain(1:5) +d2 = domain([53.69, 89.2, 0.12]) +d3 = domain([2//3, 89//123]) +d4 = domain(4.3) +d5 = domain(1,42,86.9) +``` + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L31-L42) + +
+
+
+# ConstraintDomains.domainMethod. + + + + +```julia +domain() +``` + + +Construct an `EmptyDomain`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L20-L23) + +
+
+
+# ConstraintDomains.domainMethod. + + + + +```julia +domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real} +domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real} +``` + + +Construct a domain of continuous interval(s). + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L15-L19) + +
+
+
+# ConstraintDomains.domain_sizeMethod. + + + + +```julia +domain_size(itv::Intervals) +``` + + +Return the difference between the highest and lowest values in `itv`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L61-L64) + +
+
+
+# ConstraintDomains.domain_sizeMethod. + + + + +```julia +domain_size(d <: AbstractDomain) +``` + + +Fallback method for `domain_size(d)` that return `length(d)`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L46-L49) + +
+
+
+# ConstraintDomains.domain_sizeMethod. + + + + +```julia +domain_size(d::D) where D <: DiscreteDomain +``` + + +Return the maximum distance between two points in `d`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L64-L67) + +
+
+
+# ConstraintDomains.exploreMethod. + + + + +```julia +explore(domains, concept, param = nothing; search_limit = 1000, solutions_limit = 100) +``` + + +Search (a part of) a search space and returns a pair of vector of configurations: `(solutions, non_solutions)`. If the search space size is over `search_limit`, then both `solutions` and `non_solutions` are limited to `solutions_limit`. + +Beware that if the density of the solutions in the search space is low, `solutions_limit` needs to be reduced. This process will be automatic in the future (simple reinforcement learning). + +**Arguments:** +- `domains`: a collection of domains + +- `concept`: the concept of the targeted constraint + +- `param`: an optional parameter of the constraint + +- `sol_number`: the required number of solutions (half of the number of configurations), default to `100` + + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/explore.jl#L66-L78) + +
+
+
+# ConstraintDomains.generate_parametersMethod. + + + + +```julia +generate_parameters(d<:AbstractDomain, param) +``` + + +Generates random parameters based on the domain `d` and the kind of parameters `param`. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/parameters.jl#L128-L132) + +
+
+
+# ConstraintDomains.get_domainMethod. + + + + +```julia +get_domain(::AbstractDomain) +``` + + +Access the internal structure of any domain type. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L52-L55) + +
+
+
+# ConstraintDomains.intersect_domainsMethod. + + + + +```julia +intersect_domains(d₁, d₂) +``` + + +Compute the intersections of two domains. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/continuous.jl#L72-L76) + +
+
+
+# ConstraintDomains.merge_domainsMethod. + + + + +```julia +merge_domains(d₁::AbstractDomain, d₂::AbstractDomain) +``` + + +Merge two domains of same nature (discrete/contiuous). + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/discrete.jl#L83-L87) + +
+
+
+# ConstraintDomains.to_domainsMethod. + + + + +```julia +to_domains(args...) +``` + + +Convert various arguments into valid domains format. + + +[source](https://github.com/JuliaConstraints/ConstraintDomains.jl/blob/v0.3.10/src/common.jl#L58-L62) + +
+
+
+# Constraints.USUAL_CONSTRAINTSConstant. + + + + +```julia +USUAL_CONSTRAINTS::Dict +``` + + +Dictionary that contains all the usual constraints defined in Constraint.jl. It is based on XCSP3-core specifications available at https://arxiv.org/abs/2009.00514 + +Adding a new constraint is as simple as defining a new function with the same name as the constraint and using the `@usual` macro to define it. The macro will take care of adding the new constraint to the `USUAL_CONSTRAINTS` dictionary. + +**Example** + +```julia +@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L1-L11) + +
+
+
+# Constraints.USUAL_SYMMETRIESConstant. + + + + +```julia +USUAL_SYMMETRIES +``` + + +A Dictionary that contains the function to apply for each symmetry to avoid searching a whole space. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L1-L4) + +
+
+
+# Constraints.ConstraintType. + + + + +```julia +Constraint +``` + + +Parametric structure with the following fields. +- `concept`: a Boolean function that, given an assignment `x`, outputs `true` if `x` satisfies the constraint, and `false` otherwise. + +- `error`: a positive function that works as preferences over invalid assignments. Return `0.0` if the constraint is satisfied, and a strictly positive real otherwise. + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L7-L12) + +
+
+
+# ConstraintCommons.extract_parametersFunction. + + + + +```julia +extract_parameters(s::Symbol, constraints_dict=USUAL_CONSTRAINTS; parameters=ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS) +``` + + +Return the parameters of the constraint `s` in `constraints_dict`. + +**Arguments** +- `s::Symbol`: the constraint name. + +- `constraints_dict::Dict{Symbol,Constraint}`: dictionary of constraints. Default is `USUAL_CONSTRAINTS`. + +- `parameters::Vector{Symbol}`: vector of parameters. Default is `ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS`. + + +**Example** + +```julia +extract_parameters(:all_different) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L44-L58) + +
+
+
+# Constraints.argsMethod. + + + + +```julia +args(c::Constraint) +``` + + +Return the expected length restriction of the arguments in a constraint `c`. The value `nothing` indicates that any strictly positive number of value is accepted. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L62-L65) + +
+
+
+# Constraints.conceptMethod. + + + + +```julia +concept(c::Constraint) +``` + + +Return the concept (function) of constraint `c`. concept(c::Constraint, x...; param = nothing) Apply the concept of `c` to values `x` and optionally `param`. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L40-L45) + +
+
+
+# Constraints.conceptMethod. + + + + +```julia +concept(s::Symbol, args...; kargs...) +``` + + +Return the concept of the constraint `s` applied to `args` and `kargs`. This is a shortcut for `concept(USUAL_CONSTRAINTS[s])(args...; kargs...)`. + +**Arguments** +- `s::Symbol`: the constraint name. + +- `args...`: the arguments to apply the concept to. + +- `kargs...`: the keyword arguments to apply the concept to. + + +**Example** + +```julia +concept(:all_different, [1, 2, 3]) +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L221-L235) + +
+
+
+# Constraints.constraints_descriptionsFunction. + + + + +```julia +constraints_descriptions(C=USUAL_CONSTRAINTS) +``` + + +Return a pretty table with the descriptions of the constraints in `C`. + +**Arguments** +- `C::Dict{Symbol,Constraint}`: dictionary of constraints. Default is `USUAL_CONSTRAINTS`. + + +**Example** + +```julia +constraints_descriptions() +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L180-L192) + +
+
+
+# Constraints.constraints_parametersFunction. + + + + +```julia +constraints_parameters(C=USUAL_CONSTRAINTS) +``` + + +Return a pretty table with the parameters of the constraints in `C`. + +**Arguments** +- `C::Dict{Symbol,Constraint}`: dictionary of constraints. Default is `USUAL_CONSTRAINTS`. + + +**Example** + +```julia +constraints_parameters() +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L127-L139) + +
+
+
+# Constraints.describeFunction. + + + + +```julia +describe(constraints::Dict{Symbol,Constraint}=USUAL_CONSTRAINTS; width=150) +``` + + +Return a pretty table with the description of the constraints in `constraints`. + +**Arguments** +- `constraints::Dict{Symbol,Constraint}`: dictionary of constraints to describe. Default is `USUAL_CONSTRAINTS`. + +- `width::Int`: width of the table. + + +**Example** + +```julia +describe() +``` + + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/usual_constraints.jl#L14-L27) + +
+
+
+# Constraints.error_fMethod. + + + + +```julia +error_f(c::Constraint) +``` + + +Return the error function of constraint `c`. error_f(c::Constraint, x; param = nothing) Apply the error function of `c` to values `x` and optionally `param`. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L51-L56) + +
+
+
+# Constraints.params_lengthMethod. + + + + +```julia +params_length(c::Constraint) +``` + + +Return the expected length restriction of the arguments in a constraint `c`. The value `nothing` indicates that any strictly positive number of parameters is accepted. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L68-L71) + +
+
+
+# Constraints.symmetriesMethod. + + + + +```julia +symmetries(c::Constraint) +``` + + +Return the list of symmetries of `c`. + + +[source](https://github.com/JuliaConstraints/Constraints.jl/blob/v0.5.5/src/constraint.jl#L74-L77) + +
+
+
+# CompositionalNetworks.CompositionMethod. + + + + +```julia +Composition(f::F, symbols) where {F<:Function} +``` + + +Construct a `Composition`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L12-L16) + +
+
+
+# CompositionalNetworks.CompositionType. + + + + +```julia +struct Composition{F<:Function} +``` + + +Store the all the information of a composition learned by an ICN. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L1-L5) + +
+
+
+# CompositionalNetworks.ICNType. + + + + +```julia +ICN(; nvars, dom_size, param, transformation, arithmetic, aggregation, comparison) +``` + + +Construct an Interpretable Compositional Network, with the following arguments: +- `nvars`: number of variable in the constraint + +- `dom_size: maximum domain size of any variable in the constraint` + +- `param`: optional parameter (default to `nothing`) + +- `transformation`: a transformation layer (optional) + +- `arithmetic`: a arithmetic layer (optional) + +- `aggregation`: a aggregation layer (optional) + +- `comparison`: a comparison layer (optional) + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L1-L11) + +
+
+
+# CompositionalNetworks.aggregation_layerMethod. + + + + +```julia +aggregation_layer() +``` + + +Generate the layer of aggregations of the ICN. The operations are mutually exclusive, that is only one will be selected. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/aggregation.jl#L13-L16) + +
+
+
+# CompositionalNetworks.arithmetic_layerMethod. + + + + +```julia +arithmetic_layer() +``` + + +Generate the layer of arithmetic operations of the ICN. The operations are mutually exclusive, that is only one will be selected. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/arithmetic.jl#L13-L16) + +
+
+
+# CompositionalNetworks.codeFunction. + + + + +```julia +code(c::Composition, lang=:maths; name="composition") +``` + + +Access the code of a composition `c` in a given language `lang`. The name of the generated method is optional. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L22-L26) + +
+
+
+# CompositionalNetworks.comparison_layerFunction. + + + + +```julia +comparison_layer(param = false) +``` + + +Generate the layer of transformations functions of the ICN. Iff `param` value is set, also includes all the parametric comparison with that value. The operations are mutually exclusive, that is only one will be selected. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/comparison.jl#L85-L88) + +
+
+
+# CompositionalNetworks.composeFunction. + + + + +```julia +compose(icn, weights=nothing) +``` + + +Return a function composed by some of the operations of a given ICN. Can be applied to any vector of variables. If `weights` are given, will assign to `icn`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L45-L48) + +
+
+
+# CompositionalNetworks.compose_to_file!Method. + + + + +```julia +compose_to_file!(concept, name, path; domains, param = nothing, language = :Julia, search = :complete, global_iter = 10, local_iter = 100, metric = hamming, popSize = 200) +``` + + +Explore, learn and compose a function and write it to a file. + +**Arguments:** +- `concept`: the concept to learn + +- `name`: the name to give to the constraint + +- `path`: path of the output file + + +**Keywords arguments:** +- `domains`: domains that defines the search space + +- `param`: an optional parameter of the constraint + +- `language`: the language to export to, default to `:julia` + +- `search`: either `:partial` or `:complete` search + +- `global_iter`: number of learning iteration + +- `local_iter`: number of generation in the genetic algorithm + +- `metric`: the metric to measure the distance between a configuration and known solutions + +- `popSize`: size of the population in the genetic algorithm + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/learn.jl#L77-L95) + +
+
+
+# CompositionalNetworks.compositionMethod. + + + + +```julia +composition(c::Composition) +``` + + +Access the actual method of an ICN composition `c`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L31-L35) + +
+
+
+# CompositionalNetworks.composition_to_file!Function. + + + + +```julia +composition_to_file!(c::Composition, path, name, language=:Julia) +``` + + +Write the composition code in a given `language` into a file at `path`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L97-L101) + +
+
+
+# CompositionalNetworks.explore_learn_composeMethod. + + + + +```julia +explore_learn_compose(concept; domains, param = nothing, search = :complete, global_iter = 10, local_iter = 100, metric = hamming, popSize = 200, action = :composition) +``` + + +Explore a search space, learn a composition from an ICN, and compose an error function. + +**Arguments:** +- `concept`: the concept of the targeted constraint + +- `domains`: domains of the variables that define the training space + +- `param`: an optional parameter of the constraint + +- `search`: either `flexible`,`:partial` or `:complete` search. Flexible search will use `search_limit` and `solutions_limit` to determine if the search space needs to be partially or completely explored + +- `global_iter`: number of learning iteration + +- `local_iter`: number of generation in the genetic algorithm + +- `metric`: the metric to measure the distance between a configuration and known solutions + +- `popSize`: size of the population in the genetic algorithm + +- `action`: either `:symbols` to have a description of the composition or `:composition` to have the composed function itself + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/learn.jl#L35-L50) + +
+
+
+# CompositionalNetworks.hammingMethod. + + + + +```julia +hamming(x, X) +``` + + +Compute the hamming distance of `x` over a collection of solutions `X`, i.e. the minimal number of variables to switch in `x`to reach a solution. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/metrics.jl#L1-L4) + +
+
+
+# CompositionalNetworks.lazyMethod. + + + + +```julia +lazy(funcs::Function...) +``` + + +Generate methods extended to a vector instead of one of its components. A function `f` should have the following signature: `f(i::Int, x::V)`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L22-L25) + +
+
+
+# CompositionalNetworks.lazy_paramMethod. + + + + +```julia +lazy_param(funcs::Function...) +``` + + +Generate methods extended to a vector instead of one of its components. A function `f` should have the following signature: `f(i::Int, x::V; param)`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/utils.jl#L36-L39) + +
+
+
+# CompositionalNetworks.learn_composeMethod. + + + + +```julia +learn_compose(; + nvars, dom_size, param=nothing, icn=ICN(nvars, dom_size, param), + X, X_sols, global_iter=100, local_iter=100, metric=hamming, popSize=200 +) +``` + + +Create an ICN, optimize it, and return its composition. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/learn.jl#L7-L13) + +
+
+
+# CompositionalNetworks.manhattanMethod. + + + + +```julia +manhattan(x, X) +``` + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/metrics.jl#L12-L14) + +
+
+
+# CompositionalNetworks.minkowskiMethod. + + + + +```julia +minkowski(x, X, p) +``` + + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/metrics.jl#L7-L9) + +
+
+
+# CompositionalNetworks.nbitsMethod. + + + + +```julia +nbits(icn) +``` + + +Return the expected number of bits of a viable weight of an ICN. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L43-L46) + +
+
+
+# CompositionalNetworks.regularizationMethod. + + + + +```julia +regularization(icn) +``` + + +Return the regularization value of an ICN weights, which is proportional to the normalized number of operations selected in the icn layers. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L89-L92) + +
+
+
+# CompositionalNetworks.show_layersMethod. + + + + +```julia +show_layers(icn) +``` + + +Return a formatted string with each layers in the icn. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L81-L84) + +
+
+
+# CompositionalNetworks.symbolsMethod. + + + + +```julia +symbols(c::Composition) +``` + + +Output the composition as a layered collection of `Symbol`s. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/composition.jl#L38-L42) + +
+
+
+# CompositionalNetworks.transformation_layerFunction. + + + + +```julia +transformation_layer(param = false) +``` + + +Generate the layer of transformations functions of the ICN. Iff `param` value is true, also includes all the parametric transformations. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/layers/transformation.jl#L298-L301) + +
+
+
+# CompositionalNetworks.weights!Method. + + + + +```julia +weights!(icn, weights) +``` + + +Set the weights of an ICN with a `BitVector`. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L71-L74) + +
+
+
+# CompositionalNetworks.weightsMethod. + + + + +```julia +weights(icn) +``` + + +Access the current set of weights of an ICN. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/icn.jl#L49-L52) + +
+
+
+# CompositionalNetworks.weights_biasMethod. + + + + +```julia +weights_bias(x) +``` + + +A metric that bias `x` towards operations with a lower bit. Do not affect the main metric. + + +[source](https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/v0.5.6/src/metrics.jl#L17-L20) + +
+
+
+# QUBOConstraints.QUBO_linear_sumMethod. + + + + +```julia +QUBO_linear_sum(n, σ) +``` + + +One valid QUBO matrix given `n` variables and parameter `σ` for the linear sum constraint. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/handmade/linear_sum.jl#L1-L5) + +
+
+
+# QUBOConstraints.binarizeMethod. + + + + +```julia +binarize(x[, domain]; binarization = :one_hot) +``` + + +Binarize `x` following the `binarization` encoding. If `x` is a vector (instead of a number per say), `domain` is optional. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/encoding/conversion.jl#L12-L16) + +
+
+
+# QUBOConstraints.debinarizeMethod. + + + + +```julia +debinarize(x[, domain]; binarization = :one_hot) +``` + + +Transform a binary vector into a number or a set of number. If `domain` is not given, it will compute a default value based on `binarization` and `x`. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/encoding/conversion.jl#L35-L39) + +
+
+
+# QUBOConstraints.is_validFunction. + + + + +```julia +is_valid(x, encoding::Symbol = :none) +``` + + +Check if `x` has a valid format for `encoding`. + +For instance, if `encoding == :one_hot`, at most one bit of `x` can be set to 1. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/encoding/conversion.jl#L1-L7) + +
+
+
+# QUBOConstraints.trainMethod. + + + + +```julia +train(args...) +``` + + +Default `train` method for any AbstractOptimizer. + + +[source](https://github.com/JuliaConstraints/QUBOConstraints.jl/blob/v0.2.1/src/learn.jl#L8-L12) + +
+
diff --git a/dev/.documenter/solvers/cbls.md b/dev/.documenter/solvers/cbls.md new file mode 100644 index 0000000..1e0835d --- /dev/null +++ b/dev/.documenter/solvers/cbls.md @@ -0,0 +1,929 @@ + +# CBLS.jl + +Documentation for `CBLS.jl`. +
+# CBLS.AllDifferentType. + + + + +Global constraint ensuring that all the values of a given configuration are unique. + +```julia +@constraint(model, X in AllDifferent()) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L139-L145) + +
+
+
+# CBLS.AllEqualType. + + + + +Global constraint ensuring that all the values of `X` are all equal. + +```julia +@constraint(model, X in AllEqual()) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L170-L176) + +
+
+
+# CBLS.AllEqualParamType. + + + + +Global constraint ensuring that all the values of `X` are all equal to a given parameter `param`. + +```julia +@constraint(model, X in AllEqualParam(param)) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L338-L344) + +
+
+
+# CBLS.AlwaysTrueType. + + + + +Always return `true`. Mainly used for testing purpose. + +```julia +@constraint(model, X in AlwaysTrue()) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L231-L237) + +
+
+
+# CBLS.DiscreteSetType. + + + + +```julia +DiscreteSet(values) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/MOI_wrapper.jl#L98-L100) + +
+
+
+# CBLS.DistDifferentType. + + + + +Local constraint ensuring that, given a vector `X` of size 4, `|X[1] - X[2]| ≠ |X[3] - X[4]|)`. + +```julia +@constraint(model, X in DistDifferent()) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L293-L299) + +
+
+
+# CBLS.EqType. + + + + +Equality between two variables. + +```julia +@constraint(model, X in Eq()) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L201-L207) + +
+
+
+# CBLS.ErrorType. + + + + +```julia +Error{F <: Function} <: JuMP.AbstractVectorSet +``` + + +The solver will compute a straightforward error function based on the `concept`. To run the solver efficiently, it is possible to provide an _error function_ `err` instead of `concept`. `err` must return a nonnegative real number. + +```julia +@constraint(model, X in Error(err)) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L58-L66) + +
+
+
+# CBLS.LessThanParamType. + + + + +Constraint ensuring that the value of `x` is less than a given parameter `param`. + +```julia +@constraint(model, x in LessThanParam(param)) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L432-L438) + +
+
+
+# CBLS.MOIAllDifferentType. + + + + +```julia +MOIAllDifferent <: MOI.AbstractVectorSet +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L119-L123) + +
+
+
+# CBLS.MOIAllEqualType. + + + + +```julia +MOIAllEqual <: MOI.AbstractVectorSet +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L149-L153) + +
+
+
+# CBLS.MOIAllEqualParamType. + + + + +```julia +MOIAllEqualParam{T <: Number} <: MOI.AbstractVectorSet +``` + + +DOCSTRING + +**Arguments:** +- `param::T`: DESCRIPTION + +- `dimension::Int`: DESCRIPTION + +- `MOIAllEqualParam(param, dim = 0) = begin #= none:5 =# new{typeof(param)}(param, dim) end`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L303-L315) + +
+
+
+# CBLS.MOIAlwaysTrueType. + + + + +```julia +MOIAlwaysTrue <: MOI.AbstractVectorSet +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L211-L215) + +
+
+
+# CBLS.MOIDistDifferentType. + + + + +```julia +MOIDistDifferent <: MOI.AbstractVectorSet +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L273-L277) + +
+
+
+# CBLS.MOIEqType. + + + + +```julia +MOIEq <: MOI.AbstractVectorSet +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L180-L184) + +
+
+
+# CBLS.MOIErrorType. + + + + +```julia +MOIError{F <: Function} <: MOI.AbstractVectorSet +``` + + +DOCSTRING + +**Arguments:** +- `f::F`: DESCRIPTION + +- `dimension::Int`: DESCRIPTION + +- `MOIError(f, dim = 0) = begin #= none:5 =# new{typeof(f)}(f, dim) end`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L1-L13) + +
+
+
+# CBLS.MOILessThanParamType. + + + + +```julia +MOILessThanParam{T <: Number} <: MOI.AbstractVectorSet +``` + + +DOCSTRING + +**Arguments:** +- `param::T`: DESCRIPTION + +- `dimension::Int`: DESCRIPTION + +- `MOILessThanParam(param, dim = 0) = begin #= none:5 =# new{typeof(param)}(param, dim) end`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L397-L409) + +
+
+
+# CBLS.MOIMinusEqualParamType. + + + + +```julia +MOIMinusEqualParam{T <: Number} <: MOI.AbstractVectorSet +``` + + +DOCSTRING + +**Arguments:** +- `param::T`: DESCRIPTION + +- `dimension::Int`: DESCRIPTION + +- `MOIMinusEqualParam(param, dim = 0) = begin #= none:5 =# new{typeof(param)}(param, dim) end`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L444-L456) + +
+
+
+# CBLS.MOIOrderedType. + + + + +```julia +MOIOrdered <: MOI.AbstractVectorSet +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L241-L245) + +
+
+
+# CBLS.MOIPredicateType. + + + + +```julia +MOIPredicate{F <: Function} <: MOI.AbstractVectorSet +``` + + +DOCSTRING + +**Arguments:** +- `f::F`: DESCRIPTION + +- `dimension::Int`: DESCRIPTION + +- `MOIPredicate(f, dim = 0) = begin #= none:5 =# new{typeof(f)}(f, dim) end`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L74-L86) + +
+
+
+# CBLS.MOISequentialTasksType. + + + + +```julia +MOISequentialTasks <: MOI.AbstractVectorSet +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L492-L496) + +
+
+
+# CBLS.MOISumEqualParamType. + + + + +```julia +MOISumEqualParam{T <: Number} <: MOI.AbstractVectorSet +``` + + +DOCSTRING + +**Arguments:** +- `param::T`: DESCRIPTION + +- `dimension::Int`: DESCRIPTION + +- `MOISumEqualParam(param, dim = 0) = begin #= none:5 =# new{typeof(param)}(param, dim) end`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L350-L362) + +
+
+
+# CBLS.MinusEqualParamType. + + + + +Constraint ensuring that the value of `x` is less than a given parameter `param`. + +```julia +@constraint(model, x in MinusEqualParam(param)) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L479-L485) + +
+
+
+# CBLS.OptimizerType. + + + + +```julia +Optimizer(model = Model(); options = Options()) +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/MOI_wrapper.jl#L35-L39) + +
+
+
+# CBLS.OptimizerType. + + + + +```julia +Optimizer <: MOI.AbstractOptimizer +``` + + +DOCSTRING + +**Arguments:** +- `solver::Solver`: DESCRIPTION + +- `status::MOI.TerminationStatusCode`: DESCRIPTION + +- `options::Options`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/MOI_wrapper.jl#L19-L28) + +
+
+
+# CBLS.OrderedType. + + + + +Global constraint ensuring that all the values of `x` are ordered. + +```julia +@constraint(model, X in Ordered()) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L262-L268) + +
+
+
+# CBLS.PredicateType. + + + + +```julia +Predicate{F <: Function} <: JuMP.AbstractVectorSet +``` + + +Assuming `X` is a (collection of) variables, `concept` a boolean function over `X`, and that a `model` is defined. In `JuMP` syntax we can create a constraint based on `concept` as follows. + +```julia +@constraint(model, X in Predicate(concept)) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L105-L113) + +
+
+
+# CBLS.ScalarFunctionType. + + + + +```julia +ScalarFunction{F <: Function, V <: Union{Nothing, VOV}} <: MOI.AbstractScalarFunction +``` + + +A container to express any function with real value in JuMP syntax. Used with the `@objective` macro. + +**Arguments:** +- `f::F`: function to be applied to `X` + +- `X::V`: a subset of the variables of the model. + + +Given a `model`, and some (collection of) variables `X` to optimize. an objective function `f` can be added as follows. Note that only `Min` for minimization us currently defined. `Max` will come soon. + +```julia +# Applies to all variables in order of insertion. +# Recommended only when the function argument order does not matter. +@objective(model, ScalarFunction(f)) + +# Generic use +@objective(model, ScalarFunction(f, X)) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/objectives.jl#L9-L28) + +
+
+
+# CBLS.SequentialTasksType. + + + + +Local constraint ensuring that, given a vector `X` of size 4, `|X[1] - X[2]| ≠ |X[3] - X[4]|)`. + +```julia +@constraint(model, X in SequentialTasks()) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L512-L518) + +
+
+
+# CBLS.SumEqualParamType. + + + + +Global constraint ensuring that the sum of the values of `X` is equal to a given parameter `param`. + +```julia +@constraint(model, X in SumEqualParam(param)) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L385-L391) + +
+
+
+# Base.copyMethod. + + + + +```julia +Base.copy(set::MOIError) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L51-L55) + +
+
+
+# Base.copyMethod. + + + + +```julia +Base.copy(set::DiscreteSet) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/MOI_wrapper.jl#L107-L111) + +
+
+
+# JuMP.build_variableMethod. + + + + +```julia +JuMP.build_variable(::Function, info::JuMP.VariableInfo, set::T) where T <: MOI.AbstractScalarSet +``` + + +DOCSTRING + +**Arguments:** +- ``: DESCRIPTION + +- `info`: DESCRIPTION + +- `set`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/MOI_wrapper.jl#L1-L10) + +
+
+
+# MathOptInterface.add_constraintMethod. + + + + +```julia +MOI.add_constraint(optimizer::Optimizer, vars::MOI.VectorOfVariables, set::MOIError) +``` + + +DOCSTRING + +**Arguments:** +- `optimizer`: DESCRIPTION + +- `vars`: DESCRIPTION + +- `set`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L36-L45) + +
+
+
+# MathOptInterface.add_constraintMethod. + + + + +```julia +MOI.add_constraint(optimizer::Optimizer, v::VI, set::DiscreteSet{T}) where T <: Number +``` + + +DOCSTRING + +**Arguments:** +- `optimizer`: DESCRIPTION + +- `v`: DESCRIPTION + +- `set`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/variables.jl#L34-L43) + +
+
+
+# MathOptInterface.add_variableMethod. + + + + +```julia +MOI.add_variable(model::Optimizer) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/variables.jl#L2-L6) + +
+
+
+# MathOptInterface.empty!Method. + + + + +```julia +MOI.empty!(opt) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/MOI_wrapper.jl#L114-L118) + +
+
+
+# MathOptInterface.getMethod. + + + + +```julia +MOI.get(::Optimizer, ::MOI.SolverName) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/MOI_wrapper.jl#L59-L63) + +
+
+
+# MathOptInterface.is_emptyMethod. + + + + +```julia +MOI.is_empty(model::Optimizer) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/MOI_wrapper.jl#L78-L82) + +
+
+
+# MathOptInterface.optimize!Method. + + + + +```julia +MOI.optimize!(model::Optimizer) +``` + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/MOI_wrapper.jl#L93-L95) + +
+
+
+# MathOptInterface.setFunction. + + + + +```julia +MOI.set(::Optimizer, ::MOI.Silent, bool = true) = begin +``` + + +DOCSTRING + +**Arguments:** +- ``: DESCRIPTION + +- ``: DESCRIPTION + +- `bool`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/MOI_wrapper.jl#L66-L75) + +
+
+
+# MathOptInterface.setMethod. + + + + +```julia +MOI.set(model::Optimizer, p::MOI.RawOptimizerAttribute, value) +``` + + +Set a RawOptimizerAttribute to `value` + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/attributes.jl#L19-L22) + +
+
+
+# MathOptInterface.setMethod. + + + + +```julia +MOI.set(model::Optimizer, ::MOI.TimeLimitSec, value::Union{Nothing,Float64}) +``` + + +Set the time limit + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/attributes.jl#L7-L10) + +
+
+
+# MathOptInterface.supports_constraintMethod. + + + + +```julia +MOI.supports_constraint(::Optimizer, ::Type{VOV}, ::Type{MOIError}) = begin +``` + + +DOCSTRING + +**Arguments:** +- ``: DESCRIPTION + +- ``: DESCRIPTION + +- ``: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/constraints.jl#L21-L30) + +
+
+
+# MathOptInterface.supports_incremental_interfaceMethod. + + + + +Copy constructor for the optimizer + + +[source](https://github.com/JuliaConstraints/CBLS.jl/blob/v0.1.13/src/MOI_wrapper.jl#L85-L87) + +
+
diff --git a/dev/.documenter/solvers/intro.md b/dev/.documenter/solvers/intro.md new file mode 100644 index 0000000..ba43c19 --- /dev/null +++ b/dev/.documenter/solvers/intro.md @@ -0,0 +1,4 @@ + +# Solvers + +About solvers. diff --git a/dev/.documenter/solvers/local_search_solvers.md b/dev/.documenter/solvers/local_search_solvers.md new file mode 100644 index 0000000..7c1d120 --- /dev/null +++ b/dev/.documenter/solvers/local_search_solvers.md @@ -0,0 +1,2704 @@ + +# LocalSearchSolvers.jl + +Documentation for `LocalSearchSolvers.jl`. +
+# LocalSearchSolvers.AbstractSolverType. + + + + +```julia +AbstractSolver +``` + + +Abstract type to encapsulate the different solver types such as `Solver` or `_SubSolver`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L1-L4) + +
+
+
+# LocalSearchSolvers.ConstraintType. + + + + +```julia +Constraint{F <: Function} +``` + + +Structure to store an error function and the variables it constrains. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/constraint.jl#L1-L5) + +
+
+
+# LocalSearchSolvers.LeadSolverType. + + + + +```julia +LeadSolver <: MetaSolver +``` + + +Solver managed remotely by a MainSolver. Can manage its own set of local sub solvers. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solvers/lead.jl#L1-L4) + +
+
+
+# LocalSearchSolvers.MainSolverType. + + + + +```julia +MainSolver <: AbstractSolver +``` + + +Main solver. Handle the solving of a model, and optional multithreaded and/or distributed subsolvers. + +**Arguments:** +- `model::Model`: A formal description of the targeted problem + +- `state::_State`: An internal state to store the info necessary to a solving run + +- `options::Options`: User options for this solver + +- `subs::Vector{_SubSolver}`: Optional subsolvers + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solvers/main.jl#L1-L11) + +
+
+
+# LocalSearchSolvers.MetaSolverType. + + + + +Abstract type to encapsulate all solver types that manages other solvers. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solvers/meta.jl#L1-L3) + +
+
+
+# LocalSearchSolvers.ObjectiveType. + + + + +```julia +Objective{F <: Function} +``` + + +A structure to handle objectives in a solver. `struct Objective{F <: Function} name::String f::F end`` + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/objective.jl#L1-L10) + +
+
+
+# LocalSearchSolvers.ObjectiveMethod. + + + + +```julia +Objective(F, o::Objective{F2}) where {F2 <: Function} +``` + + +Constructor used in specializing a solver. Should never be called externally. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/objective.jl#L16-L19) + +
+
+
+# LocalSearchSolvers.OptionsType. + + + + +```julia +Options() +``` + + +**Arguments:** +- `dynamic::Bool`: is the model dynamic? + +- `iteration::Union{Int, Float64}`: limit on the number of iterations + +- `print_level::Symbol`: verbosity to choose among `:silent`, `:minimal`, `:partial`, `:verbose` + +- `solutions::Int`: number of solutions to return + +- `specialize::Bool`: should the types of the model be specialized or not. Usually yes for static problems. For dynamic in depends if the user intend to introduce new types. The specialized model is about 10% faster. + +- `tabu_time::Int`: DESCRIPTION + +- `tabu_local::Int`: DESCRIPTION + +- `tabu_delta::Float64`: DESCRIPTION + +- `threads::Int`: Number of threads to use + +- `time_limit::Float64`: time limit in seconds + +- `function Options(; dynamic = false, iteration = 10000, print_level = :minimal, solutions = 1, specialize = !dynamic, tabu_time = 0, tabu_local = 0, tabu_delta = 0.0, threads = typemax(0), time_limit = Inf) + + +```julia +# Setting options in JuMP syntax: print_level, time_limit, iteration +model = Model(CBLS.Optimizer) +set_optimizer_attribute(model, "iteration", 100) +set_optimizer_attribute(model, "print_level", :verbose) +set_time_limit_sec(model, 5.0) +``` + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L13-L35) + +
+
+
+# LocalSearchSolvers.VariableType. + + + + +```julia +Variable{D <: AbstractDomain} +``` + + +A structure containing the necessary information for a solver's variables: `name`, `domain`, and `constraints` it belongs. + +``` +struct Variable{D <: AbstractDomain} + domain::D + constraints::Indices{Int} +end +``` + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/variable.jl#L1-L10) + +
+
+
+# LocalSearchSolvers._ModelType. + + + + +```julia +_Model{V <: Variable{<:AbstractDomain},C <: Constraint{<:Function},O <: Objective{<:Function}} +``` + + +A struct to model a problem as a set of variables, domains, constraints, and objectives. + +``` +struct _Model{V <: Variable{<:AbstractDomain},C <: Constraint{<:Function},O <: Objective{<:Function}} + variables::Dictionary{Int,V} + constraints::Dictionary{Int,C} + objectives::Dictionary{Int,O} + + # counter to add new variables: vars, cons, objs + max_vars::Ref{Int} + max_cons::Ref{Int} + max_objs::Ref{Int} + + # Bool to indicate if the _Model instance has been specialized (relatively to types) + specialized::Ref{Bool} + + # Symbol to indicate the kind of model for specialized methods such as pretty printing + kind::Symbol +end +``` + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L1-L22) + +
+
+
+# LocalSearchSolvers._StateType. + + + + +```julia +GeneralState{T <: Number} +``` + + +A mutable structure to store the general state of a solver. All methods applied to `GeneralState` are forwarded to `S <: AbstractSolver`. + +``` +mutable struct GeneralState{T <: Number} <: AbstractState + configuration::Configuration{T} + cons_costs::Dictionary{Int, Float64} + last_improvement::Int + tabu::Dictionary{Int, Int} + vars_costs::Dictionary{Int, Float64} +end +``` + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L5-L17) + +
+
+
+# LocalSearchSolvers._SubSolverType. + + + + +```julia +_SubSolver <: AbstractSolver +``` + + +An internal solver type called by MetaSolver when multithreading is enabled. + +**Arguments:** +- `id::Int`: subsolver id for debugging + +- `model::Model`: a ref to the model of the main solver + +- `state::_State`: a `deepcopy` of the main solver that evolves independently + +- `options::Options`: a ref to the options of the main solver + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solvers/sub.jl#L1-L11) + +
+
+
+# Base.empty!Method. + + + + +```julia +empty!(s::Solver) +``` + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solvers/main.jl#L49-L52) + +
+
+
+# Base.empty!Method. + + + + +```julia +empty!(m::Model) +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L437-L441) + +
+
+
+# Base.inMethod. + + + + +```julia +var::Int ∈ c::Constraint +``` + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/constraint.jl#L43-L45) + +
+
+
+# Base.inMethod. + + + + +```julia +x::Variable ∈ constraint +value ∈ x::Variable +``` + + +Check if a variable `x` is restricted by a `constraint::Int`, or if a `value` belongs to the domain of `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/variable.jl#L52-L56) + +
+
+
+# LocalSearchSolvers._add!Method. + + + + +```julia +_add!(c::Constraint, x) +``` + + +Add the variable of indice `x` to `c`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/constraint.jl#L22-L26) + +
+
+
+# LocalSearchSolvers._add_to_constraint!Method. + + + + +```julia +_add_to_constraint!(x::Variable, id) +``` + + +Add a constraint `id` to the list of constraints of `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/variable.jl#L34-L37) + +
+
+
+# LocalSearchSolvers._check_restartMethod. + + + + +```julia +_check_restart(s) +``` + + +Check if a restart of `s` is necessary. If `s` has subsolvers, this check is independent for all of them. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L265-L269) + +
+
+
+# LocalSearchSolvers._check_subsMethod. + + + + +```julia +_check_subs(s) +``` + + +Check if any subsolver of a main solver `s`, for +- _Satisfaction_, has a solution, then return it, resume the run otherwise + +- _Optimization_, has a better solution, then assign it to its internal state + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L390-L396) + +
+
+
+# LocalSearchSolvers._compute!Method. + + + + +```julia +_compute!(s; o::Int = 1, cons_lst = Indices{Int}()) +``` + + +Compute the objective `o`'s value if `s` is satisfied and return the current `error`. + +**Arguments:** +- `s`: a solver + +- `o`: targeted objective + +- `cons_lst`: list of targeted constraints, if empty compute for the whole set + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L165-L174) + +
+
+
+# LocalSearchSolvers._compute_cost!Method. + + + + +```julia +_compute_cost!(s, ind, c) +``` + + +Compute the cost of constraint `c` with index `ind`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L121-L125) + +
+
+
+# LocalSearchSolvers._compute_costs!Method. + + + + +```julia +_compute_costs!(s; cons_lst::Indices{Int} = Indices{Int}()) +``` + + +Compute the cost of constraints `c` in `cons_lst`. If `cons_lst` is empty, compute the cost for all the constraints in `s`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L133-L137) + +
+
+
+# LocalSearchSolvers._compute_objective!Method. + + + + +```julia +_compute_objective!(s, o::Objective) +_compute_objective!(s, o = 1) +``` + + +Compute the objective `o`'s value. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L150-L155) + +
+
+
+# LocalSearchSolvers._cons_cost!Method. + + + + +```julia +_cons_cost!(s::S, c, cost) where S <: Union{_State, AbstractSolver} +``` + + +Set the `cost` of constraint `c`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L117-L120) + +
+
+
+# LocalSearchSolvers._cons_costMethod. + + + + +```julia +_cons_cost(s::S, c) where S <: Union{_State, AbstractSolver} +``` + + +Return the cost of constraint `c`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L99-L102) + +
+
+
+# LocalSearchSolvers._cons_costs!Method. + + + + +```julia +_cons_costs!(s::S, costs) where S <: Union{_State, AbstractSolver} +``` + + +Set the constraints costs. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L69-L72) + +
+
+
+# LocalSearchSolvers._cons_costsMethod. + + + + +```julia +_cons_costs(s::S) where S <: Union{_State, AbstractSolver} +``` + + +Access the constraints costs. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L45-L48) + +
+
+
+# LocalSearchSolvers._constrictionMethod. + + + + +```julia +_constriction(x::Variable) +``` + + +Return the `cosntriction` of `x`, i.e. the number of constraints restricting `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/variable.jl#L46-L49) + +
+
+
+# LocalSearchSolvers._delete!Method. + + + + +```julia +_delete!(c::Constraint, x::Int) +``` + + +Delete `x` from `c`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/constraint.jl#L29-L33) + +
+
+
+# LocalSearchSolvers._delete_from_constraint!Method. + + + + +```julia +_delete_from_constraint!(x::Variable, id) +``` + + +Delete a constraint `id` from the list of constraints of `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/variable.jl#L40-L43) + +
+
+
+# LocalSearchSolvers._draw!Method. + + + + +```julia +_draw!(s) +``` + + +Draw a random (re-)starting configuration. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L113-L116) + +
+
+
+# LocalSearchSolvers._dynamic!Method. + + + + +```julia +_dynamic!(options, dynamic) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L106-L110) + +
+
+
+# LocalSearchSolvers._dynamicMethod. + + + + +```julia +_dynamic(options) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L99-L103) + +
+
+
+# LocalSearchSolvers._find_rand_argmaxMethod. + + + + +```julia +_find_rand_argmax(d::DictionaryView) +``` + + +Compute `argmax` of `d` and select one element randomly. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/utils.jl#L7-L10) + +
+
+
+# LocalSearchSolvers._get_constraintsMethod. + + + + +```julia +_get_constraints(x::Variable) +``` + + +Access the list of `constraints` of `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/variable.jl#L28-L31) + +
+
+
+# LocalSearchSolvers._get_varsMethod. + + + + +```julia +_get_vars(c::Constraint) +``` + + +Returns the variables constrained by `c`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/constraint.jl#L15-L19) + +
+
+
+# LocalSearchSolvers._inc_cons!Method. + + + + +```julia +_inc_vars!(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Increment the maximum constraint id that has been attributed to `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L102-L105) + +
+
+
+# LocalSearchSolvers._inc_objs!Method. + + + + +```julia +_inc_vars!(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Increment the maximum objective id that has been attributed to `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L108-L111) + +
+
+
+# LocalSearchSolvers._inc_vars!Method. + + + + +```julia +_inc_vars!(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Increment the maximum variable id that has been attributed to `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L96-L99) + +
+
+
+# LocalSearchSolvers._info_path!Method. + + + + +```julia +_info_path!(options, iterations) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L120-L124) + +
+
+
+# LocalSearchSolvers._info_pathMethod. + + + + +```julia +_info_path(options, path) +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L113-L117) + +
+
+
+# LocalSearchSolvers._is_emptyMethod. + + + + +```julia +_is_empty(m::Model) +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L385-L389) + +
+
+
+# LocalSearchSolvers._iteration!Method. + + + + +```julia +_iteration!(options, iterations) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L134-L138) + +
+
+
+# LocalSearchSolvers._iterationMethod. + + + + +```julia +_iteration(options) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L127-L131) + +
+
+
+# LocalSearchSolvers._lengthMethod. + + + + +```julia +_length(c::Constraint) +``` + + +Return the number of constrained variables by `c`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/constraint.jl#L36-L40) + +
+
+
+# LocalSearchSolvers._max_consMethod. + + + + +```julia +_max_cons(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Access the maximum constraint id that has been attributed to `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L82-L85) + +
+
+
+# LocalSearchSolvers._max_objsMethod. + + + + +```julia +_max_objs(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Access the maximum objective id that has been attributed to `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L88-L91) + +
+
+
+# LocalSearchSolvers._max_varsMethod. + + + + +```julia +_max_vars(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Access the maximum variable id that has been attributed to `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L76-L79) + +
+
+
+# LocalSearchSolvers._move!Function. + + + + +```julia +_move!(s, x::Int, dim::Int = 0) +``` + + +Perform an improving move in `x` neighbourhood if possible. + +**Arguments:** +- `s`: a solver of type S <: AbstractSolver + +- `x`: selected variable id + +- `dim`: describe the dimension of the considered neighbourhood + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L285-L294) + +
+
+
+# LocalSearchSolvers._neighboursFunction. + + + + +```julia +_neighbours(s, x, dim = 0) +``` + + +DOCSTRING + +**Arguments:** +- `s`: DESCRIPTION + +- `x`: DESCRIPTION + +- `dim`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L185-L194) + +
+
+
+# LocalSearchSolvers._optimizing!Method. + + + + +```julia +_optimizing!(s::S) where S <: Union{_State, AbstractSolver} +``` + + +Set the solver `optimizing` status to `true`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L87-L90) + +
+
+
+# LocalSearchSolvers._optimizingMethod. + + + + +```julia +_optimizing(s::S) where S <: Union{_State, AbstractSolver} +``` + + +Check if `s` is in an optimizing state. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L63-L66) + +
+
+
+# LocalSearchSolvers._print_level!Method. + + + + +```julia +_print_level!(options, level) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L148-L152) + +
+
+
+# LocalSearchSolvers._print_levelMethod. + + + + +```julia +_print_level(options) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L141-L145) + +
+
+
+# LocalSearchSolvers._restart!Function. + + + + +```julia +_restart!(s, k = 10) +``` + + +Restart a solver. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L251-L255) + +
+
+
+# LocalSearchSolvers._satisfying!Method. + + + + +```julia +_satisfying!(s::S) where S <: Union{_State, AbstractSolver} +``` + + +Set the solver `optimizing` status to `false`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L93-L96) + +
+
+
+# LocalSearchSolvers._select_worseMethod. + + + + +```julia +_select_worse(s::S) where S <: Union{_State, AbstractSolver} +``` + + +Within the non-tabu variables, select the one with the worse error . + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L276-L279) + +
+
+
+# LocalSearchSolvers._set!Method. + + + + +```julia +_set!(s::S, x, val) where S <: Union{_State, AbstractSolver} +``` + + +Set the value of variable `x` to `val`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L135-L138) + +
+
+
+# LocalSearchSolvers._set_domain!Method. + + + + +```julia +_set_domain!(m::Model, x, values) +``` + + +DOCSTRING + +**Arguments:** +- `m`: DESCRIPTION + +- `x`: DESCRIPTION + +- `values`: DESCRIPTION + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L394-L403) + +
+
+
+# LocalSearchSolvers._solutions!Method. + + + + +```julia +_solutions!(options, solutions) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L162-L166) + +
+
+
+# LocalSearchSolvers._solutionsMethod. + + + + +```julia +_solutions(options) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L155-L159) + +
+
+
+# LocalSearchSolvers._specialize!Method. + + + + +```julia +_specialize!(options, specialize) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L176-L180) + +
+
+
+# LocalSearchSolvers._specializeMethod. + + + + +```julia +_specialize(options) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L169-L173) + +
+
+
+# LocalSearchSolvers._step!Method. + + + + +```julia +_step!(s) +``` + + +Iterate a step of the solver run. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L337-L341) + +
+
+
+# LocalSearchSolvers._swap_value!Method. + + + + +```julia +_set!(s::S, x, y) where S <: Union{_State, AbstractSolver} +``` + + +Swap the values of variables `x` and `y`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L141-L144) + +
+
+
+# LocalSearchSolvers._tabu_delta!Method. + + + + +```julia +_tabu_delta!(options, time) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L218-L222) + +
+
+
+# LocalSearchSolvers._tabu_deltaMethod. + + + + +```julia +_tabu_delta(options) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L211-L215) + +
+
+
+# LocalSearchSolvers._tabu_local!Method. + + + + +```julia +_tabu_local!(options, time) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L204-L208) + +
+
+
+# LocalSearchSolvers._tabu_localMethod. + + + + +```julia +_tabu_local(options) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L197-L201) + +
+
+
+# LocalSearchSolvers._tabu_time!Method. + + + + +```julia +_tabu_time!(options, time) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L190-L194) + +
+
+
+# LocalSearchSolvers._tabu_timeMethod. + + + + +```julia +_tabu_time(options) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L183-L187) + +
+
+
+# LocalSearchSolvers._threads!Method. + + + + +```julia +_threads!(options, threads) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L232-L236) + +
+
+
+# LocalSearchSolvers._threadsMethod. + + + + +```julia +_threads(options) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L225-L229) + +
+
+
+# LocalSearchSolvers._time_limit!Method. + + + + +```julia +_time_limit!(options, time::Time) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L246-L250) + +
+
+
+# LocalSearchSolvers._time_limitMethod. + + + + +```julia +_time_limit(options) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L239-L243) + +
+
+
+# LocalSearchSolvers._to_unionMethod. + + + + +```julia +_to_union(datatype) +``` + + +Make a minimal `Union` type from a collection of data types. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/utils.jl#L1-L4) + +
+
+
+# LocalSearchSolvers._value!Method. + + + + +```julia +_value!(s::S, x, val) where S <: Union{_State, AbstractSolver} +``` + + +Set the value of variable `x` to `val`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L129-L132) + +
+
+
+# LocalSearchSolvers._valueMethod. + + + + +```julia +_value(s::S, x) where S <: Union{_State, AbstractSolver} +``` + + +Return the value of variable `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L111-L114) + +
+
+
+# LocalSearchSolvers._values!Method. + + + + +```julia +_values!(s::S, values) where S <: Union{_State, AbstractSolver} +``` + + +Set the variables values. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L81-L84) + +
+
+
+# LocalSearchSolvers._valuesMethod. + + + + +```julia +_vars_costs(s::S) where S <: Union{_State, AbstractSolver} +``` + + +Access the variables costs. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L57-L60) + +
+
+
+# LocalSearchSolvers._var_cost!Method. + + + + +```julia +_var_cost!(s::S, x, cost) where S <: Union{_State, AbstractSolver} +``` + + +Set the `cost` of variable `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L123-L126) + +
+
+
+# LocalSearchSolvers._var_costMethod. + + + + +```julia +_var_cost(s::S, x) where S <: Union{_State, AbstractSolver} +``` + + +Return the cost of variable `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L105-L108) + +
+
+
+# LocalSearchSolvers._vars_costs!Method. + + + + +```julia +_vars_costs!(s::S, costs) where S <: Union{_State, AbstractSolver} +``` + + +Set the variables costs. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L75-L78) + +
+
+
+# LocalSearchSolvers._vars_costsMethod. + + + + +```julia +_vars_costs(s::S) where S <: Union{_State, AbstractSolver} +``` + + +Access the variables costs. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/state.jl#L51-L54) + +
+
+
+# LocalSearchSolvers._verboseMethod. + + + + +```julia +_verbose(settings, str) +``` + + +Temporary logging function. #TODO: use better log instead (LoggingExtra.jl) + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/options.jl#L90-L93) + +
+
+
+# LocalSearchSolvers.add!Method. + + + + +```julia +mts = - get_time_stamp(model) +``` + + +return TimeStamps(mts, mts, mts, mts, mts, mts, mts) end + +``` +add!(m::M, x) where M <: Union{Model, AbstractSolver} +add!(m::M, c) where M <: Union{Model, AbstractSolver} +add!(m::M, o) where M <: Union{Model, AbstractSolver} +``` + + +Add a variable `x`, a constraint `c`, or an objective `o` to `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L253-L262) + +
+
+
+# LocalSearchSolvers.add_value!Method. + + + + +```julia +add_value!(m::M, x, val) where M <: Union{Model, AbstractSolver} +``` + + +Add `val` to `x` domain. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L241-L244) + +
+
+
+# LocalSearchSolvers.add_var_to_cons!Method. + + + + +```julia +add_var_to_cons!(m::M, c, x) where M <: Union{Model, AbstractSolver} +``` + + +Add `x` to the constraint `c` list of restricted variables. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L247-L250) + +
+
+
+# LocalSearchSolvers.constraint!Method. + + + + +```julia +constraint!(m::M, func, vars) where M <: Union{Model, AbstractSolver} +``` + + +Add a constraint with an error function `func` defined over variables `vars`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L287-L290) + +
+
+
+# LocalSearchSolvers.constraintMethod. + + + + +```julia +constraint(f, vars) +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/constraint.jl#L48-L52) + +
+
+
+# LocalSearchSolvers.constrictionMethod. + + + + +```julia +constriction(m::M, x) where M <: Union{Model, AbstractSolver} +``` + + +Return the constriction of variable `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L223-L226) + +
+
+
+# LocalSearchSolvers.decay_tabu!Method. + + + + +```julia +_decay_tabu!(s::S) where S <: Union{_State, AbstractSolver} +``` + + +Decay the tabu list. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/strategies/tabu.jl#L77-L80) + +
+
+
+# LocalSearchSolvers.decrease_tabu!Method. + + + + +```julia +_decrease_tabu!(s::S, x) where S <: Union{_State, AbstractSolver} +``` + + +Decrement the tabu value of variable `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/strategies/tabu.jl#L44-L47) + +
+
+
+# LocalSearchSolvers.delete_tabu!Method. + + + + +```julia +_delete_tabu!(s::S, x) where S <: Union{_State, AbstractSolver} +``` + + +Delete the tabu entry of variable `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/strategies/tabu.jl#L50-L53) + +
+
+
+# LocalSearchSolvers.delete_value!Method. + + + + +```julia +delete_value(m::M, x, val) where M <: Union{Model, AbstractSolver} +``` + + +Delete `val` from `x` domain. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L229-L232) + +
+
+
+# LocalSearchSolvers.delete_var_from_cons!Method. + + + + +```julia +delete_var_from_cons(m::M, c, x) where M <: Union{Model, AbstractSolver} +``` + + +Delete `x` from the constraint `c` list of restricted variables. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L235-L238) + +
+
+
+# LocalSearchSolvers.describeMethod. + + + + +```julia +describe(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Describe the model. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L304-L307) + +
+
+
+# LocalSearchSolvers.domain_sizeMethod. + + + + +```julia +domain_size(m::Model, x) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L423-L427) + +
+
+
+# LocalSearchSolvers.drawMethod. + + + + +```julia +draw(m::M, x) where M <: Union{Model, AbstractSolver} +``` + + +Draw a random value of `x` domain. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L216-L219) + +
+
+
+# LocalSearchSolvers.empty_tabu!Method. + + + + +```julia +_empty_tabu!(s::S) where S <: Union{_State, AbstractSolver} +``` + + +Empty the tabu list. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/strategies/tabu.jl#L56-L59) + +
+
+
+# LocalSearchSolvers.get_cons_from_varMethod. + + + + +```julia +get_cons_from_var(m::M, x) where M <: Union{Model, AbstractSolver} +``` + + +Access the constraints restricting variable `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L168-L171) + +
+
+
+# LocalSearchSolvers.get_constraintMethod. + + + + +```julia +get_constraint(m::M, c) where M <: Union{Model, AbstractSolver} +``` + + +Access the constraint `c`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L144-L147) + +
+
+
+# LocalSearchSolvers.get_constraintsMethod. + + + + +```julia +get_constraints(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Access the constraints of `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L120-L123) + +
+
+
+# LocalSearchSolvers.get_domainMethod. + + + + +```julia +get_domain(m::M, x) where M <: Union{Model, AbstractSolver} +``` + + +Access the domain of variable `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L156-L159) + +
+
+
+# LocalSearchSolvers.get_kindMethod. + + + + +```julia +get_kind(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Access the kind of `m`, such as `:sudoku` or `:generic` (default). + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L132-L135) + +
+
+
+# LocalSearchSolvers.get_nameMethod. + + + + +```julia +get_name(m::M, x) where M <: Union{Model, AbstractSolver} +``` + + +Access the name of variable `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L162-L165) + +
+
+
+# LocalSearchSolvers.get_objectiveMethod. + + + + +```julia +get_objective(m::M, o) where M <: Union{Model, AbstractSolver} +``` + + +Access the objective `o`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L150-L153) + +
+
+
+# LocalSearchSolvers.get_objectivesMethod. + + + + +```julia +get_objectives(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Access the objectives of `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L126-L129) + +
+
+
+# LocalSearchSolvers.get_time_stampMethod. + + + + +```julia +get_time_stamp(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Access the time (since epoch) when the model was created. This time stamp is for internal performance measurement. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L180-L183) + +
+
+
+# LocalSearchSolvers.get_variableMethod. + + + + +```julia +get_variable(m::M, x) where M <: Union{Model, AbstractSolver} +``` + + +Access the variable `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L138-L141) + +
+
+
+# LocalSearchSolvers.get_variablesMethod. + + + + +```julia +get_variables(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Access the variables of `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L114-L117) + +
+
+
+# LocalSearchSolvers.get_vars_from_consMethod. + + + + +```julia +get_vars_from_cons(m::M, c) where M <: Union{Model, AbstractSolver} +``` + + +Access the variables restricted by constraint `c`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L174-L177) + +
+
+
+# LocalSearchSolvers.insert_tabu!Method. + + + + +```julia +_insert_tabu!(s::S, x, tabu_time) where S <: Union{_State, AbstractSolver} +``` + + +Insert the bariable `x` as tabu for `tabu_time`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/strategies/tabu.jl#L68-L71) + +
+
+
+# LocalSearchSolvers.is_satMethod. + + + + +```julia +is_sat(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Return `true` if `m` is a satisfaction model. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L336-L339) + +
+
+
+# LocalSearchSolvers.is_specializedMethod. + + + + +```julia +is_specialized(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Return `true` if the model is already specialized. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L342-L345) + +
+
+
+# LocalSearchSolvers.length_consMethod. + + + + +```julia +length_cons(m::M, c) where M <: Union{Model, AbstractSolver} +``` + + +Return the length of constraint `c`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L192-L195) + +
+
+
+# LocalSearchSolvers.length_consMethod. + + + + +```julia +length_cons(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Return the number of constraints in `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L210-L213) + +
+
+
+# LocalSearchSolvers.length_objsMethod. + + + + +```julia +length_objs(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Return the number of objectives in `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L198-L201) + +
+
+
+# LocalSearchSolvers.length_tabuMethod. + + + + +```julia +_length_tabu!(s::S) where S <: Union{_State, AbstractSolver} +``` + + +Return the length of the tabu list. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/strategies/tabu.jl#L62-L65) + +
+
+
+# LocalSearchSolvers.length_varMethod. + + + + +```julia +length_var(m::M, x) where M <: Union{Model, AbstractSolver} +``` + + +Return the domain length of variable `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L186-L189) + +
+
+
+# LocalSearchSolvers.length_varsMethod. + + + + +```julia +length_vars(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Return the number of variables in `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L204-L207) + +
+
+
+# LocalSearchSolvers.max_domains_sizeMethod. + + + + +```julia +max_domains_size(m::Model, vars) = begin +``` + + +DOCSTRING + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L430-L434) + +
+
+
+# LocalSearchSolvers.modelMethod. + + + + +```julia +model() +``` + + +Construct a _Model, empty by default. It is recommended to add the constraints, variables, and objectives from an empty _Model. The following keyword arguments are available, +- `vars=Dictionary{Int,Variable}()`: collection of variables + +- `cons=Dictionary{Int,Constraint}()`: collection of constraints + +- `objs=Dictionary{Int,Objective}()`: collection of objectives + +- `kind=:generic`: the kind of problem modeled (useful for specialized methods such as pretty printing) + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L50-L57) + +
+
+
+# LocalSearchSolvers.o_dist_extremaMethod. + + + + +```julia +dist_extrema(values::T...) where {T <: Number} +``` + + +Computes the distance between extrema in an ordered set. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/objectives/extrema.jl#L1-L4) + +
+
+
+# LocalSearchSolvers.o_mincutMethod. + + + + +```julia +o_mincut(graph, values; interdiction = 0) +``` + + +Compute the capacity of a cut (determined by the state of the solver) with a possible `interdiction` on the highest capacited links. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/objectives/cut.jl#L1-L4) + +
+
+
+# LocalSearchSolvers.objective!Method. + + + + +```julia +objective!(m::M, func) where M <: Union{Model, AbstractSolver} +``` + + +Add an objective evaluated by `func`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L296-L299) + +
+
+
+# LocalSearchSolvers.objectiveMethod. + + + + +```julia +objective(func, name) +``` + + +Construct an objective with a function `func` that should be applied to a collection of variables. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/objective.jl#L24-L27) + +
+
+
+# LocalSearchSolvers.post_processMethod. + + + + +```julia +post_process(s::MainSolver) +``` + + +Launch a series of tasks to round-up a solving run, for instance, export a run's info. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L450-L453) + +
+
+
+# LocalSearchSolvers.remote_dispatch!Method. + + + + +```julia +remote_dispatch!(solver) +``` + + +Starts the `LeadSolver`s attached to the `MainSolver`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L425-L428) + +
+
+
+# LocalSearchSolvers.remote_stop!Method. + + + + +```julia +remote_stop!!(solver) +``` + + +Fetch the pool of solutions from `LeadSolvers` and merge it into the `MainSolver`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L444-L447) + +
+
+
+# LocalSearchSolvers.solutionMethod. + + + + +```julia +solution(s) +``` + + +Return the only/best known solution of a satisfaction/optimization model. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L470-L473) + +
+
+
+# LocalSearchSolvers.solve_for_loop!Method. + + + + +```julia +solve_for_loop!(solver, stop, sat, iter) +``` + + +First loop in the solving process that starts `LeadSolver`s from the `MainSolver`, and `_SubSolver`s from each `MetaSolver`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L431-L434) + +
+
+
+# LocalSearchSolvers.solve_while_loop!Method. + + + + +```julia +solve_while_loop!(s, ) +``` + + +Search the space of configurations. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L405-L408) + +
+
+
+# LocalSearchSolvers.specialize!Method. + + + + +```julia +specialize!(solver) +``` + + +Replace the model of `solver` by one with specialized types (variables, constraints, objectives). + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L107-L110) + +
+
+
+# LocalSearchSolvers.specializeMethod. + + + + +```julia +specialize(m::M) where M <: Union{Model, AbstractSolver} +``` + + +Specialize the structure of a model to avoid dynamic type attribution at runtime. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L350-L353) + +
+
+
+# LocalSearchSolvers.statusMethod. + + + + +```julia +status(solver) +``` + + +Return the status of a MainSolver. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solvers/main.jl#L60-L63) + +
+
+
+# LocalSearchSolvers.stop_while_loopMethod. + + + + +```julia +stop_while_loop() +``` + + +Check the stop conditions of the `solve!` while inner loop. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/solver.jl#L399-L402) + +
+
+
+# LocalSearchSolvers.tabu_listMethod. + + + + +```julia +_tabu(s::S) where S <: Union{_State, AbstractSolver} +``` + + +Access the list of tabu variables. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/strategies/tabu.jl#L32-L35) + +
+
+
+# LocalSearchSolvers.tabu_valueMethod. + + + + +```julia +_tabu(s::S, x) where S <: Union{_State, AbstractSolver} +``` + + +Return the tabu value of variable `x`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/strategies/tabu.jl#L38-L41) + +
+
+
+# LocalSearchSolvers.variable!Function. + + + + +```julia +variable!(m::M, d) where M <: Union{Model, AbstractSolver} +``` + + +Add a variable with domain `d` to `m`. + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/model.jl#L278-L281) + +
+
+
+# LocalSearchSolvers.variableMethod. + + + + +```julia +variable(values::AbstractVector{T}, name::AbstractString; domain = :set) where T <: Number +variable(domain::AbstractDomain, name::AbstractString) where D <: AbstractDomain +``` + + +Construct a variable with discrete domain. See the `domain` method for other options. + +```julia +d = domain([1,2,3,4], types = :indices) +x1 = variable(d, "x1") +x2 = variable([-89,56,28], "x2", domain = :indices) +``` + + + +[source](https://github.com/JuliaConstraints/LocalSearchSolvers.jl/blob/v0.4.5/src/variable.jl#L60-L70) + +
+
diff --git a/dev/404.html b/dev/404.html deleted file mode 100644 index a91104c..0000000 --- a/dev/404.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - 404 | Julia Constraints - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/dev/assets/app.BR380OMv.js b/dev/assets/app.BR380OMv.js deleted file mode 100644 index cd93618..0000000 --- a/dev/assets/app.BR380OMv.js +++ /dev/null @@ -1 +0,0 @@ -import{j as o,a8 as p,a9 as u,aa as l,ab as c,ac as f,ad as d,ae as m,af as h,ag as g,ah as A,Y as P,d as _,u as v,l as R,z as w,ai as y,aj as C,ak as E,a6 as b}from"./chunks/framework.aA95Gx5L.js";import{R as T}from"./chunks/theme.DQqwdnSU.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(T),S=_({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=v();return R(()=>{w(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&y(),C(),E(),s.setup&&s.setup(),()=>b(s.Layout)}});async function j(){globalThis.__VITEPRESS__=!0;const e=L(),a=D();a.provide(u,e);const t=l(e.route);return a.provide(c,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return h(S)}function L(){let e=o,a;return g(t=>{let n=A(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=P(()=>import(n),[])),o&&(e=!1),r},s.NotFound)}o&&j().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{j as createApp}; diff --git a/dev/assets/chunks/@localSearchIndexroot.CHYlrtr2.js b/dev/assets/chunks/@localSearchIndexroot.CHYlrtr2.js deleted file mode 100644 index 92ee6a0..0000000 --- a/dev/assets/chunks/@localSearchIndexroot.CHYlrtr2.js +++ /dev/null @@ -1 +0,0 @@ -const i='{"documentCount":128,"nextId":128,"documentIds":{"0":"/dev/constraints/comparison_constraints#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia","1":"/dev/constraints/comparison_constraints#Comparison-based-Constraints","2":"/dev/constraints/connection_constraints#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia","3":"/dev/constraints/connection_constraints#Connection-Constraints","4":"/dev/constraints/constraint_commons#ConstraintCommons.jl","5":"/dev/constraints/constraint_commons#Key-Features-and-Functionalities","6":"/dev/constraints/constraint_commons#Parameters","7":"/dev/constraints/constraint_commons#Performances-–-TODO","8":"/dev/constraints/constraint_commons#Languages","9":"/dev/constraints/constraint_commons#Performances-–-TODO-2","10":"/dev/constraints/constraint_commons#Extensions","11":"/dev/constraints/constraint_commons#Performances-–-TODO-3","12":"/dev/constraints/constraint_commons#Sampling","13":"/dev/constraints/constraint_commons#Performances-–-TODO-4","14":"/dev/constraints/constraint_commons#Extrema","15":"/dev/constraints/constraint_commons#Performances-–-TODO-5","16":"/dev/constraints/constraint_commons#Dictionaries","17":"/dev/constraints/constraint_commons#Performances-–-TODO-6","18":"/dev/constraints/constraint_domains#ConstraintDomains.jl:-Defining-and-Exploring-Variable-Domains-within-JuliaConstraints","19":"/dev/constraints/constraint_domains#Key-Features-and-Functionalities","20":"/dev/constraints/constraint_domains#Empowering-Constraint-Programming-in-Julia","21":"/dev/constraints/constraint_domains#Commons","22":"/dev/constraints/constraint_domains#Extension-to-Base-module","23":"/dev/constraints/constraint_domains#Performances","24":"/dev/constraints/constraint_domains#Continuous","25":"/dev/constraints/constraint_domains#Extension-to-Base-module-2","26":"/dev/constraints/constraint_domains#Discrete","27":"/dev/constraints/constraint_domains#Extension-to-Base-module-3","28":"/dev/constraints/constraint_domains#General","29":"/dev/constraints/constraint_domains#Exploration","30":"/dev/constraints/constraint_domains#Parameters","31":"/dev/constraints/constraint_models#ConstraintModels.jl","32":"/dev/constraints/constraints#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia","33":"/dev/constraints/constraints#Key-Features-and-Functionalities","34":"/dev/constraints/constraints#Enabling-Advanced-Modeling-in-Constraint-Programming","35":"/dev/constraints/constraints#Basic-tools","36":"/dev/constraints/constraints#Usual-constraints-(based-on-and-including-XCSP3-core-categories)","37":"/dev/constraints/counting_summing_constraints#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia","38":"/dev/constraints/counting_summing_constraints#Counting-and-Summing-Constraints","39":"/dev/constraints/elementary_constraints#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia","40":"/dev/constraints/elementary_constraints#Elementary-Constraints","41":"/dev/constraints/generic_constraints#Generic-Constraints","42":"/dev/constraints/generic_constraints#Intention-Constraints","43":"/dev/constraints/generic_constraints#Defining-an-intention-constraint-in-JC-API","44":"/dev/constraints/generic_constraints#APIs","45":"/dev/constraints/generic_constraints#Test-for-DocumenterVitePress-Issue","46":"/dev/constraints/generic_constraints#Specific-documentation","47":"/dev/constraints/generic_constraints#Extension-Constraints","48":"/dev/constraints/graph_constraints#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia","49":"/dev/constraints/graph_constraints#Constraints-on-Graphs","50":"/dev/constraints/intro#Introduction-to-basics-cosntraints-related-tools","51":"/dev/constraints/language_constraints#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia","52":"/dev/constraints/language_constraints#Constraints-defined-from-Languages","53":"/dev/constraints/packing_scheduling_constraints#Constraints.jl:-Streamlining-Constraint-Definition-and-Integration-in-Julia","54":"/dev/constraints/packing_scheduling_constraints#Packing-and-Scheduling-Constraints","55":"/dev/cp/advanced#Advanced-Constraint-Programming-Techniques","56":"/dev/cp/advanced#Global-Constraints-and-Their-Uses","57":"/dev/cp/advanced#Search-Strategies-and-Optimization","58":"/dev/cp/applications#Applying-Optimization-Methods","59":"/dev/cp/applications#Case-Studies-and-Real-World-Applications","60":"/dev/cp/applications#From-Theory-to-Practice","61":"/dev/cp/contribution#Community-and-Contribution","62":"/dev/cp/contribution#Joining-the-JuliaConstraint-Community","63":"/dev/cp/contribution#Future-Directions","64":"/dev/cp/cp101#Constraint-Programming-101","65":"/dev/cp/cp101#What-is-Constraint-Programming?","66":"/dev/cp/cp101#Basic-Concepts-and-Terminology","67":"/dev/cp/cp101#How-CP-differs-from-other-optimization-techniques","68":"/dev/cp/ecosystem#Exploring-JuliaConstraint-Packages","69":"/dev/cp/ecosystem#Package-Overviews","70":"/dev/cp/ecosystem#Installation-and-Getting-Started-Guides","71":"/dev/cp/getting_started#Getting-Started-with-Julia-for-CP-and-Optimization","72":"/dev/cp/getting_started#Why-Julia?","73":"/dev/cp/getting_started#Setting-Up-Your-Julia-Environment","74":"/dev/cp/getting_started#Your-First-Julia-CP-Model","75":"/dev/cp/intro#Welcome-to-Julia-Constraints","76":"/dev/cp/models#Building-and-Analyzing-Models","77":"/dev/cp/models#Modeling-Best-Practices","78":"/dev/cp/models#Performance-Analysis-and-Improvement","79":"/dev/cp/opt#Dive-into-Optimization","80":"/dev/cp/opt#Understanding-Optimization","81":"/dev/cp/opt#Metaheuristics-Overview","82":"/dev/cp/opt#Mathematical-Programming-Basics","83":"/dev/cp/tuto_xp#Tutorials-and-Experiments","84":"/dev/cp/tuto_xp#Hands-On-Tutorials","85":"/dev/cp/tuto_xp#Experimental-Analysis","86":"/dev/full_api#Full-API","87":"/dev/index-old#JuliaConstraints","88":"/dev/index-old#Operational-Research-vs-Constraint-Programming","89":"/dev/index-old#Constraint-Based-Local-Search","90":"/dev/learning/aggregation#Aggregation-Layer","91":"/dev/learning/aggregation#List-of-aggregations","92":"/dev/learning/aggregation#Layer-generation","93":"/dev/learning/arithmetic#Arithmetic-Layer","94":"/dev/learning/arithmetic#List-of-arithmetic-operations","95":"/dev/learning/arithmetic#Layer-generation","96":"/dev/learning/comparison#Comparison-Layer","97":"/dev/learning/comparison#List-of-comparisons","98":"/dev/learning/comparison#Non-parametric","99":"/dev/learning/comparison#Param:-:val","100":"/dev/learning/comparison#Layer-generation","101":"/dev/learning/compositional_networks#CompositionalNetworks.jl","102":"/dev/learning/compositional_networks#Utilities","103":"/dev/learning/compositional_networks#Metrics","104":"/dev/learning/constraint_learning#ConstraintLearning.jl","105":"/dev/learning/intro#Learning-about-Constraints","106":"/dev/learning/layers#A-layer-structure-for-any-ICN","107":"/dev/learning/qubo_constraints#Introduction-to-QUBOConstraints.jl","108":"/dev/learning/qubo_constraints#Basic-features","109":"/dev/learning/qubo_encoding#Encoding-for-QUBO-programs","110":"/dev/learning/qubo_learning#Learning-QUBO-matrices","111":"/dev/learning/qubo_learning#Interface","112":"/dev/learning/qubo_learning#Examples-with-various-optimizers","113":"/dev/learning/qubo_learning#Gradient-Descent","114":"/dev/learning/qubo_learning#Constraint-based-Local-Search","115":"/dev/learning/transformation#Transformations-Layer","116":"/dev/learning/transformation#List-of-transformations","117":"/dev/learning/transformation#Non-parametric","118":"/dev/learning/transformation#Param:-:val","119":"/dev/learning/transformation#Layer-generation","120":"/dev/meta/meta_strategist#MetaStrategist.jl","121":"/dev/perf/benchmark_ext#BenchmarkTools-Extension","122":"/dev/perf/perf_checker#PerfChecker.jl","123":"/dev/perf/perf_interface#Interfacing-PerfChecker","124":"/dev/public_api#Public-API","125":"/dev/solvers/cbls#CBLS.jl","126":"/dev/solvers/intro#Solvers","127":"/dev/solvers/local_search_solvers#LocalSearchSolvers.jl"},"fieldIds":{"title":0,"titles":1,"text":2},"fieldLength":{"0":[9,1,1],"1":[3,10,75],"2":[9,1,1],"3":[2,10,98],"4":[2,1,46],"5":[4,2,162],"6":[1,2,80],"7":[2,3,1],"8":[1,2,93],"9":[2,3,1],"10":[1,2,21],"11":[2,3,1],"12":[1,2,42],"13":[2,3,1],"14":[1,2,31],"15":[2,3,1],"16":[1,2,36],"17":[2,3,1],"18":[9,1,42],"19":[4,9,167],"20":[5,9,54],"21":[1,9,136],"22":[4,10,86],"23":[1,10,1],"24":[1,9,127],"25":[4,10,93],"26":[1,9,138],"27":[4,10,97],"28":[1,9,19],"29":[1,9,96],"30":[1,9,115],"31":[2,1,297],"32":[9,1,39],"33":[4,9,169],"34":[6,9,56],"35":[2,9,184],"36":[10,9,207],"37":[9,1,1],"38":[4,10,134],"39":[9,1,1],"40":[2,10,57],"41":[2,1,17],"42":[2,2,77],"43":[7,3,69],"44":[1,3,75],"45":[4,3,13],"46":[2,3,77],"47":[2,2,55],"48":[9,1,1],"49":[3,10,71],"50":[6,1,3],"51":[9,1,1],"52":[4,10,126],"53":[9,1,1],"54":[4,10,106],"55":[4,1,1],"56":[5,4,12],"57":[4,4,12],"58":[3,1,1],"59":[6,3,11],"60":[4,3,18],"61":[3,1,1],"62":[4,3,14],"63":[2,3,13],"64":[3,1,1],"65":[5,3,10],"66":[4,3,10],"67":[7,3,10],"68":[3,1,1],"69":[2,3,13],"70":[5,1,13],"71":[8,1,1],"72":[3,8,16],"73":[5,8,103],"74":[5,8,190],"75":[4,1,35],"76":[4,1,1],"77":[3,4,12],"78":[4,4,11],"79":[3,1,1],"80":[2,3,12],"81":[2,3,11],"82":[3,3,12],"83":[3,1,1],"84":[3,3,11],"85":[2,3,15],"86":[2,1,1145],"87":[1,1,122],"88":[5,2,93],"89":[4,2,80],"90":[2,1,11],"91":[3,2,26],"92":[2,2,26],"93":[2,1,11],"94":[4,2,22],"95":[2,2,25],"96":[2,1,11],"97":[3,2,10],"98":[2,5,53],"99":[2,5,34],"100":[2,5,49],"101":[2,1,5],"102":[1,2,93],"103":[1,2,45],"104":[2,1,232],"105":[3,1,6],"106":[6,1,144],"107":[4,1,5],"108":[2,4,35],"109":[4,1,64],"110":[3,1,1],"111":[1,3,31],"112":[4,3,1],"113":[2,7,102],"114":[4,7,1],"115":[2,1,30],"116":[3,2,10],"117":[2,5,66],"118":[2,5,58],"119":[2,5,157],"120":[2,1,5],"121":[2,1,26],"122":[2,1,54],"123":[2,1,18],"124":[2,1,596],"125":[2,1,251],"126":[1,1,3],"127":[2,1,504]},"averageFieldLength":[3.328125,3.6249999999999982,66.67187500000001],"storedFields":{"0":{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","titles":[]},"1":{"title":"Comparison-based Constraints","titles":["Constraints.jl: Streamlining Constraint Definition and Integration in Julia",null]},"2":{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","titles":[]},"3":{"title":"Connection Constraints","titles":["Constraints.jl: Streamlining Constraint Definition and Integration in Julia",null]},"4":{"title":"ConstraintCommons.jl","titles":[]},"5":{"title":"Key Features and Functionalities","titles":["ConstraintCommons.jl"]},"6":{"title":"Parameters","titles":["ConstraintCommons.jl"]},"7":{"title":"Performances – TODO","titles":["ConstraintCommons.jl","Parameters"]},"8":{"title":"Languages","titles":["ConstraintCommons.jl"]},"9":{"title":"Performances – TODO","titles":["ConstraintCommons.jl","Languages"]},"10":{"title":"Extensions","titles":["ConstraintCommons.jl"]},"11":{"title":"Performances – TODO","titles":["ConstraintCommons.jl","Extensions"]},"12":{"title":"Sampling","titles":["ConstraintCommons.jl"]},"13":{"title":"Performances – TODO","titles":["ConstraintCommons.jl","Sampling"]},"14":{"title":"Extrema","titles":["ConstraintCommons.jl"]},"15":{"title":"Performances – TODO","titles":["ConstraintCommons.jl","Extrema"]},"16":{"title":"Dictionaries","titles":["ConstraintCommons.jl"]},"17":{"title":"Performances – TODO","titles":["ConstraintCommons.jl","Dictionaries"]},"18":{"title":"ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints","titles":[]},"19":{"title":"Key Features and Functionalities","titles":["ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints"]},"20":{"title":"Empowering Constraint Programming in Julia","titles":["ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints"]},"21":{"title":"Commons","titles":["ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints"]},"22":{"title":"Extension to Base module","titles":["ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints","Commons"]},"23":{"title":"Performances","titles":["ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints","Commons"]},"24":{"title":"Continuous","titles":["ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints"]},"25":{"title":"Extension to Base module","titles":["ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints","Continuous"]},"26":{"title":"Discrete","titles":["ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints"]},"27":{"title":"Extension to Base module","titles":["ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints","Discrete"]},"28":{"title":"General","titles":["ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints"]},"29":{"title":"Exploration","titles":["ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints"]},"30":{"title":"Parameters","titles":["ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints"]},"31":{"title":"ConstraintModels.jl","titles":[]},"32":{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","titles":[]},"33":{"title":"Key Features and Functionalities","titles":["Constraints.jl: Streamlining Constraint Definition and Integration in Julia"]},"34":{"title":"Enabling Advanced Modeling in Constraint Programming","titles":["Constraints.jl: Streamlining Constraint Definition and Integration in Julia"]},"35":{"title":"Basic tools","titles":["Constraints.jl: Streamlining Constraint Definition and Integration in Julia"]},"36":{"title":"Usual constraints (based on and including XCSP3-core categories)","titles":["Constraints.jl: Streamlining Constraint Definition and Integration in Julia"]},"37":{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","titles":[]},"38":{"title":"Counting and Summing Constraints","titles":["Constraints.jl: Streamlining Constraint Definition and Integration in Julia",null]},"39":{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","titles":[]},"40":{"title":"Elementary Constraints","titles":["Constraints.jl: Streamlining Constraint Definition and Integration in Julia",null]},"41":{"title":"Generic Constraints","titles":[]},"42":{"title":"Intention Constraints","titles":["Generic Constraints"]},"43":{"title":"Defining an intention constraint in JC-API","titles":["Generic Constraints","Intention Constraints"]},"44":{"title":"APIs","titles":["Generic Constraints","Intention Constraints"]},"45":{"title":"Test for DocumenterVitePress Issue","titles":["Generic Constraints","Intention Constraints"]},"46":{"title":"Specific documentation","titles":["Generic Constraints","Intention Constraints"]},"47":{"title":"Extension Constraints","titles":["Generic Constraints"]},"48":{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","titles":[]},"49":{"title":"Constraints on Graphs","titles":["Constraints.jl: Streamlining Constraint Definition and Integration in Julia",null]},"50":{"title":"Introduction to basics cosntraints related tools","titles":[]},"51":{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","titles":[]},"52":{"title":"Constraints defined from Languages","titles":["Constraints.jl: Streamlining Constraint Definition and Integration in Julia",null]},"53":{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","titles":[]},"54":{"title":"Packing and Scheduling Constraints","titles":["Constraints.jl: Streamlining Constraint Definition and Integration in Julia",null]},"55":{"title":"Advanced Constraint Programming Techniques","titles":[]},"56":{"title":"Global Constraints and Their Uses","titles":["Advanced Constraint Programming Techniques"]},"57":{"title":"Search Strategies and Optimization","titles":["Advanced Constraint Programming Techniques"]},"58":{"title":"Applying Optimization Methods","titles":[]},"59":{"title":"Case Studies and Real-World Applications","titles":["Applying Optimization Methods"]},"60":{"title":"From Theory to Practice","titles":["Applying Optimization Methods"]},"61":{"title":"Community and Contribution","titles":[]},"62":{"title":"Joining the JuliaConstraint Community","titles":["Community and Contribution"]},"63":{"title":"Future Directions","titles":["Community and Contribution"]},"64":{"title":"Constraint Programming 101","titles":[]},"65":{"title":"What is Constraint Programming?","titles":["Constraint Programming 101"]},"66":{"title":"Basic Concepts and Terminology","titles":["Constraint Programming 101"]},"67":{"title":"How CP differs from other optimization techniques","titles":["Constraint Programming 101"]},"68":{"title":"Exploring JuliaConstraint Packages","titles":[]},"69":{"title":"Package Overviews","titles":["Exploring JuliaConstraint Packages"]},"70":{"title":"Installation and Getting Started Guides","titles":[]},"71":{"title":"Getting Started with Julia for CP and Optimization","titles":[]},"72":{"title":"Why Julia?","titles":["Getting Started with Julia for CP and Optimization"]},"73":{"title":"Setting Up Your Julia Environment","titles":["Getting Started with Julia for CP and Optimization"]},"74":{"title":"Your First Julia CP Model","titles":["Getting Started with Julia for CP and Optimization"]},"75":{"title":"Welcome to Julia Constraints","titles":[]},"76":{"title":"Building and Analyzing Models","titles":[]},"77":{"title":"Modeling Best Practices","titles":["Building and Analyzing Models"]},"78":{"title":"Performance Analysis and Improvement","titles":["Building and Analyzing Models"]},"79":{"title":"Dive into Optimization","titles":[]},"80":{"title":"Understanding Optimization","titles":["Dive into Optimization"]},"81":{"title":"Metaheuristics Overview","titles":["Dive into Optimization"]},"82":{"title":"Mathematical Programming Basics","titles":["Dive into Optimization"]},"83":{"title":"Tutorials and Experiments","titles":[]},"84":{"title":"Hands-On Tutorials","titles":["Tutorials and Experiments"]},"85":{"title":"Experimental Analysis","titles":["Tutorials and Experiments"]},"86":{"title":"Full API","titles":[]},"87":{"title":"JuliaConstraints","titles":[null]},"88":{"title":"Operational Research vs Constraint Programming","titles":[null,"JuliaConstraints"]},"89":{"title":"Constraint-Based Local Search","titles":[null,"JuliaConstraints"]},"90":{"title":"Aggregation Layer","titles":[]},"91":{"title":"List of aggregations","titles":["Aggregation Layer"]},"92":{"title":"Layer generation","titles":["Aggregation Layer"]},"93":{"title":"Arithmetic Layer","titles":[]},"94":{"title":"List of arithmetic operations","titles":["Arithmetic Layer"]},"95":{"title":"Layer generation","titles":["Arithmetic Layer"]},"96":{"title":"Comparison Layer","titles":[]},"97":{"title":"List of comparisons","titles":["Comparison Layer"]},"98":{"title":"Non-parametric","titles":["Comparison Layer","List of comparisons"]},"99":{"title":"Param: :val","titles":["Comparison Layer","List of comparisons"]},"100":{"title":"Layer generation","titles":["Comparison Layer","List of comparisons"]},"101":{"title":"CompositionalNetworks.jl","titles":[]},"102":{"title":"Utilities","titles":["CompositionalNetworks.jl"]},"103":{"title":"Metrics","titles":["CompositionalNetworks.jl"]},"104":{"title":"ConstraintLearning.jl","titles":[]},"105":{"title":"Learning about Constraints","titles":[]},"106":{"title":"A layer structure for any ICN","titles":[]},"107":{"title":"Introduction to QUBOConstraints.jl","titles":[]},"108":{"title":"Basic features","titles":["Introduction to QUBOConstraints.jl"]},"109":{"title":"Encoding for QUBO programs","titles":[]},"110":{"title":"Learning QUBO matrices","titles":[]},"111":{"title":"Interface","titles":["Learning QUBO matrices"]},"112":{"title":"Examples with various optimizers","titles":["Learning QUBO matrices"]},"113":{"title":"Gradient Descent","titles":["Learning QUBO matrices","Examples with various optimizers"]},"114":{"title":"Constraint-based Local Search","titles":["Learning QUBO matrices","Examples with various optimizers"]},"115":{"title":"Transformations Layer","titles":[]},"116":{"title":"List of transformations","titles":["Transformations Layer"]},"117":{"title":"Non-parametric","titles":["Transformations Layer","List of transformations"]},"118":{"title":"Param: :val","titles":["Transformations Layer","List of transformations"]},"119":{"title":"Layer generation","titles":["Transformations Layer","List of transformations"]},"120":{"title":"MetaStrategist.jl","titles":[]},"121":{"title":"BenchmarkTools Extension","titles":[]},"122":{"title":"PerfChecker.jl","titles":[]},"123":{"title":"Interfacing PerfChecker","titles":[]},"124":{"title":"Public API","titles":[]},"125":{"title":"CBLS.jl","titles":[]},"126":{"title":"Solvers","titles":[]},"127":{"title":"LocalSearchSolvers.jl","titles":[]}},"dirtCount":0,"index":[["θ",{"2":{"113":2}}],["≥",{"2":{"113":1}}],["^2",{"2":{"113":1}}],["η",{"2":{"104":1,"113":6}}],["σ",{"2":{"86":2,"108":2,"124":2}}],["∉",{"2":{"86":3}}],["⋯",{"2":{"74":2}}],["×",{"2":{"74":3}}],["+",{"2":{"46":2,"86":9,"87":1,"91":1,"117":2,"118":4}}],[">",{"2":{"44":2,"49":1,"86":1,"113":8}}],["≠",{"2":{"43":1,"44":1,"125":2}}],["|",{"2":{"125":4}}],["||",{"2":{"86":2}}],["|the",{"2":{"43":1}}],["|≠|x",{"2":{"43":1}}],["|x",{"2":{"43":1,"125":4}}],["−x",{"2":{"43":2}}],["yes",{"2":{"127":1}}],["yet",{"2":{"19":1,"21":1,"24":1,"31":1,"33":1,"86":2}}],["you",{"2":{"87":1}}],["your",{"0":{"73":1,"74":1}}],["y",{"2":{"42":2,"44":5,"47":1,"87":1,"104":4,"113":7,"127":2}}],["y=1",{"2":{"36":1,"86":1}}],["7",{"2":{"31":3,"38":2,"54":3,"86":5,"122":1}}],["`function",{"2":{"127":1}}],["`struct",{"2":{"127":1}}],["``",{"2":{"125":6}}],["`",{"2":{"52":1,"86":1,"104":1}}],["`automaton`",{"2":{"52":1,"86":1}}],["`x`",{"2":{"52":2,"86":2}}],["`grid`",{"2":{"31":1}}],["`m`",{"2":{"31":1}}],["`rangedomain``",{"2":{"21":1,"24":1,"26":1,"86":1,"124":1}}],["q",{"2":{"104":7,"113":18}}],["qap",{"2":{"31":1}}],["qubooptimizer",{"2":{"104":2}}],["qubogradientoptimizer",{"2":{"104":4}}],["qubo",{"0":{"109":1,"110":1},"1":{"111":1,"112":1,"113":1,"114":1},"2":{"86":5,"104":4,"108":4,"111":1,"124":2}}],["quboconstraints",{"0":{"107":1},"1":{"108":1},"2":{"5":1,"86":7,"104":1,"107":1,"108":2,"109":3,"111":2,"113":1,"124":5}}],["quite",{"2":{"74":1}}],["quot",{"2":{"35":6,"54":4,"74":6,"86":10,"87":4}}],["quadractic",{"2":{"31":1}}],["queens",{"2":{"31":6}}],["zeros",{"2":{"113":3}}],["zero",{"2":{"31":1,"54":11,"86":11}}],["≤",{"2":{"22":4,"25":4,"27":4,"54":1,"74":2,"86":5}}],["9×9",{"2":{"31":4}}],["9",{"2":{"21":1,"24":1,"26":1,"31":4,"74":7,"86":1,"124":1}}],["8",{"2":{"31":3,"38":5,"54":1,"86":6}}],["86",{"2":{"21":1,"24":1,"26":1,"86":1,"124":1}}],["89",{"2":{"21":2,"24":2,"26":2,"86":2,"124":2,"127":1}}],["∈",{"2":{"19":1,"21":1,"22":7,"25":7,"27":7,"86":8,"124":1,"127":3}}],["δ",{"2":{"14":1,"86":1,"104":1,"113":1,"124":1}}],["heavily",{"2":{"115":1}}],["helps",{"2":{"87":1}}],["help",{"2":{"87":2,"88":1}}],["heuristic",{"2":{"74":1,"89":2}}],["heights",{"2":{"54":5,"86":5}}],["here",{"2":{"36":1,"44":1,"86":1}}],["highly",{"2":{"106":1}}],["highlight",{"2":{"75":1}}],["highlighting",{"2":{"62":1,"72":1}}],["high",{"2":{"87":1}}],["higher",{"2":{"42":1,"44":1}}],["highest",{"2":{"21":1,"24":1,"26":1,"86":1,"124":1,"127":1}}],["hide",{"2":{"46":2,"86":2}}],["https",{"2":{"36":1,"86":1,"124":1}}],["hot",{"2":{"86":3,"109":3,"113":1,"124":3}}],["hosts",{"2":{"87":1}}],["host",{"2":{"73":1}}],["however",{"2":{"74":1}}],["how",{"0":{"67":1},"2":{"33":1,"42":1,"43":1,"44":2,"56":1,"62":1,"78":1,"85":1,"97":1,"116":1}}],["holds",{"2":{"87":1}}],["hold",{"2":{"3":4,"86":4,"104":1}}],["hamming",{"2":{"86":4,"103":2,"104":3,"124":4}}],["hand",{"2":{"88":1}}],["hands",{"0":{"84":1}}],["handling",{"2":{"32":1,"33":2}}],["handled",{"2":{"24":1,"86":1}}],["handle",{"2":{"21":1,"44":2,"86":1,"127":2}}],["handles",{"2":{"19":1}}],["hardware",{"2":{"73":1}}],["have",{"2":{"31":2,"36":1,"46":1,"59":1,"73":1,"86":6,"89":1,"102":2,"124":4}}],["half",{"2":{"29":1,"86":1,"124":1}}],["has",{"2":{"12":1,"36":3,"74":1,"86":6,"106":1,"109":1,"121":1,"124":2,"127":10}}],["keep",{"2":{"86":1,"108":1}}],["keywords",{"2":{"86":1,"124":1}}],["keyword",{"2":{"35":2,"36":8,"86":9,"124":1,"127":1}}],["key",{"0":{"5":1,"19":1,"33":1},"2":{"36":2,"66":1,"86":2}}],["k",{"2":{"86":2,"94":2,"127":1}}],["known",{"2":{"31":1,"38":3,"86":5,"124":2,"127":1}}],["kind=",{"2":{"127":1}}],["kind",{"2":{"14":1,"29":1,"30":1,"86":2,"124":1,"127":6}}],["kinds",{"2":{"8":1}}],["kargs",{"2":{"6":1,"35":6,"36":5,"86":7,"104":6,"124":5}}],["wrappers",{"2":{"87":1}}],["wrapping",{"2":{"87":1}}],["write",{"2":{"86":2,"87":1,"124":2}}],["was",{"2":{"123":1,"127":1}}],["way",{"2":{"36":1,"42":1,"44":1,"47":1,"86":3}}],["warning",{"2":{"31":2,"35":1,"86":1}}],["would",{"2":{"36":1,"86":1}}],["worse",{"2":{"127":3}}],["world",{"0":{"59":1},"2":{"60":1,"75":1}}],["works",{"2":{"35":1,"86":1,"124":1}}],["work",{"2":{"33":2}}],["working",{"2":{"32":1,"34":1}}],["workflows",{"2":{"5":1}}],["workflow",{"2":{"5":1}}],["word",{"2":{"8":6,"30":2,"52":2,"86":8,"124":1}}],["why",{"0":{"72":1}}],["what",{"0":{"65":1},"2":{"36":1,"74":1,"75":1,"86":1}}],["whole",{"2":{"35":1,"86":1,"124":1,"127":1}}],["which",{"2":{"22":1,"31":8,"36":1,"52":2,"74":1,"86":6,"102":1,"106":1,"124":1}}],["while",{"2":{"19":1,"88":2,"89":1,"127":5}}],["when",{"2":{"31":1,"74":1,"86":19,"104":2,"117":10,"118":6,"119":2,"125":1,"127":2}}],["whether",{"2":{"20":1,"34":1,"35":1,"36":1,"38":1,"54":1,"86":4}}],["where",{"2":{"19":1,"21":5,"22":5,"24":5,"25":4,"26":5,"27":4,"30":2,"31":1,"38":1,"46":1,"49":2,"52":1,"59":1,"86":18,"88":1,"89":2,"98":2,"113":1,"124":6,"125":2,"127":69}}],["welcome",{"0":{"75":1}}],["well",{"2":{"74":1}}],["weighting",{"2":{"104":1}}],["weighted",{"2":{"86":1}}],["weight",{"2":{"31":1,"86":2,"108":1,"124":1}}],["weights=nothing",{"2":{"86":1,"124":1}}],["weights",{"2":{"31":3,"86":17,"104":5,"106":5,"124":8}}],["weigths",{"2":{"31":1,"86":1,"103":1,"106":2}}],["we",{"2":{"10":1,"12":1,"14":1,"16":1,"42":1,"43":1,"44":1,"73":4,"74":6,"125":1}}],["w",{"2":{"8":2,"30":2,"86":4,"104":2,"106":2,"124":2}}],["width",{"2":{"36":2,"86":2,"124":2}}],["width=150",{"2":{"36":1,"86":1,"124":1}}],["wide",{"2":{"33":1,"52":1,"86":1}}],["wikipedia",{"2":{"31":2,"74":1}}],["will",{"2":{"6":1,"29":1,"36":1,"73":2,"74":1,"86":9,"92":1,"95":1,"100":1,"104":1,"106":1,"109":1,"121":1,"123":1,"124":8,"125":2}}],["with",{"0":{"71":1,"112":1},"1":{"72":1,"73":1,"74":1,"113":1,"114":1},"2":{"5":3,"8":1,"19":1,"24":1,"30":1,"31":9,"33":4,"34":1,"35":7,"36":7,"52":4,"54":3,"67":1,"70":1,"74":5,"86":56,"87":3,"88":3,"89":1,"100":1,"102":2,"104":3,"106":4,"117":10,"118":6,"119":3,"121":1,"124":10,"125":2,"127":8}}],["without",{"2":{"5":1,"86":17,"117":10,"118":6}}],["within",{"0":{"18":1},"1":{"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1},"2":{"4":1,"18":1,"19":1,"32":1,"33":3,"52":2,"69":1,"73":1,"86":8,"90":1,"93":1,"96":1,"115":1,"127":1}}],["right",{"2":{"86":18,"117":15,"119":3}}],["rich",{"2":{"20":1}}],["rules",{"2":{"52":2,"86":2}}],["ruler",{"2":{"31":1,"43":4,"46":2,"86":2}}],["runtime",{"2":{"127":1}}],["run",{"2":{"31":1,"74":1,"104":1,"125":1,"127":5}}],["rawoptimizerattribute",{"2":{"125":2}}],["raw",{"2":{"31":2}}],["rates",{"2":{"31":1}}],["rate",{"2":{"31":1}}],["rand",{"2":{"19":1,"21":1,"22":16,"25":9,"27":9,"30":8,"86":13,"124":1,"127":2}}],["randomly",{"2":{"22":2,"25":1,"27":1,"30":1,"86":1,"127":1}}],["random",{"2":{"19":2,"22":2,"25":1,"27":1,"30":10,"86":10,"124":1,"127":2}}],["rangedomain",{"2":{"19":1,"26":2,"28":2,"86":4,"124":2}}],["ranges",{"2":{"19":3,"26":1,"86":1,"124":1}}],["range",{"2":{"18":1,"19":1,"21":1,"24":1,"26":3,"33":2,"52":1,"86":4,"124":3}}],["round",{"2":{"113":1,"127":1}}],["routing",{"2":{"49":2,"86":2,"88":1}}],["robust",{"2":{"34":1}}],["rows",{"2":{"74":1}}],["row",{"2":{"31":1,"74":1}}],["role",{"2":{"5":1,"82":1}}],["roles",{"2":{"5":1}}],["r",{"2":{"21":2,"24":2,"26":2,"31":2,"52":3,"86":5,"113":8,"124":2}}],["remote",{"2":{"127":2}}],["remotely",{"2":{"127":1}}],["re",{"2":{"127":1}}],["recommended",{"2":{"125":1,"127":1}}],["recognize",{"2":{"8":1}}],["ref",{"2":{"115":1,"127":6}}],["refer",{"2":{"31":5}}],["rev",{"2":{"86":5,"117":4,"119":1}}],["reverse",{"2":{"31":1,"86":1,"119":1}}],["registries",{"2":{"122":1}}],["regions",{"2":{"74":1}}],["regularization",{"2":{"86":2,"124":2}}],["regular",{"2":{"52":9,"86":9}}],["repositories",{"2":{"87":1}}],["replace",{"2":{"127":1}}],["repl",{"2":{"73":1}}],["represented",{"2":{"52":2,"86":2}}],["represents",{"2":{"36":1,"86":1}}],["represent",{"2":{"19":1}}],["representing",{"2":{"19":1,"52":1,"86":1}}],["relies",{"2":{"115":1}}],["relate",{"2":{"86":1,"119":1}}],["related",{"0":{"50":1},"2":{"104":1,"105":1,"121":1}}],["relatively",{"2":{"86":1,"102":1,"127":1}}],["relationships",{"2":{"47":1}}],["relying",{"2":{"5":1}}],["retrieve",{"2":{"31":1}}],["returned",{"2":{"35":1,"86":1}}],["returns",{"2":{"22":3,"25":2,"27":2,"29":1,"30":1,"35":13,"86":17,"119":1,"122":1,"124":1,"127":1}}],["return",{"2":{"1":3,"3":4,"6":1,"8":3,"21":3,"22":5,"24":3,"25":8,"26":3,"27":8,"30":2,"31":1,"35":7,"36":6,"38":4,"40":1,"49":1,"52":1,"54":2,"86":63,"98":3,"99":3,"102":1,"104":4,"106":5,"113":8,"117":2,"118":2,"124":20,"125":2,"127":21}}],["reach",{"2":{"86":1,"103":1,"124":1}}],["reactants",{"2":{"31":2}}],["reactions",{"2":{"31":1}}],["reaction",{"2":{"31":4}}],["readers",{"2":{"60":1,"62":1,"75":1}}],["realm",{"2":{"20":1}}],["real",{"0":{"59":1},"2":{"19":1,"21":3,"24":5,"26":4,"35":1,"60":1,"75":1,"86":7,"124":6,"125":2}}],["reinforcement",{"2":{"29":1,"86":1,"87":1,"124":1}}],["resume",{"2":{"127":1}}],["result",{"2":{"35":3,"86":23,"102":1,"117":10,"118":6,"119":2}}],["results",{"2":{"24":2,"31":1,"33":1,"35":1,"86":3}}],["resulting",{"2":{"5":1}}],["restart",{"2":{"127":6}}],["restricting",{"2":{"127":2}}],["restriction",{"2":{"35":2,"86":2,"124":2}}],["restricts",{"2":{"38":3,"86":3}}],["restricted",{"2":{"22":1,"25":1,"27":1,"127":4}}],["respect",{"2":{"86":1,"119":1}}],["respectively",{"2":{"19":1,"31":2}}],["researchers",{"2":{"32":1}}],["research",{"0":{"88":1},"2":{"20":1,"34":1,"63":1,"87":1,"88":1}}],["resources",{"2":{"19":1}}],["required",{"2":{"29":1,"86":2,"111":1,"123":1,"124":1}}],["requirements",{"2":{"8":2,"86":2}}],["requiring",{"2":{"5":1}}],["reduce",{"2":{"86":3,"88":1,"94":2,"102":1}}],["reduced",{"2":{"29":1,"86":1,"124":1}}],["reducing",{"2":{"5":1}}],["redundant",{"2":{"5":1,"33":1}}],["give",{"2":{"86":1,"124":1}}],["given",{"2":{"31":2,"35":1,"38":7,"52":2,"86":18,"104":6,"106":2,"108":1,"109":1,"124":7,"125":8}}],["game",{"2":{"74":1}}],["gap",{"2":{"5":1}}],["guides",{"0":{"70":1}}],["guide",{"2":{"60":1}}],["gt",{"2":{"43":1,"87":1}}],["gcc",{"2":{"38":3,"86":3}}],["good",{"2":{"89":1}}],["goes",{"2":{"33":1}}],["goal",{"2":{"31":1,"87":1}}],["golomb",{"2":{"31":2,"43":2,"46":1,"86":1}}],["grads",{"2":{"113":2}}],["gradientdescentoptimizer",{"2":{"113":5}}],["gradient",{"0":{"113":1},"2":{"104":1,"113":1}}],["graphs",{"0":{"49":1}}],["graph",{"2":{"31":4,"52":1,"86":1,"127":1}}],["greater",{"2":{"35":1,"86":12,"117":7,"118":1,"119":3}}],["grid",{"2":{"31":5,"74":3}}],["groundwork",{"2":{"20":1}}],["genetic",{"2":{"81":1,"86":4,"104":3,"124":4}}],["generalstate",{"2":{"127":2}}],["generally",{"2":{"31":1}}],["general",{"0":{"28":1},"2":{"127":1}}],["generated",{"2":{"86":18,"117":10,"118":6,"124":1}}],["generates",{"2":{"30":1,"86":5,"106":2,"119":1,"124":1}}],["generate",{"2":{"19":1,"30":10,"36":1,"86":26,"92":1,"95":1,"100":1,"102":2,"104":2,"106":4,"119":2,"124":7}}],["generation",{"0":{"92":1,"95":1,"100":1,"119":1},"2":{"19":1,"86":2,"124":2}}],["generating",{"2":{"19":2}}],["generic",{"0":{"41":1},"1":{"42":1,"43":1,"44":1,"45":1,"46":1,"47":1},"2":{"4":1,"5":2,"41":1,"46":1,"86":1,"87":1,"125":1,"127":2}}],["getting",{"0":{"70":1,"71":1},"1":{"72":1,"73":1,"74":1},"2":{"70":1}}],["get",{"2":{"19":1,"21":1,"31":2,"36":2,"74":1,"86":5,"119":2,"122":2,"124":1,"125":2,"127":17}}],["g",{"2":{"5":1,"31":1,"80":1,"86":15,"117":8,"118":4,"119":3}}],["global",{"0":{"56":1},"2":{"1":7,"3":6,"33":1,"38":4,"40":2,"49":2,"54":6,"56":1,"74":1,"86":36,"104":2,"124":5,"125":5}}],["block",{"2":{"74":1}}],["blocks",{"2":{"74":2}}],["blank",{"2":{"31":2}}],["binarization==",{"2":{"113":1}}],["binarization",{"2":{"86":4,"104":2,"109":4,"113":13,"124":4}}],["binarize",{"2":{"86":2,"109":2,"113":3,"124":2}}],["binarized",{"2":{"86":1,"108":1}}],["binary",{"2":{"47":1,"86":1,"109":1,"124":1}}],["bias",{"2":{"86":3,"103":1,"124":3}}],["bit",{"2":{"86":2,"109":1,"124":2}}],["bits",{"2":{"86":3,"106":2,"124":1}}],["bitvector",{"2":{"86":5,"102":4,"124":1}}],["bijective",{"2":{"3":2,"86":2}}],["but",{"2":{"31":1,"74":1}}],["building",{"0":{"76":1},"1":{"77":1,"78":1},"2":{"77":1}}],["build",{"2":{"8":1,"10":3,"87":1,"98":1,"99":1,"100":1,"102":1,"103":1,"106":1,"123":1,"125":2}}],["bariable",{"2":{"127":1}}],["back",{"2":{"49":2,"86":2}}],["backward",{"2":{"31":1}}],["basis",{"2":{"74":1}}],["basics",{"0":{"50":1,"82":1}}],["basic",{"0":{"35":1,"66":1,"108":1},"2":{"4":1,"5":3,"19":1,"73":1,"86":5,"104":1,"108":1,"119":4}}],["base",{"0":{"22":1,"25":1,"27":1},"2":{"10":3,"21":3,"22":12,"25":8,"27":9,"28":3,"30":4,"31":9,"86":27,"106":1,"108":2,"124":4,"125":2,"127":4}}],["based",{"0":{"1":1,"36":1,"89":1,"114":1},"2":{"5":1,"6":2,"16":1,"19":1,"30":1,"35":1,"36":1,"86":8,"89":1,"104":2,"106":1,"109":1,"119":2,"121":1,"124":4,"125":2}}],["b",{"2":{"21":1,"22":8,"24":1,"25":8,"26":1,"27":8,"52":2,"86":11,"124":1}}],["breaking",{"2":{"122":3}}],["broad",{"2":{"18":1}}],["bridges",{"2":{"5":1}}],["bounded",{"2":{"86":1,"118":1}}],["bounding",{"2":{"86":6,"118":4,"119":2}}],["bounds",{"2":{"21":1,"86":1,"124":1}}],["boxes",{"2":{"74":1}}],["bool=true",{"2":{"38":1,"86":1}}],["bool=false",{"2":{"38":3,"86":3}}],["boolparameterdomain",{"2":{"30":1,"86":1}}],["boolean",{"2":{"12":1,"30":1,"33":1,"35":2,"86":4,"124":2,"125":1}}],["bool",{"2":{"6":1,"21":4,"24":4,"26":4,"38":1,"54":3,"86":9,"113":1,"124":4,"125":2,"127":4}}],["both",{"2":{"4":1,"14":1,"18":1,"29":1,"31":2,"32":1,"35":2,"86":6,"88":1,"124":2}}],["by",{"2":{"3":2,"4":1,"5":2,"8":1,"19":1,"20":1,"22":1,"25":1,"26":1,"27":1,"29":1,"31":1,"33":3,"34":1,"35":1,"36":1,"38":1,"42":2,"47":3,"52":4,"70":1,"84":1,"86":21,"89":1,"102":1,"104":4,"106":1,"118":1,"124":6,"127":10}}],["begin",{"2":{"125":14,"127":23}}],["benchmarking",{"2":{"121":1}}],["benchmarktools",{"0":{"121":1},"2":{"121":1}}],["better",{"2":{"88":1,"127":2}}],["between",{"2":{"3":2,"5":2,"6":1,"14":2,"19":1,"21":3,"24":2,"26":2,"31":2,"36":1,"43":2,"46":4,"47":1,"86":15,"98":1,"99":1,"124":7,"125":1,"127":1}}],["best",{"0":{"77":1},"2":{"73":1,"77":1,"104":1,"127":1}}],["been",{"2":{"59":1,"121":1,"127":7}}],["before",{"2":{"54":8,"86":8}}],["because",{"2":{"42":1,"47":1}}],["behave",{"2":{"33":1}}],["behaviors",{"2":{"33":1,"34":1}}],["behavior",{"2":{"19":1,"29":1,"33":1,"86":1}}],["beware",{"2":{"29":1,"86":1,"124":1}}],["belongs",{"2":{"22":1,"25":1,"27":1,"127":2}}],["beyond",{"2":{"19":1,"33":1}}],["be",{"2":{"3":2,"5":1,"19":1,"21":1,"29":2,"31":3,"35":3,"36":2,"38":2,"42":2,"47":3,"52":3,"73":1,"74":1,"86":27,"88":2,"89":2,"92":1,"95":1,"100":1,"104":2,"106":5,"109":1,"119":1,"124":8,"125":2,"127":3}}],["69",{"2":{"21":1,"24":1,"26":1,"86":1,"124":1}}],["6",{"2":{"3":1,"31":2,"40":1,"54":3,"86":5,"122":1}}],["up",{"0":{"73":1},"2":{"127":1}}],["upcoming",{"2":{"63":1}}],["update",{"2":{"36":2,"86":2}}],["undefkeyworderror",{"2":{"113":1}}],["under",{"2":{"86":1,"119":1}}],["understanding",{"0":{"80":1},"2":{"88":1}}],["underpin",{"2":{"18":1}}],["unrolled",{"2":{"86":1}}],["unacceptable",{"2":{"86":2}}],["unordered",{"2":{"26":1,"86":1}}],["until",{"2":{"12":1,"86":1,"124":1}}],["unique",{"2":{"3":2,"43":2,"46":1,"86":3,"125":1}}],["union",{"2":{"3":4,"6":1,"8":2,"16":1,"22":2,"25":1,"27":1,"28":2,"30":2,"36":1,"38":1,"86":12,"124":4,"125":2,"127":69}}],["utility",{"2":{"33":1}}],["utilities",{"0":{"102":1},"2":{"12":1}}],["utilized",{"2":{"4":1,"5":1,"86":1}}],["us",{"2":{"125":1}}],["usage",{"2":{"44":1,"121":1}}],["usability",{"2":{"5":1}}],["using",{"2":{"36":1,"74":1,"86":1,"87":1,"104":1,"124":1}}],["usually",{"2":{"46":1,"86":1,"127":1}}],["usual",{"0":{"36":1},"2":{"6":8,"33":5,"35":2,"36":19,"42":1,"43":3,"44":1,"86":24,"90":1,"93":1,"96":1,"115":1,"124":14}}],["useful",{"2":{"86":1,"89":2,"106":1,"127":1}}],["uses",{"0":{"56":1},"2":{"86":1,"88":2,"89":2,"104":1,"119":1}}],["user",{"2":{"5":1,"34":1,"127":2}}],["users",{"2":{"5":3,"20":1,"33":2,"73":2}}],["used",{"2":{"3":6,"8":3,"21":1,"30":8,"35":2,"36":2,"40":2,"49":2,"52":1,"54":8,"73":1,"86":38,"88":1,"102":1,"104":2,"106":2,"111":1,"124":1,"125":2,"127":1}}],["use",{"2":{"1":2,"5":1,"12":1,"26":1,"33":1,"38":1,"43":2,"72":1,"73":2,"74":1,"86":5,"89":2,"115":1,"124":2,"125":1,"127":2}}],["pkg",{"2":{"122":2}}],["penalty",{"2":{"104":9,"113":20}}],["perform",{"2":{"127":1}}],["performance",{"0":{"78":1},"2":{"33":1,"72":1,"78":1,"127":1}}],["performances",{"0":{"7":1,"9":1,"11":1,"13":1,"15":1,"17":1,"23":1}}],["perfchecker",{"0":{"122":1,"123":1},"2":{"121":1,"122":5,"123":1}}],["per",{"2":{"86":1,"109":1,"124":1}}],["pôpulation",{"2":{"104":1}}],["public",{"0":{"124":1}}],["push",{"2":{"113":1}}],["pure",{"2":{"87":3}}],["purely",{"2":{"87":1}}],["purpose",{"2":{"69":1,"125":1}}],["purposes",{"2":{"20":1,"34":1,"35":1,"86":1,"104":1}}],["puzzles",{"2":{"74":1}}],["puzzle",{"2":{"74":3}}],["pluto",{"2":{"73":1}}],["please",{"2":{"43":1,"73":1}}],["platform",{"2":{"34":1}}],["plays",{"2":{"5":1}}],["p",{"2":{"31":2,"86":1,"103":1,"124":1,"125":1}}],["pool",{"2":{"127":1}}],["pop",{"2":{"104":2}}],["population",{"2":{"86":2,"104":2,"124":2}}],["popsize=100",{"2":{"104":1}}],["popsize=200",{"2":{"86":1,"124":1}}],["popsize",{"2":{"86":4,"124":4}}],["post",{"2":{"75":1,"127":1}}],["posed",{"2":{"74":1}}],["possible",{"2":{"73":1,"88":1,"97":1,"116":1,"125":1,"127":2}}],["possibly",{"2":{"26":1,"36":1,"86":2}}],["positional",{"2":{"35":1,"86":1}}],["positive",{"2":{"35":4,"86":15,"91":3,"98":2,"99":2,"117":2,"118":2,"124":4}}],["pos",{"2":{"31":2}}],["point",{"2":{"22":3,"25":2,"27":2,"30":1,"54":2,"86":4}}],["points",{"2":{"21":1,"24":1,"25":1,"26":3,"27":2,"86":5,"124":3}}],["powerful",{"2":{"33":1}}],["power",{"2":{"20":1}}],["pseudo",{"2":{"19":1,"30":1,"86":1}}],["printing",{"2":{"127":2}}],["print",{"2":{"74":1,"127":8}}],["primary",{"2":{"69":1}}],["practices",{"0":{"77":1},"2":{"77":1}}],["practice",{"0":{"60":1}}],["practical",{"2":{"5":1,"20":1,"34":1}}],["practitioners",{"2":{"34":1}}],["precision",{"2":{"104":1,"113":6}}],["preliminaries",{"2":{"104":2,"113":3}}],["predict",{"2":{"104":1,"113":9}}],["predictions",{"2":{"104":1}}],["prediction",{"2":{"104":1}}],["predicate",{"2":{"35":4,"42":1,"43":4,"44":2,"46":4,"86":9,"106":1,"125":2}}],["predicates",{"2":{"33":1,"74":2}}],["previously",{"2":{"44":1}}],["pretty",{"2":{"36":3,"86":3,"113":1,"124":3,"127":2}}],["prefix",{"2":{"35":3,"86":3}}],["preferences",{"2":{"35":1,"86":1,"124":1}}],["preference",{"2":{"33":1}}],["present",{"2":{"31":1,"36":1,"86":1}}],["programs",{"0":{"109":1}}],["programming",{"0":{"20":1,"34":1,"55":1,"64":1,"65":1,"82":1,"88":1},"1":{"56":1,"57":1,"65":1,"66":1,"67":1},"2":{"3":6,"4":1,"5":2,"18":2,"20":2,"32":1,"34":1,"38":3,"40":2,"47":1,"49":2,"54":6,"67":1,"74":1,"75":1,"80":1,"82":1,"86":20,"87":3,"88":2,"89":4,"119":1}}],["proportional",{"2":{"86":1,"124":1}}],["property",{"2":{"42":1}}],["properties",{"2":{"19":1,"31":1,"33":1}}],["properly",{"2":{"21":1,"86":1,"124":1}}],["produce",{"2":{"86":1,"102":1}}],["product",{"2":{"86":1,"94":1}}],["products",{"2":{"31":2}}],["productivity",{"2":{"5":1}}],["prod",{"2":{"86":2,"94":2}}],["providing",{"2":{"5":1,"19":1,"20":1,"33":1,"34":1,"86":2}}],["provided",{"2":{"35":1,"86":18,"117":10,"118":6}}],["provide",{"2":{"5":1,"16":1,"19":1,"42":2,"44":2,"47":1,"70":1,"73":1,"84":1,"87":1,"125":1}}],["provides",{"2":{"4":1,"18":1,"19":1,"33":1,"74":1,"75":1,"87":1,"121":1}}],["projects",{"2":{"5":1,"63":1}}],["proceeds",{"2":{"31":1}}],["proceed",{"2":{"5":1}}],["processing",{"2":{"31":1,"86":1,"119":1}}],["processes",{"2":{"12":1,"88":1}}],["process",{"2":{"5":2,"19":2,"29":1,"60":1,"86":2,"88":1,"104":1,"119":1,"124":1,"127":3}}],["problems",{"2":{"18":1,"19":1,"20":1,"31":2,"33":2,"34":1,"49":2,"52":1,"54":6,"56":1,"57":1,"65":1,"74":1,"75":1,"80":1,"86":11,"87":4,"88":3,"89":6,"127":1}}],["problem",{"2":{"5":1,"19":2,"20":1,"31":7,"43":1,"60":1,"74":1,"88":2,"89":1,"127":3}}],["phase",{"2":{"5":1,"86":1,"106":2}}],["pivotal",{"2":{"5":1,"19":1,"32":1}}],["page",{"2":{"73":1}}],["packing",{"0":{"54":1}}],["packages",{"0":{"68":1},"1":{"69":1},"2":{"4":2,"5":7,"8":2,"33":1,"86":2,"87":4}}],["package",{"0":{"69":1},"2":{"4":1,"5":3,"6":1,"18":2,"19":3,"20":1,"32":2,"33":4,"69":1,"70":1,"122":1}}],["patch",{"2":{"122":2}}],["patches",{"2":{"122":1}}],["pattern",{"2":{"86":1,"106":1}}],["patternfolds",{"2":{"24":1,"86":1}}],["path",{"2":{"52":1,"86":6,"124":5,"127":5}}],["passed",{"2":{"35":2,"86":2}}],["paradigm",{"2":{"88":1}}],["param=nothing",{"2":{"86":1,"124":1}}],["parametric",{"0":{"98":1,"117":1},"2":{"35":1,"86":4,"100":1,"104":1,"119":2,"124":3}}],["parameterization",{"2":{"86":1,"119":1}}],["parameter",{"2":{"19":2,"29":1,"30":1,"52":2,"86":16,"102":2,"104":1,"108":1,"119":6,"124":5,"125":4}}],["parameters=constraintcommons",{"2":{"6":1,"36":1,"86":1,"124":1}}],["parameters",{"0":{"6":1,"30":1},"1":{"7":1},"2":{"6":17,"19":3,"30":12,"33":1,"35":2,"36":18,"86":39,"97":1,"104":5,"116":1,"119":2,"124":22}}],["params",{"2":{"33":1,"35":2,"86":2,"113":1,"124":1}}],["param",{"0":{"99":1,"118":1},"2":{"29":2,"30":2,"35":4,"36":2,"86":109,"99":13,"100":2,"102":5,"118":54,"119":16,"124":22,"125":24}}],["parse",{"2":{"36":1,"86":1}}],["particularly",{"2":{"106":1}}],["partially",{"2":{"74":1,"86":1,"124":1}}],["partial",{"2":{"12":1,"29":1,"86":3,"124":2,"127":1}}],["part",{"2":{"29":1,"35":1,"73":1,"86":2,"87":1,"124":1}}],["pairs",{"2":{"31":2,"46":1,"86":1}}],["paired",{"2":{"30":1,"86":1}}],["pairvarsparameterdomain",{"2":{"30":1,"86":1}}],["pair",{"2":{"1":16,"6":1,"29":1,"31":5,"38":2,"40":4,"54":15,"86":63,"104":3,"106":1,"124":1}}],["mts",{"2":{"127":7}}],["move",{"2":{"127":3}}],["most",{"2":{"38":4,"74":1,"86":5,"109":1,"124":1}}],["more",{"2":{"36":1,"86":2}}],["moisumequalparam",{"2":{"125":2}}],["moisequentialtasks",{"2":{"125":1}}],["moipredicate",{"2":{"125":2}}],["moiordered",{"2":{"125":1}}],["moiminusequalparam",{"2":{"125":2}}],["moilessthanparam",{"2":{"125":2}}],["moierror",{"2":{"125":5}}],["moieq",{"2":{"125":1}}],["moidistdifferent",{"2":{"125":1}}],["moialwaystrue",{"2":{"125":1}}],["moiallequalparam",{"2":{"125":2}}],["moiallequal",{"2":{"125":1}}],["moialldifferent",{"2":{"125":1}}],["moi",{"2":{"31":1,"44":2,"125":22}}],["module",{"0":{"22":1,"25":1,"27":1},"2":{"35":1,"86":1}}],["modeled",{"2":{"127":1}}],["modeler=",{"2":{"31":1}}],["modeler",{"2":{"31":14}}],["modelize",{"2":{"31":1}}],["modeling",{"0":{"34":1,"77":1},"2":{"5":1,"19":1,"20":1,"34":1,"42":1,"44":1,"73":2,"74":1,"87":1}}],["model",{"0":{"74":1},"2":{"31":17,"33":1,"52":1,"74":3,"86":3,"125":25,"127":75}}],["models",{"0":{"76":1},"1":{"77":1,"78":1},"2":{"5":1,"19":1,"74":1,"77":1,"78":1,"86":1,"87":2,"88":2,"119":1}}],["mutable",{"2":{"127":2}}],["mutually",{"2":{"86":4,"92":1,"95":1,"100":1,"104":1,"106":1,"124":3}}],["much",{"2":{"89":1}}],["must",{"2":{"19":1,"21":1,"26":1,"31":2,"38":2,"42":1,"47":2,"52":2,"86":8,"88":1,"124":2,"125":1}}],["multithreading",{"2":{"127":1}}],["multithreaded",{"2":{"127":1}}],["multi",{"2":{"52":1,"86":1}}],["multiplication",{"2":{"86":1,"124":1}}],["multiplied",{"2":{"31":1}}],["multiple",{"2":{"5":1}}],["multimedia",{"2":{"31":4}}],["multivalued",{"2":{"8":3,"86":2,"124":1}}],["mixed",{"2":{"87":1}}],["mission",{"2":{"75":1}}],["missing",{"2":{"8":2,"10":6,"98":2,"99":2,"100":2,"102":2,"103":2,"106":2}}],["might",{"2":{"74":2}}],["min",{"2":{"113":2,"125":1}}],["minkowski",{"2":{"86":1,"103":1,"124":1}}],["minusequalparam",{"2":{"125":2}}],["minus",{"2":{"86":28,"98":4,"99":4,"117":8,"118":8,"119":4}}],["mincut",{"2":{"31":1,"127":2}}],["minimization",{"2":{"125":1}}],["minimizing",{"2":{"31":1}}],["minimizes",{"2":{"5":1}}],["minimal",{"2":{"8":2,"86":4,"102":1,"103":1,"124":3,"127":3}}],["minimum",{"2":{"3":11,"14":1,"31":1,"86":12,"113":2,"124":1}}],["mdd",{"2":{"8":4,"30":1,"52":12,"86":15,"124":2}}],["mdash",{"2":{"1":3,"3":4,"6":2,"8":6,"12":1,"14":1,"16":1,"21":6,"22":5,"24":8,"25":4,"26":10,"27":5,"28":2,"29":3,"30":13,"31":19,"35":10,"36":7,"38":4,"40":1,"46":1,"49":1,"52":2,"54":2,"86":185,"91":2,"92":1,"94":2,"95":1,"98":4,"99":3,"100":1,"102":6,"103":3,"104":28,"106":11,"108":2,"109":3,"111":2,"117":11,"118":6,"119":2,"122":4,"124":71,"125":45,"127":142}}],["mmds",{"2":{"8":1}}],["m",{"2":{"6":2,"31":6,"36":2,"74":5,"86":2,"124":2,"127":139}}],["major",{"2":{"122":2}}],["may",{"2":{"89":1}}],["map",{"2":{"86":1,"102":1,"113":5}}],["mapping",{"2":{"86":1,"119":1}}],["mainsolver",{"2":{"127":7}}],["main",{"2":{"41":1,"86":1,"124":1,"127":5}}],["mainly",{"2":{"35":1,"86":1,"125":1}}],["macro",{"2":{"36":6,"86":6,"115":1,"124":2,"125":1}}],["making",{"2":{"32":1,"89":1}}],["makes",{"2":{"87":1}}],["make",{"2":{"12":1,"35":3,"36":2,"86":8,"87":1,"88":1,"100":1,"104":3,"113":2,"115":2,"119":3,"127":1}}],["matter",{"2":{"125":1}}],["matters",{"2":{"105":1}}],["matrices",{"0":{"110":1},"1":{"111":1,"112":1,"113":1,"114":1},"2":{"86":1,"104":1,"111":1}}],["matrix",{"2":{"31":4,"86":2,"104":2,"108":2,"124":1}}],["match",{"2":{"86":3}}],["matches",{"2":{"86":3}}],["maths",{"2":{"86":1,"124":1}}],["mathematical",{"0":{"82":1},"2":{"82":1,"88":2,"89":1}}],["mathoptinterface",{"2":{"31":2,"125":12}}],["magic",{"2":{"31":2}}],["marks",{"2":{"31":1,"43":2,"46":2,"86":2}}],["max",{"2":{"29":2,"86":6,"102":2,"106":2,"124":2,"125":1,"127":10}}],["maximum",{"2":{"3":11,"14":1,"19":1,"21":1,"24":1,"26":1,"86":14,"124":3,"127":6}}],["manipulating",{"2":{"106":1}}],["manipulations",{"2":{"20":1}}],["manipulation",{"2":{"18":1,"19":2,"32":1,"33":1,"86":1,"119":1}}],["manufacturing",{"2":{"88":1}}],["manhattan",{"2":{"86":1,"103":1,"124":1}}],["managing",{"2":{"33":1}}],["manages",{"2":{"127":1}}],["managed",{"2":{"127":1}}],["manager",{"2":{"73":1}}],["manage",{"2":{"5":1,"127":1}}],["many",{"2":{"12":1,"86":1,"124":1}}],["metasolver",{"2":{"127":4}}],["metastrategist",{"0":{"120":1},"2":{"120":1}}],["metadata",{"2":{"87":1}}],["metaheuristics",{"0":{"81":1},"2":{"67":1}}],["metrics",{"0":{"103":1}}],["metric=hamming",{"2":{"86":1,"104":1,"124":1}}],["metric",{"2":{"86":8,"104":6,"124":8}}],["method",{"2":{"6":1,"8":1,"21":1,"22":3,"24":1,"25":3,"26":1,"27":3,"31":17,"36":1,"86":169,"104":26,"106":1,"111":2,"117":10,"118":6,"122":3,"123":1,"124":53,"125":14,"127":128}}],["methods",{"0":{"58":1},"1":{"59":1,"60":1},"2":{"4":1,"5":2,"8":1,"19":2,"21":1,"30":1,"33":2,"67":1,"86":4,"102":2,"124":3,"127":3}}],["meaningful",{"2":{"85":1}}],["meaning",{"2":{"38":2,"86":2,"106":1}}],["means",{"2":{"3":2,"36":3,"86":5}}],["measurement",{"2":{"127":1}}],["measure",{"2":{"33":1,"86":2,"124":2}}],["merge",{"2":{"19":1,"24":2,"26":2,"86":2,"124":2,"127":1}}],["merging",{"2":{"19":1}}],["membership",{"2":{"19":1}}],["56",{"2":{"127":1}}],["53",{"2":{"21":1,"24":1,"26":1,"86":1,"124":1}}],["5",{"2":{"1":1,"3":11,"21":1,"24":1,"26":1,"31":2,"38":29,"40":3,"54":13,"86":75,"87":1,"113":1,"122":1,"124":1,"125":6,"127":1}}],["nbits",{"2":{"86":2,"106":1,"124":1}}],["nbsp",{"2":{"1":3,"3":4,"6":2,"8":6,"12":1,"14":1,"16":1,"21":6,"22":5,"24":8,"25":4,"26":10,"27":5,"28":2,"29":3,"30":13,"31":19,"35":10,"36":7,"38":4,"40":1,"46":1,"49":1,"52":2,"54":2,"86":185,"91":2,"92":1,"94":2,"95":1,"98":4,"99":3,"100":1,"102":6,"103":3,"104":28,"106":11,"108":2,"109":3,"111":2,"117":11,"118":6,"119":2,"122":4,"124":71,"125":45,"127":142}}],["nvars",{"2":{"86":12,"98":8,"124":4}}],["nvalues",{"2":{"38":8,"86":8}}],["nine",{"2":{"74":1}}],["n5",{"2":{"52":2,"86":2}}],["n4",{"2":{"52":3,"86":3}}],["n3",{"2":{"52":2,"86":2}}],["n2",{"2":{"52":2,"86":2}}],["n1",{"2":{"52":2,"86":2}}],["n²",{"2":{"31":1}}],["n×n",{"2":{"31":1}}],["n",{"2":{"31":18,"86":7,"102":4,"108":3,"113":9,"124":2}}],["numeric",{"2":{"26":1,"86":1}}],["number",{"2":{"21":1,"25":3,"26":2,"27":3,"29":3,"31":2,"35":3,"38":11,"86":53,"91":1,"98":1,"103":1,"104":2,"106":5,"109":3,"117":8,"118":4,"124":18,"125":6,"127":12}}],["numbers",{"2":{"19":2,"86":2,"98":2}}],["normalized",{"2":{"86":1,"124":1}}],["normal",{"2":{"86":1,"119":1}}],["norm",{"2":{"86":2}}],["now",{"2":{"31":1,"74":1}}],["node",{"2":{"31":2,"52":3,"86":3}}],["no",{"2":{"31":4,"46":1,"54":20,"86":24,"102":1,"104":1,"106":1,"119":1}}],["nonnegative",{"2":{"125":1}}],["none",{"2":{"86":4,"109":1,"113":2,"119":3,"124":1,"125":6}}],["nonlinear",{"2":{"80":1}}],["non",{"0":{"98":1,"117":1},"2":{"26":1,"29":2,"86":3,"104":4,"124":2,"127":1}}],["not",{"2":{"24":1,"31":2,"35":1,"36":2,"38":1,"42":1,"44":1,"54":6,"73":1,"74":3,"86":18,"109":1,"118":1,"119":1,"124":2,"125":1,"127":1}}],["notebooks",{"2":{"73":1,"121":1}}],["note",{"2":{"6":1,"42":1,"44":1,"73":1,"74":1,"125":1}}],["nothing",{"2":{"1":1,"10":3,"29":1,"35":4,"36":1,"38":2,"86":14,"102":1,"104":2,"113":1,"124":8,"125":2}}],["natural",{"2":{"42":1,"44":1}}],["nature",{"2":{"24":1,"26":1,"86":1,"124":1}}],["names",{"2":{"86":1,"119":1}}],["name=",{"2":{"86":1,"124":1}}],["name",{"2":{"6":1,"35":1,"36":3,"86":9,"124":8,"127":8}}],["neighbours",{"2":{"127":2}}],["neighbourhood",{"2":{"127":2}}],["neither",{"2":{"35":1,"86":1}}],["never",{"2":{"127":1}}],["necessarily",{"2":{"73":1}}],["necessary",{"2":{"18":1,"127":3}}],["next",{"2":{"49":2,"86":2,"122":2}}],["negation",{"2":{"35":1,"86":1}}],["networks",{"2":{"88":1}}],["network",{"2":{"86":1,"106":1,"124":1}}],["net",{"2":{"31":1}}],["new",{"2":{"24":3,"33":2,"36":5,"86":8,"87":1,"124":3,"125":6,"127":2}}],["needs",{"2":{"19":1,"29":1,"31":1,"86":3,"119":1,"124":2}}],["need",{"2":{"5":1,"14":1,"74":2}}],["lst",{"2":{"127":5}}],["l",{"2":{"31":1,"86":15,"117":4,"118":4,"119":3}}],["l=n²",{"2":{"31":1}}],["loss",{"2":{"104":2,"113":2}}],["local",{"0":{"89":1,"114":1},"2":{"86":5,"89":1,"104":1,"106":1,"124":5,"125":2,"127":7}}],["localsearchsolverscblstodo",{"2":{"73":1}}],["localsearchsolvers",{"0":{"127":1},"2":{"73":2,"87":1,"104":1,"127":139}}],["locations",{"2":{"31":5}}],["loop",{"2":{"127":8}}],["loops",{"2":{"36":1,"49":2,"86":3}}],["look",{"2":{"73":1,"74":1}}],["lower",{"2":{"86":1,"124":1}}],["lowest",{"2":{"21":1,"24":1,"26":1,"86":1,"124":1}}],["low",{"2":{"29":1,"86":1,"87":1,"124":1}}],["loggingextra",{"2":{"127":1}}],["logging",{"2":{"127":1}}],["logic",{"2":{"86":2}}],["logical",{"2":{"42":1}}],["log",{"2":{"8":1,"10":3,"98":1,"99":1,"100":1,"102":1,"103":1,"106":1,"127":1}}],["littledict",{"2":{"86":2,"106":2,"119":1}}],["like",{"2":{"67":1,"81":1}}],["links",{"2":{"31":1,"121":1,"127":1}}],["linear",{"2":{"67":1,"80":1,"86":3,"108":3,"124":3}}],["line",{"2":{"31":9,"73":1}}],["limited",{"2":{"29":1,"86":1,"124":1}}],["limit",{"2":{"29":7,"54":2,"86":11,"124":9,"125":1,"127":10}}],["limits",{"2":{"19":1}}],["listed",{"2":{"86":2}}],["listing",{"2":{"47":1}}],["list=x",{"2":{"36":2,"86":2,"124":1}}],["list",{"0":{"91":1,"94":1,"97":1,"116":1},"1":{"98":1,"99":1,"100":1,"117":1,"118":1,"119":1},"2":{"1":13,"3":16,"6":2,"26":1,"27":1,"35":1,"38":24,"40":6,"43":1,"44":1,"46":5,"49":5,"52":8,"54":5,"86":89,"97":1,"116":1,"124":3,"127":11}}],["lt",{"2":{"8":2,"21":1,"22":4,"25":4,"26":1,"27":4,"31":1,"42":1,"43":1,"52":2,"86":10,"124":2,"127":3}}],["launch",{"2":{"127":1}}],["lazy",{"2":{"86":2,"102":2,"115":2,"124":2}}],["lang",{"2":{"86":3,"124":1}}],["lang=",{"2":{"86":1,"124":1}}],["language=",{"2":{"86":1,"124":1}}],["languageparameterdomain",{"2":{"30":1,"86":1}}],["languages",{"0":{"8":1,"52":1},"1":{"9":1},"2":{"8":1,"30":1,"86":1}}],["language",{"2":{"6":1,"42":1,"44":1,"52":17,"73":3,"86":24,"124":5}}],["large",{"2":{"74":1,"88":1,"89":1}}],["labels",{"2":{"52":2,"86":2}}],["labeled",{"2":{"52":2,"86":2}}],["last",{"2":{"52":1,"74":1,"86":1,"122":2,"127":1}}],["lays",{"2":{"20":1}}],["layered",{"2":{"86":1,"124":1}}],["layers",{"2":{"86":9,"119":1,"124":4}}],["layer",{"0":{"90":1,"92":1,"93":1,"95":1,"96":1,"100":1,"106":1,"115":1,"119":1},"1":{"91":1,"92":1,"94":1,"95":1,"97":1,"98":1,"99":1,"100":1,"116":1,"117":1,"118":1,"119":1},"2":{"4":1,"25":2,"27":2,"86":42,"90":1,"92":3,"93":1,"95":3,"96":1,"98":1,"100":3,"104":4,"106":28,"115":1,"119":3,"124":16}}],["left",{"2":{"86":18,"117":10,"119":3}}],["let",{"2":{"74":1}}],["levels",{"2":{"84":1}}],["level",{"2":{"42":1,"44":1,"52":3,"86":3,"87":2,"127":9}}],["lessthanparam",{"2":{"125":2}}],["lesser",{"2":{"86":11,"117":6,"118":1,"119":3}}],["less",{"2":{"42":1,"74":1,"125":2}}],["leadsolvers",{"2":{"127":3}}],["leadsolver",{"2":{"127":1}}],["least",{"2":{"38":4,"86":4,"104":2}}],["learn",{"2":{"75":1,"86":7,"104":5,"106":1,"111":1,"124":6}}],["learned",{"2":{"33":1,"34":1,"86":1,"104":1,"124":1}}],["learning",{"0":{"105":1,"110":1},"1":{"111":1,"112":1,"113":1,"114":1},"2":{"4":1,"5":6,"12":1,"19":1,"29":1,"33":2,"86":4,"87":1,"104":1,"105":1,"106":2,"124":3}}],["length",{"2":{"19":1,"21":2,"22":1,"24":1,"25":6,"26":1,"27":6,"33":1,"35":4,"54":3,"86":23,"94":2,"106":2,"113":4,"124":6,"127":12}}],["lengths",{"2":{"1":3,"54":6,"86":9}}],["swap",{"2":{"127":2}}],["switch",{"2":{"86":1,"103":1,"124":1}}],["sltns",{"2":{"104":2}}],["smaller",{"2":{"89":1}}],["small",{"2":{"89":1}}],["s2",{"2":{"86":1,"124":1}}],["s1",{"2":{"86":1,"124":1}}],["scalarfunction",{"2":{"125":3}}],["scalars",{"2":{"86":1,"98":1}}],["scalar",{"2":{"86":3,"91":1}}],["science",{"2":{"72":1}}],["scenario",{"2":{"60":1}}],["scheduling",{"0":{"54":1},"2":{"31":1,"54":6,"86":6,"88":1}}],["square",{"2":{"31":3}}],["sqrt",{"2":{"29":1,"86":1,"124":1}}],["syntax",{"2":{"33":1,"73":1,"74":1,"125":2,"127":1}}],["symcon",{"2":{"86":1,"124":1}}],["symb",{"2":{"35":2,"86":2}}],["symbols",{"2":{"86":11,"102":4,"106":1,"124":6}}],["symbol",{"2":{"6":4,"10":1,"35":7,"36":19,"86":32,"106":1,"109":1,"113":1,"119":4,"124":13,"127":3}}],["symmetries",{"2":{"33":3,"35":4,"86":4,"124":4}}],["symmetry",{"2":{"33":1,"35":1,"86":1,"124":1}}],["systems",{"2":{"88":2}}],["system",{"2":{"31":1}}],["subs",{"2":{"127":3}}],["subsolvers",{"2":{"127":4}}],["subsolver",{"2":{"127":6}}],["subset",{"2":{"125":1}}],["subsets",{"2":{"74":2}}],["sub",{"2":{"104":1,"127":1}}],["subtract",{"2":{"86":1,"119":1}}],["subtraction",{"2":{"86":1,"119":1}}],["subtype",{"2":{"31":1}}],["subgrid",{"2":{"74":1}}],["subgrids",{"2":{"74":1}}],["successfully",{"2":{"59":1}}],["such",{"2":{"5":1,"31":2,"33":2,"42":3,"44":2,"46":1,"52":1,"66":1,"86":3,"87":1,"88":2,"106":1,"119":1,"127":4}}],["sudoku",{"2":{"31":17,"74":4,"127":1}}],["sudokuinstances",{"2":{"31":1}}],["sudokuinstance",{"2":{"31":19}}],["sumequalparam",{"2":{"125":2}}],["summary",{"2":{"89":1}}],["summing",{"0":{"38":1}}],["sum",{"2":{"25":1,"27":1,"29":1,"31":1,"38":8,"54":2,"86":20,"91":2,"94":3,"108":3,"124":4,"125":1}}],["supply",{"2":{"88":1}}],["supplies",{"2":{"31":1,"87":1}}],["supported",{"2":{"86":4}}],["support",{"2":{"19":1,"86":1}}],["supports=nothing",{"2":{"86":1}}],["supports",{"2":{"19":1,"33":1,"86":7,"125":3}}],["supertype",{"2":{"19":3,"24":1,"26":1,"86":2,"124":2}}],["super",{"2":{"19":1,"21":1,"86":1,"124":1}}],["silent",{"2":{"125":1,"127":1}}],["sig",{"2":{"86":17,"117":10,"118":6}}],["signature",{"2":{"86":2,"102":2,"124":2}}],["significance",{"2":{"65":1}}],["significantly",{"2":{"33":1,"34":1}}],["single",{"2":{"74":1,"86":3,"91":1,"94":2}}],["since",{"2":{"42":1,"44":1,"127":1}}],["sink",{"2":{"31":3}}],["simulated",{"2":{"81":1}}],["simple",{"2":{"29":1,"33":1,"36":1,"74":2,"86":2,"124":2}}],["simply",{"2":{"22":2,"25":1,"27":1,"30":1,"35":1,"74":1,"86":2}}],["simplify",{"2":{"56":1}}],["simplifying",{"2":{"5":1}}],["simplified",{"2":{"36":3,"86":3}}],["simplifies",{"2":{"5":1,"33":1}}],["similar",{"2":{"21":1,"86":1,"124":1}}],["size",{"2":{"19":1,"21":5,"24":8,"26":8,"29":2,"31":3,"49":3,"86":31,"102":1,"104":7,"106":2,"113":2,"124":16,"125":2,"127":4}}],["situations",{"2":{"14":1}}],["split",{"2":{"104":1}}],["specialize",{"2":{"127":10}}],["specialized",{"2":{"86":2,"98":1,"117":1,"127":10}}],["specializing",{"2":{"127":1}}],["specifying",{"2":{"18":1,"86":2}}],["specific",{"0":{"46":1},"2":{"33":1,"40":4,"86":6,"104":2,"119":1}}],["specifically",{"2":{"22":2,"25":1,"27":1,"30":1,"46":1,"86":2}}],["specification",{"2":{"6":1,"19":1}}],["specifications",{"2":{"6":1,"33":1,"36":1,"86":1,"124":1}}],["specified",{"2":{"22":2,"25":1,"27":1,"30":1,"31":2,"86":2,"119":1}}],["specifies",{"2":{"3":6,"38":1,"42":1,"47":1,"86":8,"119":1}}],["space",{"2":{"29":4,"35":1,"86":11,"88":1,"124":9,"127":1}}],["spaces",{"2":{"12":1,"18":1,"19":1,"33":1}}],["span",{"2":{"24":1,"26":1,"86":1}}],["sat",{"2":{"127":3}}],["satisfying",{"2":{"127":2}}],["satisfy",{"2":{"38":3,"42":1,"47":1,"86":3,"87":1,"88":1,"89":1}}],["satisfies",{"2":{"35":1,"38":6,"52":1,"86":8,"89":1,"124":1}}],["satisfied",{"2":{"3":4,"35":1,"40":1,"49":1,"52":1,"54":2,"86":10,"88":1,"124":1,"127":1}}],["satisfaction",{"2":{"33":1,"86":2,"87":1,"127":3}}],["say",{"2":{"86":1,"109":1,"124":1}}],["same",{"2":{"24":1,"26":1,"31":2,"35":1,"36":1,"46":1,"86":4,"124":2}}],["samplings",{"2":{"19":1,"29":2,"86":2,"124":2}}],["sampling",{"0":{"12":1},"1":{"13":1},"2":{"12":2}}],["s",{"2":{"6":3,"8":7,"10":3,"19":2,"21":2,"24":1,"26":1,"31":5,"33":1,"34":1,"35":6,"36":8,"74":1,"86":18,"98":1,"99":1,"100":1,"102":1,"103":1,"106":1,"124":14,"127":109}}],["stop",{"2":{"127":5}}],["storing",{"2":{"87":1}}],["stores",{"2":{"26":2,"86":2}}],["store",{"2":{"24":3,"30":8,"36":1,"86":15,"102":1,"106":2,"124":1,"127":3}}],["stuff",{"2":{"113":2}}],["studio",{"2":{"73":1}}],["studies",{"0":{"59":1},"2":{"59":1}}],["stipulates",{"2":{"86":1}}],["step",{"2":{"36":2,"70":2,"84":2,"86":2,"127":3}}],["stamp",{"2":{"127":4}}],["static",{"2":{"127":1}}],["statistical",{"2":{"88":1}}],["status",{"2":{"125":1,"127":4}}],["states",{"2":{"52":4,"86":4}}],["state",{"2":{"31":3,"127":36}}],["started",{"0":{"70":1,"71":1},"1":{"72":1,"73":1,"74":1},"2":{"70":1}}],["starts",{"2":{"35":1,"54":8,"86":9,"89":1,"127":2}}],["start",{"2":{"31":1,"49":2,"52":2,"74":1,"86":4}}],["starting",{"2":{"31":2,"35":1,"86":1,"127":1}}],["start=",{"2":{"31":1}}],["standout",{"2":{"33":1}}],["standard",{"2":{"31":3,"32":1,"33":1,"34":1,"41":1,"87":1}}],["standardization",{"2":{"5":1}}],["stands",{"2":{"18":1}}],["stdout",{"2":{"31":1}}],["str",{"2":{"127":1}}],["straight",{"2":{"74":1}}],["straightforward",{"2":{"33":1,"42":1,"125":1}}],["strategies",{"0":{"57":1},"2":{"20":1,"57":1}}],["string",{"2":{"22":4,"25":4,"27":4,"31":1,"35":1,"86":8,"102":1,"106":1,"124":1,"127":1}}],["strictly",{"2":{"1":8,"35":3,"86":13,"91":1,"118":1,"124":3}}],["struct",{"2":{"21":1,"31":3,"86":1,"127":4}}],["structure",{"0":{"106":1},"2":{"8":3,"21":2,"30":1,"31":1,"35":1,"86":7,"89":1,"104":1,"106":4,"124":5,"127":5}}],["structures",{"2":{"4":1,"5":2}}],["streamlining",{"0":{"0":1,"2":1,"32":1,"37":1,"39":1,"48":1,"51":1,"53":1},"1":{"1":1,"3":1,"33":1,"34":1,"35":1,"36":1,"38":1,"40":1,"49":1,"52":1,"54":1},"2":{"5":1}}],["shifted",{"2":{"113":3}}],["share",{"2":{"63":1,"77":1}}],["shared",{"2":{"4":1,"5":3}}],["shrink",{"2":{"35":1,"36":1,"86":2}}],["show",{"2":{"86":4,"102":1,"106":1,"124":1}}],["showcase",{"2":{"59":1}}],["shortcut",{"2":{"35":1,"36":1,"86":1,"124":1}}],["should",{"2":{"3":6,"42":1,"44":1,"46":1,"86":11,"102":2,"124":2,"127":3}}],["soon",{"2":{"125":1}}],["sophisticated",{"2":{"34":1}}],["so",{"2":{"31":1,"36":2,"74":1,"86":2,"88":1}}],["something",{"2":{"35":1,"86":1}}],["some",{"2":{"10":1,"12":1,"74":1,"86":1,"87":1,"90":1,"93":1,"96":1,"104":1,"115":1,"121":1,"124":1,"125":1}}],["sols",{"2":{"86":1,"104":4,"124":1}}],["solve",{"2":{"31":1,"74":1,"87":2,"88":1,"127":3}}],["solvername",{"2":{"125":1}}],["solvers",{"0":{"126":1},"2":{"73":3,"74":4,"87":10,"89":3,"106":1,"126":1,"127":2}}],["solver",{"2":{"31":6,"74":2,"87":1,"89":2,"104":1,"125":4,"127":29}}],["solving",{"2":{"20":1,"34":1,"57":1,"60":1,"65":1,"73":1,"75":1,"88":4,"127":4}}],["sol",{"2":{"29":1,"86":1,"124":1}}],["solution",{"2":{"19":1,"31":2,"74":3,"86":3,"88":1,"89":4,"103":1,"124":1,"127":4}}],["solutions",{"2":{"4":1,"5":2,"29":10,"86":14,"87":1,"88":2,"89":4,"103":1,"104":8,"124":14,"127":9}}],["solely",{"2":{"5":1}}],["source",{"2":{"1":3,"3":4,"6":3,"8":7,"12":1,"14":1,"16":1,"21":10,"22":15,"24":12,"25":15,"26":14,"27":16,"28":2,"29":3,"30":17,"31":22,"35":11,"36":9,"38":4,"40":1,"46":1,"49":1,"52":2,"54":2,"86":185,"91":2,"92":1,"94":2,"95":1,"98":4,"99":3,"100":1,"102":6,"103":3,"104":28,"106":11,"108":2,"109":3,"111":2,"117":11,"118":6,"119":2,"122":4,"124":71,"125":45,"127":142}}],["sequentialtasks",{"2":{"125":2}}],["sequence",{"2":{"49":6,"52":4,"86":10}}],["select",{"2":{"127":4}}],["selection",{"2":{"86":1,"119":1}}],["selected",{"2":{"86":8,"92":1,"95":1,"100":1,"104":2,"106":6,"124":4,"127":1}}],["series",{"2":{"74":1,"127":1}}],["serves",{"2":{"4":1,"19":1}}],["see",{"2":{"43":1,"127":1}}],["seems",{"2":{"31":1}}],["separates",{"2":{"86":1,"102":1}}],["separator",{"2":{"31":1}}],["sep",{"2":{"31":2,"86":2,"102":2}}],["segment",{"2":{"31":3}}],["several",{"2":{"14":1,"73":1,"87":1,"106":1}}],["seaperl",{"2":{"87":1}}],["searching",{"2":{"35":1,"86":1,"124":1}}],["searches",{"2":{"19":1}}],["search",{"0":{"57":1,"89":1,"114":1},"2":{"12":1,"18":1,"19":3,"29":9,"33":1,"57":1,"81":1,"86":20,"88":1,"89":3,"106":1,"124":20,"127":1}}],["seamless",{"2":{"5":1}}],["seamlessly",{"2":{"5":1}}],["sec",{"2":{"127":1}}],["section",{"2":{"6":1,"43":1,"121":1,"123":1}}],["seconds",{"2":{"127":1}}],["second",{"2":{"3":2,"54":8,"86":10}}],["setter",{"2":{"74":1}}],["setting",{"0":{"73":1},"2":{"127":1}}],["settings",{"2":{"19":1,"29":1,"86":1,"124":1,"127":1}}],["setup",{"2":{"73":1}}],["setdomain",{"2":{"21":1,"24":1,"26":3,"27":2,"86":5,"124":4}}],["set",{"2":{"3":4,"5":1,"8":1,"20":1,"22":2,"25":1,"26":3,"27":1,"30":1,"31":4,"38":3,"40":2,"47":2,"86":29,"88":1,"100":1,"102":1,"104":11,"109":2,"119":1,"124":8,"125":16,"127":22}}],["sets",{"2":{"3":2,"19":1,"86":2,"104":3}}],["001",{"2":{"113":1}}],["00514",{"2":{"36":1,"86":1,"124":1}}],["0",{"2":{"1":14,"3":1,"21":1,"22":2,"24":1,"25":1,"26":1,"27":1,"31":54,"35":7,"38":8,"49":1,"52":22,"74":2,"86":73,"98":4,"99":4,"113":1,"117":4,"118":4,"122":8,"124":3,"125":6,"127":9}}],["42",{"2":{"21":1,"24":1,"26":1,"38":2,"86":3,"124":1}}],["4",{"2":{"1":12,"3":15,"21":1,"24":1,"26":1,"31":3,"38":14,"40":4,"43":2,"44":2,"45":2,"46":3,"47":3,"49":4,"54":18,"86":82,"122":1,"124":1,"125":4,"127":1}}],["3j+1",{"2":{"74":1}}],["3i+1",{"2":{"74":1}}],["3",{"2":{"1":17,"3":15,"21":2,"24":2,"26":2,"31":6,"35":4,"36":1,"38":33,"40":4,"43":2,"44":4,"45":6,"46":7,"47":3,"49":6,"54":26,"74":6,"86":125,"122":1,"124":3,"125":2,"127":1}}],["28",{"2":{"127":1}}],["225",{"2":{"86":1}}],["200",{"2":{"86":2,"104":1,"124":2}}],["2009",{"2":{"36":1,"86":1,"124":1}}],["2",{"2":{"1":15,"3":16,"21":2,"24":2,"26":2,"31":5,"35":3,"36":1,"38":40,"40":4,"43":2,"44":3,"45":4,"46":7,"47":3,"49":3,"52":10,"54":28,"74":2,"86":146,"122":1,"124":3,"125":2,"127":1}}],["101",{"0":{"64":1},"1":{"65":1,"66":1,"67":1}}],["10",{"2":{"38":27,"86":29,"87":1,"124":2,"127":2}}],["100",{"2":{"29":2,"86":4,"124":4,"127":1}}],["10000",{"2":{"127":1}}],["1000",{"2":{"29":1,"86":1,"124":1}}],["10^6",{"2":{"29":1,"86":1,"124":1}}],["123",{"2":{"21":1,"24":1,"26":1,"86":1,"124":1}}],["12",{"2":{"21":1,"24":1,"26":1,"54":1,"86":2,"124":1}}],["1",{"2":{"1":19,"3":17,"16":2,"21":2,"24":2,"26":2,"31":3,"35":6,"36":1,"38":34,"40":4,"43":2,"44":3,"45":4,"46":5,"47":3,"49":4,"52":15,"54":41,"74":5,"86":174,"108":1,"109":1,"113":4,"117":2,"122":8,"124":6,"125":2,"127":4}}],["=>",{"2":{"52":15,"86":15,"113":1}}],["=usual",{"2":{"36":1,"86":1,"124":1}}],["=0",{"2":{"31":1}}],["==",{"2":{"3":4,"22":1,"38":2,"49":1,"86":9,"109":1,"113":2,"124":1}}],["=",{"2":{"1":3,"3":12,"6":1,"16":2,"21":5,"22":4,"24":5,"25":4,"26":5,"27":4,"29":7,"31":11,"35":3,"36":3,"38":16,"40":1,"43":5,"44":3,"45":2,"46":2,"49":5,"52":16,"54":17,"74":1,"86":126,"87":1,"94":2,"100":1,"102":1,"104":12,"108":1,"109":3,"113":34,"119":5,"124":36,"125":35,"127":49}}],["epoch",{"2":{"127":1}}],["err",{"2":{"125":3}}],["error",{"2":{"33":2,"35":20,"36":3,"86":24,"104":1,"124":6,"125":4,"127":4}}],["euclidian",{"2":{"98":1,"99":1}}],["euclidean",{"2":{"86":6}}],["eq",{"2":{"86":22,"117":12,"118":4,"119":6,"125":2}}],["equiped",{"2":{"31":1}}],["equilibrium",{"2":{"31":4}}],["equivalent",{"2":{"22":1,"25":1,"27":1,"86":1}}],["equality",{"2":{"125":1}}],["equalities",{"2":{"86":2,"119":2}}],["equal",{"2":{"1":8,"3":2,"31":1,"35":1,"38":1,"86":17,"117":3,"118":1,"119":1,"125":3}}],["editors",{"2":{"73":1}}],["edge",{"2":{"52":2,"86":2}}],["educational",{"2":{"20":1,"34":1}}],["either",{"2":{"21":1,"24":1,"26":1,"47":2,"54":4,"86":8,"87":1,"124":4}}],["efficiency",{"2":{"20":1,"88":1}}],["efficiently",{"2":{"12":1,"31":1,"125":1}}],["efficient",{"2":{"5":1,"77":1,"86":1}}],["embodies",{"2":{"20":1,"34":1,"86":2}}],["empty",{"2":{"104":2,"125":4,"127":11}}],["emptydomain",{"2":{"19":1,"21":2,"24":1,"26":1,"86":2,"124":1}}],["empowering",{"0":{"20":1}}],["emphasizes",{"2":{"5":1}}],["evaluation",{"2":{"104":1}}],["evaluates",{"2":{"35":1,"36":1,"86":2}}],["evaluated",{"2":{"33":1,"127":1}}],["eventually",{"2":{"49":2,"86":2}}],["even",{"2":{"31":1}}],["everuseful",{"2":{"16":1}}],["evolves",{"2":{"127":1}}],["evolve",{"2":{"19":1}}],["earlier",{"2":{"122":1}}],["easy",{"2":{"87":1,"123":1}}],["easier",{"2":{"36":1,"86":1}}],["ease",{"2":{"5":1,"20":1,"72":1}}],["eachrow",{"2":{"113":4}}],["each",{"2":{"3":2,"25":1,"27":1,"31":3,"35":1,"36":1,"49":2,"52":2,"69":1,"70":1,"74":5,"86":10,"106":1,"115":1,"124":2,"127":1}}],["else",{"2":{"113":4}}],["eltype",{"2":{"28":3,"86":3,"104":2}}],["eliminating",{"2":{"5":1}}],["elementary",{"0":{"40":1}}],["elements",{"2":{"5":1,"12":1,"19":2,"21":1,"31":1,"33":1,"86":18,"91":1,"102":1,"106":1,"117":8,"118":4,"124":2}}],["element",{"2":{"3":9,"86":9,"104":2,"122":1,"127":1}}],["e",{"2":{"5":1,"31":1,"35":4,"49":2,"52":4,"54":4,"80":1,"86":15,"103":1,"113":3,"124":1,"127":1}}],["exclu",{"2":{"86":3,"106":3}}],["exclusive",{"2":{"86":11,"92":1,"95":1,"100":1,"104":3,"106":9,"124":3}}],["excluded",{"2":{"86":1}}],["exclude",{"2":{"38":1,"86":1}}],["exceed",{"2":{"54":2,"86":2}}],["except",{"2":{"38":2,"86":2}}],["except=vals",{"2":{"36":2,"86":2,"124":1}}],["exact",{"2":{"89":4}}],["exactly",{"2":{"38":4,"86":4}}],["examine",{"2":{"33":1}}],["exampleusing",{"2":{"46":2,"86":2}}],["example2",{"2":{"46":2,"86":2}}],["example",{"2":{"6":1,"35":1,"36":8,"42":2,"44":1,"47":1,"73":1,"86":8,"122":1,"124":6}}],["examples",{"0":{"112":1},"1":{"113":1,"114":1},"2":{"1":3,"3":4,"35":2,"38":4,"40":1,"46":1,"49":1,"52":2,"54":2,"73":1,"86":22,"119":1,"121":1}}],["existing",{"2":{"36":2,"86":2,"87":1,"88":1}}],["exists",{"2":{"35":3,"74":1,"86":3}}],["ex",{"2":{"36":3,"86":3}}],["expansion",{"2":{"86":1}}],["export",{"2":{"86":1,"124":1,"127":1}}],["explicit",{"2":{"86":2}}],["explicitly",{"2":{"47":1,"86":2}}],["explanation",{"2":{"36":1,"80":1,"86":1}}],["explored",{"2":{"86":1,"124":1}}],["explore",{"2":{"29":4,"86":7,"124":4}}],["exploresettings",{"2":{"19":1,"29":1,"86":1,"124":1}}],["exploring",{"0":{"18":1,"68":1},"1":{"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"69":1},"2":{"20":1}}],["explorations",{"2":{"33":1}}],["exploration",{"0":{"29":1},"2":{"12":1,"19":4,"29":2,"30":1,"86":3,"124":1}}],["express",{"2":{"125":1}}],["expressions",{"2":{"106":1}}],["expression",{"2":{"36":7,"38":1,"42":1,"86":8}}],["expr",{"2":{"36":2,"86":2}}],["experimental",{"0":{"85":1},"2":{"85":1}}],["experiments",{"0":{"83":1},"1":{"84":1,"85":1},"2":{"85":1}}],["experience",{"2":{"5":1}}],["expect",{"2":{"75":1}}],["expectations",{"2":{"73":1}}],["expected",{"2":{"35":2,"36":1,"86":4,"124":3}}],["externally",{"2":{"127":1}}],["external",{"2":{"19":1,"86":1,"119":1}}],["extends",{"2":{"22":5,"25":3,"27":3,"28":1,"30":2,"31":4,"86":5,"104":3,"124":1}}],["extend",{"2":{"21":1,"28":1,"86":2,"123":1,"124":1}}],["extended",{"2":{"10":1,"86":19,"102":2,"117":10,"118":6,"124":2}}],["extensionally",{"2":{"47":1}}],["extensional",{"2":{"47":1}}],["extensions",{"0":{"10":1},"1":{"11":1}}],["extension",{"0":{"22":1,"25":1,"27":1,"47":1,"121":1},"2":{"5":1,"41":1,"86":8,"121":1}}],["extrema",{"0":{"14":1},"1":{"15":1},"2":{"14":3,"86":2,"104":1,"113":1,"124":2,"127":3}}],["extracts",{"2":{"6":1,"36":2,"86":2,"124":1}}],["extract",{"2":{"6":2,"36":1,"86":2,"124":2}}],["enumerate",{"2":{"113":1}}],["enforcing",{"2":{"86":2}}],["encode",{"2":{"104":1}}],["encoded",{"2":{"52":2,"86":2}}],["encoding",{"0":{"109":1},"2":{"86":5,"108":1,"109":4,"124":4}}],["encourage",{"2":{"62":1,"73":2}}],["encompass",{"2":{"46":1,"86":1}}],["encapsulate",{"2":{"86":1,"119":1,"127":2}}],["encapsulating",{"2":{"33":1}}],["encapsuler",{"2":{"24":1,"86":1}}],["entry",{"2":{"36":3,"86":3,"127":1}}],["energy",{"2":{"31":1}}],["enough",{"2":{"30":1,"86":1}}],["enhancement",{"2":{"33":1}}],["enhances",{"2":{"20":1,"34":1}}],["enhancing",{"2":{"5":2,"33":1}}],["enabling",{"0":{"34":1},"2":{"18":1}}],["enabled",{"2":{"127":1}}],["enable",{"2":{"5":1}}],["end``",{"2":{"127":1}}],["end",{"2":{"5":1,"8":2,"74":2,"86":2,"113":15,"125":6,"127":4}}],["ensure",{"2":{"74":1,"86":1,"108":1}}],["ensures",{"2":{"5":1,"33":1,"40":2,"43":2,"49":2,"52":2,"54":6,"74":1,"86":12}}],["ensuring",{"2":{"1":7,"5":2,"38":5,"46":2,"86":17,"104":3,"119":1,"125":9}}],["environment",{"0":{"73":1},"2":{"5":1}}],["etc",{"2":{"5":1}}],["ecosystem",{"2":{"4":1,"5":3,"18":1,"20":1,"32":1,"34":1,"73":1,"87":1}}],["especially",{"2":{"89":1}}],["essential",{"2":{"4":1,"19":1,"33":1}}],["establishes",{"2":{"3":2,"86":2}}],["x``or",{"2":{"104":1}}],["x̅",{"2":{"104":4}}],["xto",{"2":{"86":1,"103":1,"124":1}}],["xn",{"2":{"74":1}}],["x=x1",{"2":{"74":1}}],["x3",{"2":{"52":1,"86":1}}],["x3c",{"2":{"1":4,"8":3,"21":6,"22":9,"24":11,"25":8,"26":12,"27":8,"30":12,"31":3,"38":2,"52":1,"54":1,"86":48,"104":1,"113":2,"124":16,"125":29,"127":91}}],["x2",{"2":{"52":1,"86":1,"127":2}}],["x26",{"2":{"45":4,"46":4,"86":4}}],["x1",{"2":{"52":1,"86":1,"127":2}}],["x",{"2":{"1":23,"3":8,"12":2,"14":2,"22":10,"25":10,"27":10,"31":4,"35":7,"36":5,"38":28,"40":2,"42":2,"43":8,"44":4,"46":6,"47":1,"49":2,"52":6,"54":8,"74":6,"86":298,"87":2,"91":3,"94":4,"98":7,"99":6,"102":6,"103":8,"104":33,"109":8,"113":42,"117":76,"118":43,"124":33,"125":31,"127":68}}],["xcsp³",{"2":{"41":1}}],["xcsp3",{"0":{"36":1},"2":{"6":3,"8":1,"33":3,"36":1,"86":2,"124":1}}],["xcsp",{"2":{"1":3,"3":4,"33":1,"36":2,"38":4,"40":1,"43":1,"44":1,"46":1,"49":1,"52":2,"54":2,"86":21,"124":1}}],["csps",{"2":{"87":1}}],["cn",{"2":{"74":1}}],["c=c1",{"2":{"74":1}}],["c=usual",{"2":{"36":2,"86":2,"124":2}}],["clear",{"2":{"89":1}}],["classic",{"2":{"74":2}}],["closed",{"2":{"38":9,"86":9}}],["cblstodo",{"2":{"74":4}}],["cbls",{"0":{"125":1},"2":{"73":2,"74":3,"87":3,"89":3,"104":1,"125":31,"127":1}}],["circuit",{"2":{"49":12,"86":12}}],["cc",{"2":{"38":2,"86":2}}],["central",{"2":{"32":1}}],["certain",{"2":{"3":4,"54":2,"86":6}}],["cplex",{"2":{"87":1}}],["cp",{"0":{"67":1,"71":1,"74":1},"1":{"72":1,"73":1,"74":1},"2":{"32":2,"33":2,"34":2,"57":1,"59":1,"65":1,"73":1,"74":2,"75":1,"77":1,"85":1,"87":9,"88":4}}],["current",{"2":{"86":2,"106":1,"124":1,"127":1}}],["currently",{"2":{"22":2,"25":1,"27":1,"30":1,"86":1,"125":1}}],["cumulative",{"2":{"54":9,"86":9}}],["cut",{"2":{"31":1,"127":1}}],["case",{"0":{"59":1}}],["cast",{"2":{"35":1,"74":1,"86":1}}],["called",{"2":{"42":1,"47":1,"74":3,"86":1,"127":2}}],["calls",{"2":{"36":2,"86":2}}],["cardinality",{"2":{"38":20,"86":20}}],["care",{"2":{"36":1,"86":1,"124":1}}],["catch",{"2":{"113":1}}],["categorized",{"2":{"41":1}}],["categories",{"0":{"36":1}}],["cater",{"2":{"19":1}}],["catalog",{"2":{"33":1}}],["capacited",{"2":{"127":1}}],["capacity",{"2":{"127":1}}],["capacities",{"2":{"31":1}}],["capabilities",{"2":{"34":1}}],["capability",{"2":{"33":1}}],["can",{"2":{"5":3,"21":1,"33":1,"38":3,"52":1,"62":1,"73":1,"74":3,"75":1,"86":10,"89":1,"106":5,"109":1,"119":1,"124":3,"125":2,"127":1}}],["creation",{"2":{"33":1,"86":1,"119":1}}],["created",{"2":{"127":1}}],["creates",{"2":{"36":1,"86":1}}],["create",{"2":{"31":4,"35":1,"86":2,"124":1,"125":1}}],["critical",{"2":{"5":1,"18":1}}],["crucial",{"2":{"5":1,"19":1,"33":1}}],["choose",{"2":{"127":1}}],["choice",{"2":{"73":1}}],["chuffed",{"2":{"87":1}}],["chemical",{"2":{"31":3}}],["checks",{"2":{"35":2,"36":2,"46":1,"52":1,"86":6}}],["checking",{"2":{"19":1}}],["check",{"2":{"1":3,"3":8,"8":1,"10":3,"22":1,"25":1,"27":1,"35":1,"38":7,"40":2,"43":1,"49":1,"52":2,"54":1,"74":1,"86":27,"98":1,"99":1,"100":1,"102":1,"103":1,"106":2,"109":1,"124":1,"127":10}}],["chains",{"2":{"88":1}}],["chapter",{"2":{"75":1}}],["characteristics",{"2":{"19":1}}],["change",{"2":{"31":2}}],["changes",{"2":{"19":1,"24":1,"26":1,"31":1,"86":2,"89":1,"124":1}}],["channel",{"2":{"3":9,"86":9}}],["c",{"2":{"1":14,"3":15,"22":1,"25":1,"27":1,"35":16,"36":8,"38":19,"40":2,"44":3,"45":4,"46":6,"49":4,"52":10,"54":11,"86":116,"124":24,"127":31}}],["copy",{"2":{"125":5}}],["cops",{"2":{"87":1}}],["cosntriction",{"2":{"127":1}}],["cosntraints",{"0":{"50":1}}],["cost",{"2":{"127":19}}],["costs",{"2":{"88":1,"127":20}}],["covering",{"2":{"84":1}}],["cover",{"2":{"82":1,"123":1}}],["could",{"2":{"42":1,"47":1}}],["count",{"2":{"38":6,"86":95,"91":3,"117":40,"118":20,"119":21}}],["counting",{"0":{"38":1},"2":{"86":1,"119":1}}],["counter",{"2":{"16":2,"86":2,"124":2,"127":1}}],["co",{"2":{"38":2,"86":11,"98":5,"99":4}}],["coefficients",{"2":{"38":1,"86":1}}],["coeffs",{"2":{"38":2,"86":2}}],["columns",{"2":{"74":1}}],["column",{"2":{"74":1}}],["collect",{"2":{"113":1}}],["collections",{"2":{"14":2,"86":1,"124":1}}],["collection",{"2":{"5":1,"16":1,"22":2,"24":1,"25":1,"27":1,"29":2,"30":1,"42":1,"43":1,"44":1,"74":4,"86":8,"87":1,"103":1,"104":3,"124":5,"125":2,"127":5}}],["collaborate",{"2":{"62":1}}],["col",{"2":{"31":1}}],["coordinates",{"2":{"31":1}}],["core",{"0":{"36":1},"2":{"6":2,"8":1,"33":4,"36":1,"41":1,"86":2,"124":1}}],["corresponding",{"2":{"31":1,"86":1,"119":1}}],["corresponds",{"2":{"3":2,"86":2}}],["correspondence",{"2":{"3":2,"86":2}}],["code",{"2":{"5":1,"73":1,"86":5,"124":3}}],["come",{"2":{"125":1}}],["combinatorial",{"2":{"65":1,"88":1,"106":1}}],["command",{"2":{"73":1}}],["community",{"0":{"61":1,"62":1},"1":{"62":1,"63":1},"2":{"62":1}}],["commitment",{"2":{"34":1}}],["commons",{"0":{"21":1},"1":{"22":1,"23":1}}],["common",{"2":{"5":1,"87":1}}],["compile",{"2":{"86":1,"119":1}}],["compliance",{"2":{"52":2,"86":2}}],["complex",{"2":{"20":1,"32":1,"33":1,"47":1,"56":1,"88":2,"89":1}}],["complexity",{"2":{"5":1,"84":1}}],["completely",{"2":{"86":1,"124":1}}],["completed",{"2":{"5":1,"74":1}}],["complete",{"2":{"5":1,"19":1,"29":2,"86":6,"124":5}}],["components",{"2":{"33":1,"86":2,"102":2,"124":2}}],["compounds",{"2":{"31":1}}],["compositions",{"2":{"86":1}}],["compositionalneworks",{"2":{"102":1}}],["compositionalnetworks",{"0":{"101":1},"1":{"102":1,"103":1},"2":{"5":1,"86":77,"91":2,"92":1,"94":2,"95":1,"98":4,"99":3,"100":1,"101":1,"102":6,"103":3,"104":3,"106":10,"117":11,"118":6,"119":2,"124":26}}],["compositional",{"2":{"86":1,"106":1,"124":1}}],["composition",{"2":{"86":24,"102":1,"124":21}}],["compose",{"2":{"74":1,"86":12,"106":1,"124":8}}],["composed",{"2":{"29":1,"86":3,"124":3}}],["comprehensive",{"2":{"20":1,"34":1,"86":2}}],["computational",{"2":{"19":1,"72":1}}],["computes",{"2":{"127":1}}],["computed",{"2":{"86":17,"117":10,"118":6}}],["compute",{"2":{"14":2,"24":2,"26":1,"31":1,"86":7,"103":1,"104":1,"109":1,"124":4,"125":1,"127":17}}],["compatible",{"2":{"5":1}}],["compare",{"2":{"1":1,"35":1,"86":2}}],["comparisons",{"0":{"97":1},"1":{"98":1,"99":1,"100":1},"2":{"86":2,"100":1,"119":2}}],["comparison",{"0":{"1":1,"96":1},"1":{"97":1,"98":1,"99":1,"100":1},"2":{"1":1,"38":1,"86":9,"96":1,"97":1,"98":1,"100":2,"119":1,"124":5}}],["cohesive",{"2":{"5":1}}],["conflict",{"2":{"86":1}}],["conflicted",{"2":{"86":3}}],["conflicts",{"2":{"86":8}}],["conflicts=nothing",{"2":{"86":1}}],["configuration",{"2":{"31":2,"86":8,"104":4,"124":2,"125":1,"127":3}}],["configurations",{"2":{"12":1,"29":2,"86":7,"104":1,"124":3,"127":1}}],["configure",{"2":{"19":1}}],["connecting",{"2":{"86":1,"124":1}}],["connection",{"0":{"3":1}}],["connector",{"2":{"86":1,"124":1}}],["conduct",{"2":{"85":1}}],["conditions",{"2":{"86":1,"88":1,"119":1,"127":1}}],["condition",{"2":{"3":13,"38":15,"54":3,"86":31}}],["concerned",{"2":{"88":2}}],["concentrations",{"2":{"31":2}}],["concepts",{"0":{"66":1},"2":{"66":1,"81":1}}],["concept",{"2":{"1":10,"3":8,"29":3,"33":2,"35":19,"36":18,"38":15,"40":2,"43":1,"44":1,"45":2,"46":3,"49":2,"52":4,"54":6,"86":95,"124":20,"125":5}}],["convert",{"2":{"21":1,"28":3,"86":7,"102":2,"106":1,"124":1}}],["containing",{"2":{"127":1}}],["container",{"2":{"86":1,"106":1,"125":1}}],["contains",{"2":{"35":1,"36":2,"74":1,"86":4,"106":1,"124":2}}],["content",{"2":{"75":1}}],["contexts",{"2":{"33":1}}],["context",{"2":{"21":1,"86":1,"106":2,"124":1}}],["contrast",{"2":{"67":1,"89":1}}],["contribute",{"2":{"62":1}}],["contribution",{"0":{"61":1},"1":{"62":1,"63":1}}],["contiguous",{"2":{"86":12,"117":8,"119":4}}],["contiuous",{"2":{"24":1,"26":1,"86":1,"124":1}}],["continuousdomain",{"2":{"19":1,"24":2,"86":2,"124":1}}],["continuous",{"0":{"24":1},"1":{"25":1},"2":{"18":1,"19":2,"21":2,"24":2,"26":1,"31":1,"86":3,"124":3}}],["cons=dictionary",{"2":{"127":1}}],["cons",{"2":{"127":31}}],["considered",{"2":{"38":2,"86":2,"127":1}}],["considers",{"2":{"8":1}}],["consistent",{"2":{"36":1,"86":1}}],["constriction",{"2":{"127":4}}],["constrained",{"2":{"127":2}}],["constrains",{"2":{"127":1}}],["constraintprogrammingextensions",{"2":{"87":1}}],["constraintmodels",{"0":{"31":1},"2":{"31":15,"87":1}}],["constrainttranslator",{"2":{"5":1}}],["constraintlearning",{"0":{"104":1},"2":{"5":1,"104":27,"122":1}}],["constraintdomains",{"0":{"18":1},"1":{"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1},"2":{"5":1,"18":1,"19":3,"20":2,"21":6,"24":8,"26":10,"29":3,"30":11,"86":35,"87":1,"124":18}}],["constraintcommons",{"0":{"4":1},"1":{"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1},"2":{"4":1,"5":4,"6":3,"8":6,"12":1,"14":1,"16":1,"30":2,"36":2,"86":16,"124":10}}],["constraint",{"0":{"0":1,"2":1,"20":1,"32":1,"34":1,"37":1,"39":1,"43":1,"48":1,"51":1,"53":1,"55":1,"64":1,"65":1,"88":1,"89":1,"114":1},"1":{"1":1,"3":1,"33":1,"34":1,"35":1,"36":1,"38":1,"40":1,"49":1,"52":1,"54":1,"56":1,"57":1,"65":1,"66":1,"67":1},"2":{"1":7,"3":24,"4":1,"5":3,"6":9,"12":1,"18":2,"19":1,"20":2,"22":3,"25":3,"27":3,"29":2,"32":1,"33":10,"34":2,"35":17,"36":24,"38":20,"40":7,"42":5,"43":5,"44":4,"46":4,"47":3,"49":7,"52":6,"54":20,"74":7,"75":1,"86":156,"87":5,"88":1,"89":5,"104":4,"106":1,"108":1,"119":3,"124":39,"125":29,"127":33}}],["constraintsolver",{"2":{"87":1}}],["constraints",{"0":{"0":1,"1":1,"2":1,"3":1,"32":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1,"42":1,"47":1,"48":1,"49":1,"51":1,"52":1,"53":1,"54":1,"56":1,"75":1,"105":1},"1":{"1":1,"3":1,"33":1,"34":1,"35":1,"36":1,"38":1,"40":1,"42":1,"43":2,"44":2,"45":2,"46":2,"47":1,"49":1,"52":1,"54":1},"2":{"1":3,"3":4,"4":1,"5":1,"6":9,"8":3,"18":1,"32":3,"33":17,"34":5,"35":12,"36":38,"38":4,"40":1,"41":2,"42":3,"43":3,"44":2,"46":3,"47":2,"49":1,"50":1,"52":2,"54":2,"56":1,"66":1,"73":1,"74":2,"86":75,"87":4,"88":3,"89":2,"104":1,"105":1,"111":1,"124":40,"127":23}}],["constructor",{"2":{"31":1,"104":3,"125":1,"127":1}}],["constructing",{"2":{"31":1}}],["construct",{"2":{"21":3,"24":3,"26":3,"30":1,"31":3,"86":6,"124":5,"127":3}}],["constant",{"2":{"6":1,"35":1,"36":1,"86":3,"124":2}}],["o",{"2":{"104":1,"127":16}}],["objs=dictionary",{"2":{"127":1}}],["objs",{"2":{"127":7}}],["objectives",{"2":{"127":10}}],["objective",{"2":{"74":1,"125":4,"127":24}}],["observable",{"2":{"31":1}}],["own",{"2":{"73":1,"74":1,"127":1}}],["occurs",{"2":{"38":2,"86":2}}],["occurrences",{"2":{"38":7,"86":7}}],["others",{"2":{"87":1}}],["other",{"0":{"67":1},"2":{"31":1,"67":1,"73":1,"74":4,"87":1,"88":1,"89":2,"127":2}}],["otherwise",{"2":{"1":3,"3":4,"8":1,"22":1,"25":1,"27":1,"30":1,"35":3,"38":4,"40":1,"49":1,"54":2,"86":28,"98":2,"99":2,"117":2,"118":2,"124":3,"127":1}}],["oversampling",{"2":{"104":1,"113":6}}],["oversample",{"2":{"12":2,"86":2,"113":1,"124":2}}],["overview",{"0":{"81":1},"2":{"75":1}}],["overviews",{"0":{"69":1}}],["overlap",{"2":{"54":21,"86":21}}],["over",{"2":{"14":1,"29":1,"33":1,"35":1,"36":1,"46":2,"74":2,"86":7,"103":1,"104":1,"124":4,"125":1,"127":1}}],["output",{"2":{"86":2,"104":1,"124":2}}],["outputs",{"2":{"35":1,"86":1,"122":3,"124":1}}],["out",{"2":{"74":1}}],["outlined",{"2":{"33":1}}],["outcomes",{"2":{"5":1}}],["our",{"2":{"12":1,"74":2}}],["ongoing",{"2":{"54":2,"86":2}}],["only",{"2":{"38":1,"74":1,"86":6,"92":1,"95":1,"100":1,"106":2,"111":1,"124":3,"125":2,"127":1}}],["on",{"0":{"36":1,"49":1,"84":1},"2":{"5":2,"6":2,"18":1,"19":1,"21":1,"29":1,"30":1,"31":1,"35":1,"36":3,"40":2,"42":1,"43":2,"46":1,"57":1,"73":1,"86":14,"87":1,"88":3,"104":3,"109":1,"115":1,"119":2,"121":1,"124":4,"125":2,"127":2}}],["once",{"2":{"5":2,"73":1}}],["one",{"2":{"5":1,"30":1,"33":1,"36":1,"74":3,"86":14,"92":1,"95":1,"100":1,"102":2,"104":2,"106":2,"108":1,"109":4,"113":1,"124":10,"127":3}}],["originating",{"2":{"86":1}}],["origins",{"2":{"54":6,"86":6}}],["oriented",{"2":{"4":1}}],["org",{"2":{"36":1,"86":1,"124":1}}],["organizations",{"2":{"88":1}}],["organization",{"2":{"33":1,"69":1,"75":1}}],["or",{"2":{"5":1,"6":1,"16":1,"19":4,"20":1,"21":2,"22":1,"24":1,"25":1,"26":1,"27":1,"31":1,"34":1,"35":1,"36":2,"38":1,"42":1,"47":2,"54":4,"63":1,"73":1,"74":1,"86":24,"87":2,"88":4,"89":2,"109":1,"119":5,"122":3,"124":8,"127":6}}],["order",{"2":{"1":6,"31":1,"40":2,"86":9,"119":1,"125":2}}],["ordered",{"2":{"1":6,"86":8,"106":1,"125":3,"127":1}}],["opt",{"2":{"125":1}}],["optmizers",{"2":{"104":1}}],["optimisation",{"2":{"87":1}}],["optimizing",{"2":{"88":1,"127":7}}],["optimization",{"0":{"57":1,"58":1,"67":1,"71":1,"79":1,"80":1},"1":{"59":1,"60":1,"72":1,"73":1,"74":1,"80":1,"81":1,"82":1},"2":{"33":1,"59":1,"60":1,"72":1,"75":1,"77":1,"80":2,"82":1,"88":2,"127":2}}],["optimizers",{"0":{"112":1},"1":{"113":1,"114":1},"2":{"104":1}}],["optimizer",{"2":{"74":1,"87":1,"104":6,"113":8,"125":17,"127":3}}],["optimize",{"2":{"31":1,"86":1,"88":1,"104":11,"124":1,"125":3}}],["optionally",{"2":{"35":2,"36":1,"86":2,"124":2}}],["optional",{"2":{"29":1,"31":1,"86":10,"104":1,"109":1,"124":10,"127":2}}],["options",{"2":{"19":1,"104":2,"125":4,"127":32}}],["open",{"2":{"38":6,"86":6,"115":1}}],["operate",{"2":{"86":1,"119":1}}],["operational",{"0":{"88":1},"2":{"88":1}}],["operation",{"2":{"86":5,"104":2,"106":5}}],["operations",{"0":{"94":1},"2":{"10":1,"25":2,"27":2,"86":21,"92":1,"95":2,"100":1,"104":3,"106":13,"119":1,"124":7}}],["operators",{"2":{"30":1,"86":1}}],["operator",{"2":{"1":3,"38":1,"86":4}}],["opparameterdomain",{"2":{"30":1,"86":1}}],["op",{"2":{"3":8,"6":1,"38":10,"49":4,"54":4,"86":29,"106":2}}],["op==",{"2":{"38":1,"86":1}}],["op===",{"2":{"3":2,"38":4,"86":6}}],["op=>",{"2":{"1":2,"86":2}}],["op=≥",{"2":{"1":2,"38":1,"86":3}}],["op=≤",{"2":{"1":6,"38":3,"86":9}}],["op=",{"2":{"1":6,"86":6}}],["op=+",{"2":{"1":2,"86":2}}],["official",{"2":{"73":1}}],["offer",{"2":{"33":1}}],["offering",{"2":{"20":1,"33":1,"34":1}}],["offers",{"2":{"5":1,"19":1,"34":1}}],["often",{"2":{"49":2,"54":6,"86":8,"88":1}}],["of",{"0":{"91":1,"94":1,"97":1,"116":1},"1":{"98":1,"99":1,"100":1,"117":1,"118":1,"119":1},"2":{"1":14,"3":17,"4":1,"5":9,"6":6,"8":3,"12":2,"14":4,"18":3,"19":8,"20":4,"21":3,"22":5,"24":7,"25":10,"26":7,"27":11,"29":14,"30":2,"31":33,"32":1,"33":13,"34":1,"35":18,"36":23,"38":35,"40":6,"46":3,"47":4,"49":8,"52":10,"54":14,"60":1,"63":1,"72":2,"73":1,"74":11,"75":2,"78":1,"80":2,"82":1,"85":1,"86":292,"87":7,"88":2,"89":4,"91":2,"92":2,"95":2,"98":3,"100":2,"102":6,"103":3,"104":14,"106":15,"109":3,"115":3,"117":13,"118":4,"119":8,"122":2,"124":96,"125":16,"127":78}}],["f2",{"2":{"127":2}}],["fetch",{"2":{"127":1}}],["few",{"2":{"123":1}}],["feasible",{"2":{"74":2,"89":1}}],["features",{"0":{"5":1,"19":1,"33":1,"108":1},"2":{"33":1,"69":1}}],["feature",{"2":{"4":1,"19":1,"33":1}}],["front",{"2":{"115":1}}],["from",{"0":{"52":1,"60":1,"67":1},"2":{"22":4,"25":2,"27":3,"30":2,"31":2,"33":2,"36":1,"46":1,"52":1,"60":1,"74":2,"75":1,"86":14,"88":1,"104":1,"111":1,"119":2,"124":2,"127":17}}],["framework",{"2":{"87":1}}],["friendly",{"2":{"34":1}}],["free",{"2":{"31":1}}],["finds",{"2":{"122":1}}],["find",{"2":{"89":5,"127":2}}],["finding",{"2":{"87":1,"88":1,"89":2}}],["finishes",{"2":{"54":8,"86":8}}],["finish",{"2":{"52":2,"86":2}}],["filter",{"2":{"113":1}}],["file",{"2":{"86":7,"106":1,"124":7}}],["filled",{"2":{"74":1}}],["fill",{"2":{"31":4,"74":1}}],["fields",{"2":{"35":1,"86":1,"124":1}}],["first",{"0":{"74":1},"2":{"3":2,"35":1,"36":3,"52":1,"54":8,"74":1,"86":15,"104":1,"113":4,"122":1,"127":1}}],["flatten",{"2":{"113":1}}],["flaw",{"2":{"31":1}}],["flexibility",{"2":{"33":2,"73":1}}],["flexible",{"2":{"19":1,"29":2,"33":1,"34":1,"47":1,"86":5,"119":1,"124":3}}],["float64",{"2":{"35":2,"86":2,"113":1,"125":1,"127":5}}],["flows",{"2":{"31":1}}],["flow",{"2":{"31":1}}],["floor",{"2":{"29":1,"86":1,"124":1}}],["f",{"2":{"8":1,"12":2,"33":1,"35":3,"86":16,"102":6,"124":14,"125":20,"127":7}}],["full",{"0":{"86":1}}],["further",{"2":{"31":1,"73":1}}],["future",{"0":{"63":1},"2":{"6":1,"29":1,"86":1,"124":1}}],["func",{"2":{"127":6}}],["funcs",{"2":{"86":2,"102":2,"124":2}}],["functionality",{"2":{"5":1}}],["functionalities",{"0":{"5":1,"19":1,"33":1},"2":{"5":1,"19":1,"20":1,"33":1}}],["functions",{"2":{"4":1,"5":2,"19":1,"31":1,"35":2,"86":8,"100":1,"106":3,"119":4,"124":2}}],["function",{"2":{"1":3,"3":4,"6":2,"8":2,"12":2,"14":1,"16":2,"21":4,"22":5,"24":6,"25":4,"26":7,"27":5,"28":2,"29":3,"30":4,"31":1,"33":2,"35":29,"36":14,"38":4,"40":1,"42":1,"46":2,"49":1,"52":3,"54":2,"74":1,"86":67,"91":2,"92":1,"94":2,"95":1,"98":5,"99":3,"100":1,"102":12,"103":3,"104":4,"106":9,"108":2,"109":3,"111":1,"113":7,"115":1,"117":12,"118":6,"119":6,"122":1,"124":31,"125":14,"127":16}}],["fundamentals",{"2":{"82":1}}],["fundamental",{"2":{"5":1,"46":1,"86":1}}],["found",{"2":{"106":1}}],["foundation",{"2":{"19":1}}],["foundational",{"2":{"4":1,"5":1}}],["fold",{"2":{"87":1}}],["following",{"2":{"21":1,"33":1,"35":1,"38":1,"86":8,"102":2,"109":1,"119":1,"124":6,"127":1}}],["follows",{"2":{"12":1,"74":1,"125":2}}],["follow",{"2":{"6":1}}],["focuses",{"2":{"87":1,"88":2}}],["focusing",{"2":{"18":1}}],["fostering",{"2":{"5":1}}],["forbidden",{"2":{"31":1,"86":1}}],["forwarded",{"2":{"127":1}}],["forward",{"2":{"31":2,"74":1}}],["formal",{"2":{"127":1}}],["formatted",{"2":{"86":2,"102":1,"124":1}}],["format",{"2":{"6":1,"21":1,"31":9,"86":2,"109":1,"124":2}}],["formulating",{"2":{"60":1}}],["formulation",{"2":{"19":1}}],["form",{"2":{"49":2,"86":2}}],["forseeable",{"2":{"6":1}}],["for",{"0":{"45":1,"71":1,"106":1,"109":1},"1":{"72":1,"73":1,"74":1},"2":{"3":4,"5":5,"6":1,"8":5,"10":7,"16":1,"18":1,"19":13,"20":3,"21":3,"22":3,"24":2,"25":3,"26":2,"27":3,"28":2,"29":1,"30":2,"31":13,"32":1,"33":6,"34":4,"35":5,"36":4,"42":1,"43":1,"44":1,"47":1,"54":6,"63":1,"70":1,"72":1,"73":3,"74":2,"77":1,"86":53,"87":5,"88":1,"89":3,"98":3,"99":2,"100":2,"101":1,"102":4,"103":2,"104":8,"106":4,"108":1,"109":2,"111":1,"113":2,"117":1,"119":5,"120":1,"122":1,"124":12,"125":4,"127":18}}],["faster",{"2":{"127":1}}],["facilities",{"2":{"31":6}}],["facilitating",{"2":{"19":1,"34":1}}],["facilitates",{"2":{"5":1,"19":1,"86":1,"119":1}}],["facilitate",{"2":{"4":1,"32":1}}],["fake",{"2":{"30":1,"86":1}}],["fakeautomaton",{"2":{"8":2,"19":1,"22":2,"25":1,"27":1,"30":5,"86":5}}],["fallback",{"2":{"21":1,"22":2,"24":1,"25":2,"26":1,"27":2,"86":4,"124":1}}],["false",{"2":{"1":3,"3":10,"8":1,"12":1,"22":2,"25":2,"27":2,"30":1,"35":3,"36":1,"38":4,"40":1,"44":1,"49":1,"54":2,"86":31,"100":1,"113":3,"119":1,"124":5,"127":2}}],["fa",{"2":{"8":1,"22":4,"25":2,"27":2,"30":3,"86":3}}],["vov",{"2":{"125":2}}],["v",{"2":{"86":3,"102":3,"122":7,"124":2,"125":4,"127":3}}],["vs",{"0":{"88":1},"2":{"35":3,"86":3}}],["vi",{"2":{"125":1}}],["viable",{"2":{"86":6,"106":5,"124":1}}],["visual",{"2":{"73":1}}],["vision",{"2":{"63":1}}],["vital",{"2":{"33":1}}],["vice",{"2":{"3":2,"86":3,"119":1}}],["vec",{"2":{"74":1}}],["vectorofvariables",{"2":{"125":1}}],["vectors",{"2":{"86":3,"94":2,"117":1}}],["vector",{"2":{"1":6,"6":2,"8":1,"21":1,"22":4,"24":4,"25":3,"26":1,"27":3,"29":1,"30":1,"36":2,"38":9,"46":1,"52":2,"86":59,"91":1,"94":2,"102":2,"109":2,"113":5,"117":10,"118":6,"122":2,"124":10,"125":2,"127":1}}],["verbose",{"2":{"127":4}}],["verbosity",{"2":{"127":1}}],["very",{"2":{"88":1}}],["verifies",{"2":{"52":2,"86":2}}],["versionnumber",{"2":{"122":1}}],["versions",{"2":{"122":3}}],["version",{"2":{"36":1,"73":1,"86":2,"119":1,"122":3}}],["versatile",{"2":{"86":2}}],["versatility",{"2":{"20":1}}],["versa",{"2":{"3":2,"86":3,"119":1}}],["var",{"2":{"127":12}}],["variety",{"2":{"89":1}}],["various",{"0":{"112":1},"1":{"113":1,"114":1},"2":{"14":1,"19":1,"21":1,"33":1,"57":1,"73":1,"84":1,"86":2,"89":1,"119":1,"124":1}}],["variant",{"2":{"54":2,"86":2}}],["variants",{"2":{"1":3,"3":4,"38":4,"40":1,"46":1,"49":1,"52":2,"54":2,"74":1,"86":19}}],["variableinfo",{"2":{"125":1}}],["variable",{"0":{"18":1},"1":{"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1},"2":{"3":6,"18":1,"19":1,"20":1,"22":3,"25":3,"27":3,"33":1,"35":1,"42":2,"47":2,"74":2,"86":9,"124":2,"125":4,"127":40}}],["variables",{"2":{"3":8,"30":1,"38":8,"40":2,"46":1,"47":1,"49":2,"52":1,"66":1,"74":3,"86":32,"87":1,"98":3,"103":1,"108":2,"124":4,"125":5,"127":26}}],["vars",{"2":{"6":1,"40":2,"54":15,"86":42,"98":6,"125":2,"127":24}}],["vars=dictionary",{"2":{"127":1}}],["vars=ones",{"2":{"38":2,"86":2}}],["vars=nothing",{"2":{"1":10,"86":10}}],["vars=",{"2":{"1":4,"40":2,"86":11}}],["vars=zeros",{"2":{"1":2,"86":2}}],["valparameterdomain",{"2":{"30":1,"86":1}}],["validity",{"2":{"46":1,"86":1}}],["valid",{"2":{"21":1,"52":1,"86":10,"88":2,"108":2,"109":3,"124":5}}],["val=3",{"2":{"38":1,"86":1}}],["val=2",{"2":{"3":1,"38":3,"86":4}}],["val=15",{"2":{"38":2,"86":2}}],["val=1",{"2":{"1":2,"3":1,"38":1,"86":4}}],["val=nothing",{"2":{"1":2,"3":2,"86":4}}],["valued",{"2":{"52":1,"86":1}}],["value",{"2":{"1":1,"3":13,"22":8,"25":7,"26":2,"27":10,"30":2,"31":1,"35":3,"36":5,"38":5,"49":4,"52":3,"74":3,"86":58,"100":2,"106":1,"109":1,"119":8,"124":13,"125":6,"127":20}}],["values",{"2":{"1":13,"3":4,"21":2,"24":2,"26":4,"30":3,"31":4,"35":2,"36":1,"38":24,"40":6,"47":2,"49":3,"52":2,"74":2,"86":66,"119":5,"124":4,"125":6,"127":11}}],["val",{"0":{"99":1,"118":1},"2":{"1":3,"3":8,"6":1,"16":2,"21":1,"31":4,"38":21,"49":4,"54":6,"86":74,"98":6,"99":6,"118":8,"119":8,"124":3,"127":8}}],["valsparameterdomain",{"2":{"30":1,"86":1}}],["vals=nothing",{"2":{"36":2,"86":2,"124":1}}],["vals=",{"2":{"1":2,"38":13,"86":15}}],["vals",{"2":{"1":2,"6":1,"38":18,"86":31,"117":8,"119":2}}],["tbw",{"2":{"104":4}}],["typically",{"2":{"88":1}}],["typeof",{"2":{"125":6}}],["typemax",{"2":{"113":1,"127":1}}],["type",{"2":{"8":4,"19":2,"21":6,"24":2,"26":5,"28":1,"29":1,"30":9,"31":7,"33":1,"35":1,"86":34,"89":2,"104":7,"106":1,"111":2,"119":1,"124":13,"125":32,"127":17}}],["types",{"2":{"4":1,"5":2,"19":3,"41":1,"47":1,"80":1,"86":2,"119":2,"127":8}}],["tutorials",{"0":{"83":1,"84":1},"1":{"84":1,"85":1},"2":{"84":1}}],["tuples",{"2":{"47":2,"86":6}}],["tuple",{"2":{"3":7,"21":5,"24":5,"26":5,"31":2,"54":1,"86":17,"124":5}}],["tips",{"2":{"77":1}}],["timelimitsec",{"2":{"125":1}}],["timestamps",{"2":{"127":1}}],["times",{"2":{"38":3,"86":3}}],["time",{"2":{"31":2,"54":8,"86":10,"89":1,"106":2,"119":1,"125":1,"127":27}}],["temporary",{"2":{"127":1}}],["terminationstatuscode",{"2":{"125":1}}],["terminology",{"0":{"66":1}}],["text",{"2":{"90":1,"93":1,"96":1,"115":1}}],["teach",{"2":{"78":1}}],["techniques",{"0":{"55":1,"67":1},"1":{"56":1,"57":1},"2":{"88":2,"89":2}}],["test",{"0":{"45":1},"2":{"104":2,"113":6}}],["testing",{"2":{"35":1,"86":1,"104":1,"125":1}}],["tendency",{"2":{"31":1}}],["tabu",{"2":{"81":1,"127":46}}],["table",{"2":{"36":4,"86":4,"113":1,"124":4}}],["task",{"2":{"54":16,"86":16}}],["tasks",{"2":{"54":18,"86":18,"127":1}}],["take",{"2":{"36":1,"74":1,"86":1,"89":1,"124":1}}],["takes",{"2":{"35":1,"36":1,"40":2,"86":4}}],["targeted",{"2":{"29":1,"73":1,"86":2,"124":2,"127":3}}],["tailoring",{"2":{"19":1,"33":1}}],["t",{"2":{"8":2,"21":8,"24":11,"26":14,"30":5,"31":10,"35":1,"36":2,"52":2,"86":29,"124":12,"125":12,"127":7}}],["tries",{"2":{"89":1}}],["tr",{"2":{"86":58,"102":3,"117":33,"118":18}}],["try",{"2":{"73":1,"89":1,"113":1}}],["train",{"2":{"86":3,"104":2,"111":3,"113":5,"124":2}}],["training",{"2":{"86":1,"104":7,"124":1}}],["traditional",{"2":{"33":1}}],["transpose",{"2":{"113":3}}],["transportation",{"2":{"88":1}}],["transported",{"2":{"31":1}}],["transform",{"2":{"86":1,"109":1,"124":1}}],["transforms",{"2":{"86":4,"119":4}}],["transformations",{"0":{"115":1,"116":1},"1":{"116":1,"117":2,"118":2,"119":2},"2":{"86":16,"100":1,"116":1,"119":15,"124":3}}],["transformation",{"2":{"86":12,"115":3,"119":8,"124":4}}],["transition",{"2":{"5":2}}],["true",{"2":{"1":3,"3":6,"8":3,"12":1,"22":2,"25":2,"27":2,"30":1,"35":2,"36":1,"38":4,"40":1,"44":1,"45":2,"49":1,"54":2,"86":28,"104":1,"106":1,"119":1,"124":4,"125":2,"127":3}}],["two",{"2":{"3":2,"8":1,"21":1,"24":3,"26":3,"31":1,"36":1,"41":1,"46":1,"47":1,"54":4,"86":11,"87":1,"124":3,"125":1}}],["th",{"2":{"86":1,"106":1}}],["threads",{"2":{"127":8}}],["threshold",{"2":{"86":1,"119":1}}],["throw",{"2":{"113":1}}],["through",{"2":{"33":1,"42":3,"44":2,"60":1,"73":3,"86":3,"91":1,"94":2,"104":2}}],["than",{"2":{"35":1,"36":1,"42":1,"86":11,"117":5,"118":2,"119":1,"125":2}}],["that",{"2":{"1":7,"3":14,"4":1,"5":6,"6":1,"18":1,"21":2,"22":2,"24":1,"25":2,"26":3,"27":2,"29":1,"31":2,"33":1,"35":11,"36":2,"38":11,"40":4,"42":4,"43":2,"44":1,"46":2,"47":4,"49":2,"52":5,"54":12,"73":1,"74":6,"75":1,"86":101,"87":3,"88":4,"89":5,"92":1,"95":1,"100":2,"102":2,"104":3,"106":3,"108":1,"119":3,"124":16,"125":11,"127":10}}],["those",{"2":{"33":1,"106":1}}],["thus",{"2":{"31":1}}],["this",{"2":{"3":2,"5":3,"6":1,"18":1,"19":1,"20":1,"29":1,"31":1,"32":1,"33":3,"35":1,"36":4,"43":1,"46":1,"52":2,"54":2,"74":2,"86":17,"106":2,"119":1,"121":1,"123":1,"124":2,"127":3}}],["third",{"2":{"3":2,"86":2}}],["theory",{"0":{"60":1}}],["them",{"2":{"46":1,"86":1,"87":1,"127":1}}],["they",{"2":{"31":1,"42":3,"47":3,"56":1,"62":1,"87":1,"88":1,"89":1}}],["there",{"2":{"31":3,"36":1,"52":1,"86":2}}],["thereby",{"2":{"5":1,"18":1}}],["then",{"2":{"29":1,"36":2,"43":1,"86":3,"124":1,"127":2}}],["these",{"2":{"19":1,"33":3,"36":1,"42":1,"47":2,"86":1,"89":1}}],["their",{"0":{"56":1},"2":{"5":1,"33":1,"57":1,"73":1,"74":1,"86":1,"119":1}}],["the",{"0":{"62":1},"2":{"1":10,"3":25,"4":2,"5":19,"6":10,"8":2,"12":1,"14":5,"16":2,"18":4,"19":14,"20":5,"21":8,"22":4,"24":8,"25":8,"26":6,"27":9,"29":13,"30":5,"31":54,"32":2,"33":19,"34":3,"35":46,"36":67,"38":41,"40":3,"41":1,"42":6,"43":9,"44":6,"46":6,"47":4,"49":16,"52":17,"54":33,"60":1,"62":1,"63":1,"69":1,"72":1,"73":9,"74":13,"75":3,"78":1,"82":1,"85":1,"86":464,"87":4,"88":3,"89":3,"90":1,"91":1,"92":3,"93":1,"95":3,"96":1,"97":2,"98":7,"99":3,"100":4,"102":4,"103":2,"104":17,"106":19,"108":1,"109":1,"115":5,"116":2,"117":25,"118":12,"119":12,"122":4,"123":1,"124":137,"125":17,"127":120}}],["too",{"2":{"89":1}}],["tool",{"2":{"32":1}}],["toolkit",{"2":{"20":1}}],["tools",{"0":{"35":1,"50":1},"2":{"19":1,"34":2}}],["towards",{"2":{"86":1,"124":1}}],["topics",{"2":{"84":1}}],["total",{"2":{"25":1,"27":1,"86":1}}],["todo",{"0":{"7":1,"9":1,"11":1,"13":1,"15":1,"17":1},"2":{"35":1,"43":1,"44":2,"73":1,"74":4,"86":1,"127":1}}],["to",{"0":{"22":1,"25":1,"27":1,"50":1,"60":1,"75":1,"107":1},"1":{"108":1},"2":{"1":9,"3":12,"4":1,"5":2,"6":1,"8":1,"12":1,"14":1,"16":1,"19":6,"21":4,"22":6,"24":3,"25":4,"26":1,"27":4,"29":3,"30":18,"31":19,"32":2,"33":4,"34":2,"35":17,"36":23,"38":13,"40":2,"42":1,"43":6,"44":3,"47":1,"49":3,"52":4,"54":2,"62":1,"73":4,"74":6,"75":1,"78":1,"85":1,"86":187,"87":3,"88":5,"89":9,"90":1,"93":1,"94":2,"96":1,"102":6,"103":1,"104":12,"106":3,"107":1,"108":1,"109":1,"111":1,"113":1,"115":2,"117":18,"118":7,"119":7,"121":1,"123":1,"124":46,"125":10,"127":49}}],["i+1",{"2":{"74":1}}],["iconic",{"2":{"74":1}}],["icnlocalsearchoptimizer",{"2":{"104":3}}],["icngeneticoptimizer",{"2":{"104":4}}],["icnoptimizer",{"2":{"104":3}}],["icnconfig",{"2":{"104":4}}],["icns",{"2":{"90":1,"93":1,"96":1,"104":1,"106":1,"115":1}}],["icn=icn",{"2":{"86":1,"124":1}}],["icn",{"0":{"106":1},"2":{"25":2,"27":2,"35":1,"86":36,"92":1,"95":1,"100":1,"104":12,"106":7,"119":1,"124":23}}],["ignores",{"2":{"54":1,"86":1}}],["ignore",{"2":{"54":1,"86":1}}],["ignored",{"2":{"54":2,"86":2}}],["illustrate",{"2":{"43":1}}],["io",{"2":{"31":2}}],["immutable",{"2":{"26":1,"86":1,"124":1}}],["impossible",{"2":{"89":1}}],["importance",{"2":{"75":1,"85":1}}],["improve",{"2":{"78":1,"88":1,"89":1}}],["improvement",{"0":{"78":1},"2":{"127":1}}],["improving",{"2":{"33":1,"127":1}}],["implemented",{"2":{"87":1}}],["implement",{"2":{"8":1,"21":1,"30":1,"86":2,"124":1}}],["implementations",{"2":{"19":1}}],["implementation",{"2":{"8":2,"86":2,"115":1,"124":2}}],["impact",{"2":{"5":1,"57":1}}],["i`",{"2":{"22":1,"25":1,"27":1,"86":1}}],["i",{"2":{"22":10,"24":7,"25":8,"26":3,"27":8,"30":2,"49":2,"54":4,"74":4,"86":64,"102":2,"103":1,"106":2,"113":2,"117":23,"118":13,"124":3,"127":1}}],["identity",{"2":{"86":14,"98":4,"117":6,"119":4}}],["identified",{"2":{"35":1,"86":1}}],["ids",{"2":{"30":1,"86":1}}],["idparameterdomain",{"2":{"30":1,"86":1}}],["id",{"2":{"6":1,"31":2,"86":1,"127":13}}],["id=3",{"2":{"3":1,"86":1}}],["id=1",{"2":{"3":3,"86":3}}],["id=nothing",{"2":{"3":4,"86":4}}],["iterate",{"2":{"127":1}}],["iterators",{"2":{"113":1}}],["iterations",{"2":{"127":3}}],["iteration",{"2":{"86":2,"124":2,"127":8}}],["iter=100",{"2":{"86":2,"124":2}}],["iter",{"2":{"86":8,"104":3,"124":8,"127":1}}],["ith",{"2":{"22":2,"25":1,"27":1,"30":1,"86":1}}],["itvls",{"2":{"24":3,"86":3}}],["itv",{"2":{"21":2,"22":8,"24":2,"25":7,"26":2,"27":7,"30":3,"86":9,"124":2}}],["itself",{"2":{"86":1,"124":1}}],["its",{"2":{"5":1,"24":1,"26":1,"31":1,"33":2,"35":1,"65":1,"69":1,"72":1,"73":2,"74":1,"75":1,"82":1,"86":5,"102":2,"124":3,"127":2}}],["it",{"2":{"4":1,"21":1,"30":8,"32":1,"35":9,"36":25,"38":2,"42":1,"43":1,"44":1,"46":2,"49":2,"52":1,"54":6,"73":1,"74":4,"86":65,"87":2,"89":2,"97":1,"104":1,"106":1,"109":1,"116":1,"119":1,"122":1,"124":6,"125":1,"127":6}}],["isa",{"2":{"113":1}}],["issue",{"0":{"45":1},"2":{"115":1}}],["isempty",{"2":{"10":1,"22":3,"86":3}}],["is",{"0":{"65":1},"2":{"3":10,"4":1,"5":4,"6":2,"19":2,"21":2,"22":5,"24":3,"25":4,"27":4,"29":3,"30":9,"31":9,"32":2,"33":3,"35":7,"36":14,"38":15,"40":3,"42":3,"43":1,"44":3,"46":2,"49":5,"52":9,"54":10,"73":1,"74":6,"86":154,"87":5,"88":5,"89":4,"92":1,"95":1,"100":2,"102":1,"104":5,"106":7,"109":4,"111":1,"117":20,"118":13,"119":4,"124":26,"125":8,"127":17}}],["iff",{"2":{"86":2,"100":1,"119":1,"124":2}}],["if",{"2":{"1":3,"3":4,"8":3,"21":1,"22":10,"25":9,"27":9,"29":2,"30":2,"35":9,"36":8,"38":4,"40":1,"49":1,"52":2,"54":2,"73":1,"74":1,"86":65,"98":2,"99":2,"104":1,"106":4,"109":4,"113":4,"117":2,"118":2,"124":12,"127":14}}],["init",{"2":{"113":1}}],["initial",{"2":{"89":1}}],["initializes",{"2":{"36":1,"86":1}}],["inner",{"2":{"104":1,"127":1}}],["inf",{"2":{"127":1}}],["info",{"2":{"125":2,"127":6}}],["information",{"2":{"73":1,"86":1,"104":1,"124":1,"127":1}}],["infrastructure",{"2":{"18":1}}],["involves",{"2":{"87":1}}],["involving",{"2":{"86":1,"119":1}}],["invalid",{"2":{"33":1,"35":1,"86":3,"124":1}}],["investigated",{"2":{"31":1}}],["input",{"2":{"31":1,"36":3,"86":3}}],["inputs",{"2":{"19":1,"35":1,"86":1}}],["instead",{"2":{"86":3,"102":2,"109":1,"124":3,"125":1,"127":1}}],["instructions",{"2":{"70":1}}],["installed",{"2":{"73":1,"122":1}}],["install",{"2":{"73":1}}],["installing",{"2":{"70":1}}],["installation",{"0":{"70":1}}],["instantiation",{"2":{"40":9,"86":9}}],["instances",{"2":{"73":1}}],["instance",{"2":{"19":1,"31":4,"52":2,"86":3,"109":1,"124":1,"127":2}}],["insertion",{"2":{"16":1,"86":1,"124":1,"125":1}}],["insert",{"2":{"16":1,"86":1,"124":1,"127":3}}],["independent",{"2":{"127":1}}],["independently",{"2":{"127":1}}],["indexed",{"2":{"3":2,"86":2}}],["index",{"2":{"3":3,"49":2,"86":5,"127":1}}],["industry",{"2":{"87":1}}],["indice",{"2":{"127":1}}],["indices",{"2":{"127":6}}],["indicate",{"2":{"127":2}}],["indicates",{"2":{"31":1,"35":2,"86":2,"124":2}}],["individuals",{"2":{"104":1}}],["indispensable",{"2":{"32":1}}],["ind",{"2":{"16":1,"86":1,"124":1,"127":2}}],["inc",{"2":{"127":6}}],["increment",{"2":{"127":3}}],["incremental",{"2":{"125":1}}],["increase",{"2":{"16":1,"86":1,"124":1}}],["increasing",{"2":{"1":10,"86":10}}],["inclusive",{"2":{"86":3,"106":3}}],["included",{"2":{"86":1}}],["include",{"2":{"33":1,"87":1}}],["includes",{"2":{"5":1,"54":1,"86":3,"100":1,"119":1,"124":2}}],["including",{"0":{"36":1},"2":{"19":1,"33":1}}],["incorporation",{"2":{"33":1,"34":1}}],["incsert",{"2":{"16":2,"86":1,"124":1}}],["introductory",{"2":{"75":1}}],["introduction",{"0":{"50":1,"107":1},"1":{"108":1},"2":{"107":1}}],["introduce",{"2":{"66":1,"69":1,"81":1,"127":1}}],["into",{"0":{"79":1},"1":{"80":1,"81":1,"82":1},"2":{"21":1,"31":1,"41":1,"56":1,"86":6,"91":1,"102":1,"104":1,"106":1,"109":1,"124":3,"127":1}}],["intend",{"2":{"127":1}}],["intentionally",{"2":{"42":1}}],["intentional",{"2":{"42":1}}],["intention",{"0":{"42":1,"43":1},"1":{"43":1,"44":1,"45":1,"46":1},"2":{"41":1,"42":2,"43":1,"44":2}}],["intensional",{"2":{"33":1,"46":1,"86":1}}],["intension",{"2":{"33":1,"43":1,"44":3,"46":2,"86":2}}],["integer",{"2":{"31":3,"38":1,"80":1,"86":1,"87":1}}],["integrating",{"2":{"34":1}}],["integration",{"0":{"0":1,"2":1,"32":1,"37":1,"39":1,"48":1,"51":1,"53":1},"1":{"1":1,"3":1,"33":1,"34":1,"35":1,"36":1,"38":1,"40":1,"49":1,"52":1,"54":1},"2":{"33":3}}],["integrates",{"2":{"19":1}}],["integrate",{"2":{"5":1}}],["interfacing",{"0":{"123":1}}],["interfaced",{"2":{"121":1}}],["interfaces",{"2":{"73":1}}],["interface",{"0":{"111":1},"2":{"5":3,"8":2,"21":1,"42":1,"44":1,"73":2,"86":4,"87":3,"111":1,"123":1,"124":1,"125":1}}],["interpretable",{"2":{"86":1,"106":1,"124":1}}],["interpreted",{"2":{"52":2,"86":2}}],["interdiction",{"2":{"31":2,"127":2}}],["interval",{"2":{"21":1,"22":2,"24":6,"25":2,"26":3,"27":2,"30":1,"86":8,"124":1}}],["intervals",{"2":{"19":2,"21":2,"22":5,"24":5,"25":4,"26":2,"27":4,"28":2,"30":2,"86":11,"124":2}}],["intersect",{"2":{"19":1,"24":2,"26":1,"86":2,"124":1}}],["intersecting",{"2":{"19":1}}],["intersections",{"2":{"24":2,"26":1,"86":2,"124":1}}],["intersection",{"2":{"6":1,"36":1,"86":1,"124":1}}],["internally",{"2":{"86":1,"102":1}}],["internals",{"2":{"19":1,"29":1,"86":1}}],["internal",{"2":{"8":1,"21":1,"31":2,"86":4,"106":1,"124":1,"127":4}}],["interacting",{"2":{"33":1,"106":1}}],["interact",{"2":{"5":1}}],["interoperability",{"2":{"4":1,"5":1}}],["int",{"2":{"1":8,"3":1,"22":2,"25":2,"27":2,"29":1,"31":11,"36":1,"38":9,"46":1,"49":1,"52":2,"74":1,"86":35,"102":8,"113":2,"124":4,"125":6,"127":30}}],["in",{"0":{"0":1,"2":1,"20":1,"32":1,"34":1,"37":1,"39":1,"43":1,"48":1,"51":1,"53":1},"1":{"1":1,"3":1,"33":1,"34":1,"35":1,"36":1,"38":1,"40":1,"49":1,"52":1,"54":1},"2":{"1":6,"3":14,"4":1,"5":1,"6":1,"8":2,"10":1,"14":1,"16":1,"20":1,"21":4,"22":6,"24":3,"25":8,"26":5,"27":9,"29":2,"30":1,"31":9,"32":2,"33":3,"34":1,"35":4,"36":7,"38":24,"40":4,"41":1,"42":2,"43":1,"44":3,"46":1,"47":1,"49":6,"54":18,"65":1,"73":1,"74":7,"75":1,"82":1,"85":1,"86":131,"87":7,"89":3,"98":2,"102":2,"103":1,"104":3,"106":7,"113":2,"115":1,"117":1,"119":1,"122":1,"124":29,"125":16,"127":16}}],["df",{"2":{"104":2,"113":24}}],["ds",{"2":{"104":2}}],["date",{"2":{"31":1}}],["datatype",{"2":{"127":1}}],["dataframe",{"2":{"104":1,"113":2}}],["data",{"2":{"5":1,"86":2,"119":2,"127":1}}],["d₂",{"2":{"24":2,"26":2,"86":2,"124":2}}],["d₁",{"2":{"24":2,"26":2,"86":2,"124":2}}],["draw",{"2":{"22":2,"25":1,"27":1,"30":1,"86":1,"127":5}}],["d5",{"2":{"21":1,"24":1,"26":1,"86":1,"124":1}}],["d4",{"2":{"21":1,"24":1,"26":1,"86":1,"124":1}}],["d3",{"2":{"21":1,"24":1,"26":1,"86":1,"124":1}}],["d2",{"2":{"21":1,"24":1,"26":1,"86":1,"124":1}}],["dynamic",{"2":{"19":3,"21":1,"24":1,"31":1,"86":3,"119":1,"124":1,"127":11}}],["dom",{"2":{"86":8,"104":2,"113":4,"124":4}}],["domain",{"2":{"19":10,"20":1,"21":19,"22":1,"24":12,"25":1,"26":15,"27":1,"29":1,"30":9,"31":1,"38":1,"74":1,"86":46,"87":1,"104":3,"109":4,"124":32,"127":20}}],["domains",{"0":{"18":1},"1":{"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1},"2":{"18":2,"19":8,"20":1,"21":4,"22":3,"24":9,"25":2,"26":7,"27":2,"28":2,"29":6,"30":1,"31":1,"66":1,"86":30,"104":2,"113":11,"124":23,"127":3}}],["download",{"2":{"73":1}}],["do",{"2":{"54":4,"86":6,"119":1,"124":1}}],["doesn",{"2":{"35":1,"36":2,"86":3}}],["does",{"2":{"35":1,"36":3,"54":2,"86":9,"125":1}}],["documentation",{"0":{"46":1},"2":{"31":1,"73":1,"101":1,"104":1,"120":1,"121":1,"122":1,"125":1,"127":1}}],["documentervitepress",{"0":{"45":1}}],["documenter",{"2":{"8":1,"10":3,"98":1,"99":1,"100":1,"102":1,"103":1,"106":1}}],["docstring",{"2":{"8":2,"10":6,"98":2,"99":2,"100":2,"102":2,"103":2,"106":2,"125":26,"127":29}}],["d",{"2":{"16":1,"21":14,"22":29,"24":7,"25":23,"26":9,"27":26,"28":1,"30":12,"52":4,"86":54,"104":2,"113":2,"124":22,"127":9}}],["due",{"2":{"31":1,"73":1}}],["during",{"2":{"12":1,"86":1,"106":2}}],["duplication",{"2":{"5":1}}],["diff",{"2":{"86":4,"98":2,"99":2}}],["differs",{"0":{"67":1}}],["difference",{"2":{"14":2,"21":1,"24":1,"26":1,"86":12,"98":3,"99":3,"117":2,"118":2,"124":2}}],["different",{"2":{"1":8,"5":1,"6":1,"19":1,"31":1,"35":5,"36":8,"42":1,"43":6,"44":3,"45":2,"46":6,"73":1,"74":1,"86":29,"88":1,"119":3,"124":4,"127":1}}],["digits",{"2":{"74":2}}],["dive",{"0":{"79":1},"1":{"80":1,"81":1,"82":1},"2":{"56":1}}],["directions",{"0":{"63":1},"2":{"86":1,"119":1}}],["directed",{"2":{"52":1,"86":1}}],["directly",{"2":{"5":1,"33":1,"42":1,"44":1,"86":1}}],["dispatch",{"2":{"86":1,"104":1,"119":1,"127":2}}],["displays",{"2":{"31":1}}],["display",{"2":{"31":13}}],["discuss",{"2":{"57":1,"72":1,"85":1}}],["discreteset",{"2":{"125":3}}],["discretedomain",{"2":{"19":1,"21":1,"22":3,"24":1,"25":3,"26":4,"27":3,"30":1,"86":7,"113":1,"124":2}}],["discrete",{"0":{"26":1},"1":{"27":1},"2":{"18":1,"19":2,"21":1,"24":1,"26":4,"86":5,"104":1,"124":4,"127":1}}],["distributed",{"2":{"127":1}}],["distdifferent",{"2":{"44":1,"125":2}}],["dist",{"2":{"42":1,"43":6,"44":3,"45":2,"46":5,"86":5,"127":1}}],["distinct",{"2":{"38":2,"74":2,"86":2}}],["distinguishes",{"2":{"19":1}}],["distances",{"2":{"31":4,"43":2,"46":1,"86":1}}],["distance",{"2":{"21":2,"24":1,"26":1,"31":1,"46":3,"86":8,"103":1,"124":5,"127":1}}],["diagram",{"2":{"8":1,"52":4,"86":5,"124":1}}],["diagrams",{"2":{"8":2,"86":1}}],["dictionaries",{"0":{"16":1},"1":{"17":1},"2":{"16":1}}],["dictionaryview",{"2":{"127":1}}],["dictionary",{"2":{"6":1,"16":1,"31":3,"33":2,"35":1,"36":14,"86":18,"119":2,"124":8,"127":6}}],["dict",{"2":{"6":3,"36":8,"52":4,"86":12,"124":8}}],["dict=usual",{"2":{"6":1,"36":1,"86":1,"124":1}}],["dimension",{"2":{"125":6,"127":1}}],["dimensions",{"2":{"30":1,"86":1}}],["dimparameterdomain",{"2":{"30":1,"86":1}}],["dim",{"2":{"6":1,"54":2,"86":3,"113":3,"125":12,"127":4}}],["dim=2",{"2":{"3":2,"86":2}}],["dim=1",{"2":{"3":2,"86":2}}],["deepcopy",{"2":{"127":1}}],["deeper",{"2":{"56":1}}],["debugging",{"2":{"127":1}}],["debinarize",{"2":{"86":1,"109":1,"124":1}}],["denotes",{"2":{"86":2,"98":2}}],["density",{"2":{"29":1,"86":1,"124":1}}],["derived",{"2":{"86":1}}],["delta",{"2":{"127":6}}],["delegates",{"2":{"86":1,"119":1}}],["delete",{"2":{"19":1,"21":1,"27":3,"35":1,"86":5,"124":4,"127":13}}],["deletion",{"2":{"19":1}}],["delineation",{"2":{"86":2}}],["dedicated",{"2":{"43":1}}],["descent",{"0":{"113":1},"2":{"104":1}}],["descriptions",{"2":{"36":4,"86":4,"124":4}}],["description",{"2":{"36":2,"43":1,"86":3,"124":2,"125":36,"127":10}}],["describe",{"2":{"36":2,"86":2,"90":1,"93":1,"96":1,"113":1,"115":1,"124":2,"127":3}}],["describes",{"2":{"31":1}}],["design",{"2":{"5":1}}],["designed",{"2":{"4":1,"32":1,"42":1,"44":1}}],["depend",{"2":{"86":1,"119":1}}],["depending",{"2":{"73":1}}],["depends",{"2":{"21":1,"86":1,"124":1,"127":1}}],["dependencies",{"2":{"5":1}}],["determined",{"2":{"127":1}}],["determine",{"2":{"35":1,"86":2,"124":1}}],["determining",{"2":{"19":1,"33":1}}],["deterministic",{"2":{"8":1,"86":1,"124":1}}],["details",{"2":{"8":1,"10":3,"98":1,"99":1,"100":1,"102":1,"103":1,"106":1}}],["decrement",{"2":{"127":1}}],["decrease",{"2":{"127":2}}],["decreasing",{"2":{"1":8,"86":8}}],["decay",{"2":{"127":3}}],["declare",{"2":{"86":1}}],["decisions",{"2":{"88":1}}],["decision",{"2":{"8":3,"52":1,"86":3,"124":1}}],["developers",{"2":{"32":1}}],["developing",{"2":{"5":1}}],["development",{"2":{"4":1,"5":3}}],["define",{"2":{"33":1,"36":3,"42":1,"43":2,"47":1,"65":1,"74":1,"86":6,"124":2}}],["defines",{"2":{"24":1,"26":1,"44":1,"86":2,"106":1,"124":1}}],["defined",{"0":{"52":1},"2":{"19":2,"21":1,"26":1,"33":1,"36":1,"38":1,"42":3,"46":1,"47":3,"74":2,"86":9,"98":1,"104":2,"117":1,"124":2,"125":2,"127":1}}],["defining",{"0":{"18":1,"43":1},"1":{"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1},"2":{"19":1,"20":1,"33":2,"36":1,"42":1,"44":1,"86":1,"124":1}}],["definitions",{"2":{"19":1}}],["definition",{"0":{"0":1,"2":1,"32":1,"37":1,"39":1,"48":1,"51":1,"53":1},"1":{"1":1,"3":1,"33":1,"34":1,"35":1,"36":1,"38":1,"40":1,"49":1,"52":1,"54":1},"2":{"18":1,"19":1,"32":1,"33":1,"34":1,"36":1,"86":1}}],["default",{"2":{"6":3,"22":1,"29":1,"31":10,"36":8,"38":1,"86":17,"104":4,"109":1,"111":1,"124":10,"127":2}}],["defaults",{"2":{"1":1,"6":1,"16":1,"36":6,"86":8,"104":2,"124":2}}],["auto",{"2":{"113":1}}],["automated",{"2":{"36":1,"86":1}}],["automatic",{"2":{"29":1,"86":1,"124":1}}],["automatically",{"2":{"29":1,"86":1}}],["automaton",{"2":{"8":6,"30":4,"52":7,"86":15,"124":3}}],["automata",{"2":{"8":2,"19":1,"86":1}}],["among",{"2":{"104":1,"127":1}}],["amount",{"2":{"31":1}}],["affects",{"2":{"97":1,"116":1}}],["affect",{"2":{"86":1,"124":1}}],["aggragation",{"2":{"90":1}}],["aggregate",{"2":{"86":1,"91":1}}],["aggregations",{"0":{"91":1},"2":{"86":1,"92":1,"124":1}}],["aggregation",{"0":{"90":1},"1":{"91":1,"92":1},"2":{"86":4,"92":1,"124":4}}],["ag",{"2":{"86":2,"91":2}}],["against",{"2":{"40":1,"86":2,"119":1}}],["again",{"2":{"31":1}}],["apixcspjumpmoi",{"2":{"44":1}}],["apis",{"0":{"44":1}}],["api",{"0":{"43":1,"86":1,"124":1},"2":{"42":1,"44":1}}],["appropriate",{"2":{"86":1,"119":1}}],["approach",{"2":{"5":1,"33":1,"74":1,"88":2}}],["appear",{"2":{"38":3,"86":3}}],["applies",{"2":{"86":1,"102":1,"125":1}}],["applied",{"2":{"35":1,"36":1,"59":1,"74":1,"86":3,"119":1,"124":2,"125":1,"127":2}}],["applicability",{"2":{"33":1}}],["applications",{"0":{"59":1},"2":{"18":1,"20":1}}],["application",{"2":{"5":2,"32":1,"33":1,"34":1,"86":1}}],["applying",{"0":{"58":1},"1":{"59":1,"60":1}}],["apply",{"2":{"33":1,"35":5,"36":3,"86":7,"119":2,"124":5}}],["about",{"0":{"105":1},"2":{"50":1,"87":1,"105":1,"126":1,"127":1}}],["absolute",{"2":{"86":2,"98":1,"99":1}}],["abs",{"2":{"36":1,"43":2,"44":2,"86":5,"98":2,"99":2,"124":1}}],["abstractstring",{"2":{"127":2}}],["abstractstring=",{"2":{"86":1,"124":1}}],["abstractstate",{"2":{"127":1}}],["abstractsolver",{"2":{"127":70}}],["abstractscalarset",{"2":{"125":1}}],["abstractscalarfunction",{"2":{"125":1}}],["abstractoptimizer",{"2":{"86":2,"104":2,"111":2,"113":1,"124":1,"125":1}}],["abstractmatrix",{"2":{"31":4}}],["abstractmultivalueddecisiondiagram",{"2":{"8":3,"86":3,"124":1}}],["abstractrange",{"2":{"21":1,"24":1,"26":2,"86":2,"124":2}}],["abstracting",{"2":{"20":1}}],["abstractdomain",{"2":{"19":3,"21":5,"22":6,"24":4,"25":5,"26":4,"27":5,"28":1,"30":10,"86":25,"124":10,"127":6}}],["abstractdictionary",{"2":{"16":1,"86":1,"124":1}}],["abstractdict",{"2":{"16":1,"86":1,"124":1}}],["abstractautomaton`",{"2":{"52":1,"86":1}}],["abstractautomaton",{"2":{"8":3,"30":1,"52":2,"86":6,"124":1}}],["abstract",{"2":{"4":1,"5":2,"8":2,"19":1,"21":1,"24":1,"26":1,"86":6,"104":2,"111":1,"124":3,"127":2}}],["abstractvectorset",{"2":{"125":15}}],["abstractvector",{"2":{"3":4,"40":2,"49":1,"54":5,"86":31,"102":1,"117":11,"118":6,"127":1}}],["ability",{"2":{"33":1}}],["avoid",{"2":{"35":1,"86":2,"124":1,"127":1}}],["avoiding",{"2":{"33":1}}],["available",{"2":{"19":1,"31":2,"34":1,"36":1,"42":1,"44":1,"73":2,"86":2,"87":1,"119":1,"124":1,"127":1}}],["always",{"2":{"125":1}}],["alwaystrue",{"2":{"125":2}}],["alternative",{"2":{"106":1}}],["although",{"2":{"73":1}}],["algorithm",{"2":{"86":4,"89":2,"104":3,"124":4}}],["algorithms",{"2":{"81":1,"89":1}}],["along",{"2":{"73":1}}],["already",{"2":{"36":1,"74":1,"86":3,"98":1,"104":1,"117":1,"127":1}}],["also",{"2":{"19":1,"38":3,"74":1,"86":5,"100":1,"119":1,"124":2}}],["allequalparam",{"2":{"125":2}}],["allequal",{"2":{"125":2}}],["allocation",{"2":{"88":1}}],["allocations",{"2":{"86":17,"117":10,"118":6}}],["allow",{"2":{"47":1}}],["allows",{"2":{"33":2}}],["allowing",{"2":{"19":1,"86":3,"119":1}}],["alldifferent",{"2":{"74":5,"125":2}}],["all",{"2":{"1":24,"6":1,"14":1,"19":1,"24":1,"31":1,"35":4,"36":9,"38":1,"47":1,"73":1,"74":2,"86":45,"87":1,"89":1,"100":1,"102":1,"119":1,"122":2,"124":10,"125":7,"127":4}}],["advantages",{"2":{"72":1}}],["advanced",{"0":{"34":1,"55":1},"1":{"56":1,"57":1},"2":{"19":1,"20":1,"33":1}}],["adjusted",{"2":{"29":1,"86":1}}],["added",{"2":{"43":1,"44":1,"125":1}}],["adds",{"2":{"36":4,"86":4}}],["adding",{"2":{"36":2,"86":2,"124":2}}],["additionally",{"2":{"21":1,"86":1,"124":1}}],["addition",{"2":{"19":1,"33":1}}],["add",{"2":{"19":1,"21":1,"26":2,"35":1,"42":1,"43":1,"73":1,"74":4,"86":4,"124":3,"125":6,"127":20}}],["attribution",{"2":{"127":1}}],["attributed",{"2":{"127":6}}],["attribute",{"2":{"127":2}}],["attached",{"2":{"127":1}}],["atoms",{"2":{"31":1}}],["at",{"2":{"8":1,"19":1,"31":1,"33":1,"36":1,"38":8,"54":2,"73":1,"86":15,"104":2,"106":2,"109":1,"124":3,"127":1}}],["accurate",{"2":{"113":2}}],["according",{"2":{"86":1,"119":1}}],["access",{"2":{"21":1,"86":5,"106":1,"124":4,"127":20}}],["accessing",{"2":{"19":1}}],["acceptable",{"2":{"86":2}}],["accepted",{"2":{"35":2,"52":2,"86":4,"124":2}}],["accepts",{"2":{"8":3,"30":1,"31":5,"86":3,"124":1}}],["accept",{"2":{"8":6,"30":3,"86":7,"124":1}}],["action",{"2":{"86":2,"124":2}}],["actively",{"2":{"5":1}}],["actual",{"2":{"86":1,"124":1}}],["across",{"2":{"5":2}}],["assuming",{"2":{"125":1}}],["assert",{"2":{"86":1,"106":1}}],["associated",{"2":{"31":1,"74":1,"106":1}}],["assign",{"2":{"31":1,"86":1,"124":1,"127":1}}],["assignments",{"2":{"33":2,"35":1,"86":1,"124":1}}],["assignment",{"2":{"31":1,"35":1,"86":1,"124":1}}],["aspect",{"2":{"5":1}}],["as",{"2":{"4":1,"5":1,"8":1,"12":1,"18":1,"19":1,"24":1,"26":3,"31":3,"33":2,"35":1,"36":9,"38":3,"42":3,"44":2,"46":1,"52":2,"66":1,"73":1,"74":1,"86":27,"87":1,"88":2,"98":1,"102":2,"104":1,"106":1,"117":1,"119":1,"122":1,"123":1,"124":7,"125":2,"127":6}}],["a",{"0":{"106":1},"2":{"1":3,"3":22,"4":1,"5":6,"8":12,"16":2,"18":2,"19":2,"20":2,"21":9,"22":19,"24":8,"25":17,"26":8,"27":17,"29":6,"30":15,"31":28,"32":1,"33":7,"34":1,"35":18,"36":21,"38":13,"40":8,"42":10,"43":2,"44":3,"46":5,"47":4,"49":8,"52":29,"54":8,"60":1,"73":2,"74":12,"86":277,"87":7,"88":4,"89":7,"91":2,"94":2,"102":8,"103":2,"104":23,"106":16,"108":2,"109":7,"111":1,"115":1,"119":10,"121":1,"122":3,"124":75,"125":17,"127":51}}],["angles",{"2":{"88":1}}],["anonymous",{"2":{"86":1,"102":1}}],["another",{"2":{"3":2,"86":2,"87":1}}],["annealing",{"2":{"81":1}}],["analyze",{"2":{"78":1,"88":1}}],["analyzing",{"0":{"76":1},"1":{"77":1,"78":1}}],["analysis",{"0":{"78":1,"85":1},"2":{"85":1,"88":1}}],["any",{"0":{"106":1},"2":{"10":1,"21":2,"22":1,"25":1,"27":1,"31":1,"35":2,"46":1,"54":6,"86":18,"111":1,"124":7,"125":1,"127":1}}],["an",{"0":{"43":1},"2":{"1":3,"4":1,"8":2,"19":1,"21":2,"24":6,"25":1,"26":3,"27":1,"29":1,"31":3,"32":1,"33":1,"35":4,"36":6,"38":1,"43":1,"44":1,"46":1,"52":3,"60":1,"74":1,"75":2,"86":57,"89":3,"102":3,"104":7,"106":5,"111":1,"115":1,"118":1,"119":1,"123":1,"124":19,"125":2,"127":11}}],["and",{"0":{"0":1,"2":1,"5":1,"18":1,"19":1,"32":1,"33":1,"36":1,"37":1,"38":1,"39":1,"48":1,"51":1,"53":1,"54":1,"56":1,"57":1,"59":1,"61":1,"66":1,"70":1,"71":1,"76":1,"78":1,"83":1},"1":{"1":1,"3":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"33":1,"34":1,"35":1,"36":1,"38":1,"40":1,"49":1,"52":1,"54":1,"62":1,"63":1,"72":1,"73":1,"74":1,"77":1,"78":1,"84":1,"85":1},"2":{"3":2,"4":3,"5":14,"6":1,"8":1,"10":1,"12":1,"14":1,"18":2,"19":11,"20":4,"21":2,"24":2,"26":1,"29":2,"30":2,"31":13,"32":3,"33":14,"34":2,"35":10,"36":10,"38":1,"41":1,"42":1,"46":3,"47":1,"49":2,"52":1,"56":1,"57":1,"59":1,"60":1,"62":1,"63":1,"65":1,"66":1,"67":1,"69":1,"70":1,"72":2,"73":2,"74":4,"75":2,"77":2,"78":1,"81":1,"82":1,"84":1,"85":1,"86":66,"87":3,"88":8,"89":3,"97":1,"98":1,"99":1,"102":1,"104":10,"106":3,"108":1,"109":1,"116":1,"117":5,"118":1,"119":3,"121":1,"122":1,"124":24,"125":2,"127":11}}],["arrange",{"2":{"122":3}}],["arrangement",{"2":{"104":1}}],["ar",{"2":{"86":2,"94":2}}],["arithmetic",{"0":{"93":1,"94":1},"1":{"94":1,"95":1},"2":{"86":5,"93":1,"95":2,"124":5}}],["arxiv",{"2":{"36":1,"86":1,"124":1}}],["arbitrary",{"2":{"26":1,"35":1,"86":2}}],["arbitrarydomain",{"2":{"26":1,"86":1}}],["argmax",{"2":{"127":3}}],["argument",{"2":{"31":5,"36":7,"86":7,"125":1}}],["arguments",{"2":{"1":3,"3":4,"6":1,"21":1,"24":1,"29":1,"31":1,"35":9,"36":11,"38":4,"40":1,"46":1,"49":1,"52":2,"54":2,"86":43,"124":15,"125":13,"127":8}}],["args",{"2":{"21":4,"29":1,"33":1,"35":7,"36":4,"86":13,"104":3,"111":1,"124":10}}],["areas",{"2":{"63":1}}],["are",{"2":{"1":10,"5":2,"19":1,"24":1,"26":1,"29":1,"31":5,"33":2,"36":1,"41":1,"42":4,"43":2,"46":2,"47":4,"54":2,"74":1,"86":42,"87":2,"88":2,"92":1,"95":1,"100":1,"106":2,"117":10,"118":5,"119":1,"124":6,"125":4,"127":2}}],["jacop",{"2":{"87":1}}],["j+1",{"2":{"74":1}}],["j",{"2":{"74":1}}],["join",{"2":{"62":1}}],["joining",{"0":{"62":1}}],["jc",{"0":{"43":1},"2":{"42":1,"44":2}}],["jump",{"2":{"31":20,"42":1,"44":3,"73":3,"74":2,"87":1,"125":6,"127":1}}],["juliajump",{"2":{"125":1}}],["juliajulia>",{"2":{"122":1}}],["juliapost",{"2":{"127":1}}],["juliapredicate",{"2":{"125":1}}],["juliapredict",{"2":{"104":1}}],["juliapreliminaries",{"2":{"104":1}}],["juliaparameter",{"2":{"104":1}}],["juliaparams",{"2":{"35":1,"86":1,"124":1}}],["juliapairvarsparameterdomain",{"2":{"30":1,"86":1}}],["juliaqubogradientoptimizer",{"2":{"104":1}}],["juliaqubo",{"2":{"86":2,"104":1,"108":2,"124":1}}],["juliaqap",{"2":{"31":1}}],["juliaweights",{"2":{"86":3,"124":3}}],["juliatrain",{"2":{"86":1,"104":2,"111":1,"124":1}}],["juliatransformation",{"2":{"86":1,"119":1,"124":1}}],["juliatr",{"2":{"86":19,"117":11,"118":6}}],["juliato",{"2":{"21":1,"86":1,"124":1}}],["juliaremote",{"2":{"127":2}}],["juliaregularization",{"2":{"86":1,"124":1}}],["juliareduce",{"2":{"86":1,"102":1}}],["juliarangedomain",{"2":{"26":1,"86":1,"124":1}}],["juliahamming",{"2":{"86":1,"103":1,"124":1}}],["juliafunctions",{"2":{"86":1,"106":1}}],["juliafor",{"2":{"74":2}}],["juliafake",{"2":{"30":1,"86":1}}],["juliafakeautomaton",{"2":{"30":1,"86":1}}],["juliausing",{"2":{"73":2}}],["juliausual",{"2":{"35":1,"36":2,"86":3,"124":2}}],["juliaup",{"2":{"73":1}}],["juliano",{"2":{"104":1}}],["julianbits",{"2":{"86":2,"106":1,"124":1}}],["julian",{"2":{"31":1}}],["juliagolomb",{"2":{"31":1}}],["juliageneralstate",{"2":{"127":1}}],["juliagenerate",{"2":{"30":1,"86":5,"104":1,"106":2,"124":1}}],["juliaget",{"2":{"21":1,"86":1,"124":1,"127":12}}],["juliastop",{"2":{"127":1}}],["juliastatus",{"2":{"127":1}}],["juliastruct",{"2":{"86":1,"104":1,"113":1,"124":1}}],["juliaspecialize",{"2":{"127":2}}],["juliasolve",{"2":{"127":2}}],["juliasolution",{"2":{"127":1}}],["juliascalarfunction",{"2":{"125":1}}],["juliascheduling",{"2":{"31":1}}],["juliasub",{"2":{"104":1}}],["juliasudoku",{"2":{"31":1}}],["juliasudokuinstance",{"2":{"31":2}}],["juliasymbols",{"2":{"86":1,"124":1}}],["juliasymbol",{"2":{"86":1,"106":1}}],["juliasymmetries",{"2":{"35":1,"86":1,"124":1}}],["juliashow",{"2":{"86":2,"106":1,"124":1}}],["juliashrink",{"2":{"35":1,"86":1}}],["juliaselected",{"2":{"86":1,"106":1}}],["juliasetdomain",{"2":{"26":1,"86":1}}],["juliavalue",{"2":{"74":1}}],["juliavalsparameterdomain",{"2":{"30":1,"86":1}}],["juliavalparameterdomain",{"2":{"30":1,"86":1}}],["juliavariable",{"2":{"127":3}}],["juliavar",{"2":{"22":1,"25":1,"27":1,"127":1}}],["juliao",{"2":{"127":1}}],["juliaobjective",{"2":{"127":4}}],["juliaoptions",{"2":{"127":1}}],["juliaoptimizer",{"2":{"125":2}}],["juliaoptimize",{"2":{"74":1,"104":1}}],["juliaopparameterdomain",{"2":{"30":1,"86":1}}],["juliaoversample",{"2":{"12":1,"86":1,"124":1}}],["julialoss",{"2":{"104":1}}],["julialeadsolver",{"2":{"127":1}}],["julialearn",{"2":{"86":1,"124":1}}],["julialength",{"2":{"25":1,"27":1,"86":1,"106":1,"127":5}}],["julialazy",{"2":{"86":2,"102":2,"124":2}}],["julialayers",{"2":{"86":1}}],["julialayer",{"2":{"86":1,"106":1}}],["julialanguageparameterdomain",{"2":{"30":1,"86":1}}],["juliais",{"2":{"86":2,"106":1,"109":1,"124":1,"127":2}}],["juliaicnlocalsearchoptimizer",{"2":{"104":1}}],["juliaicngeneticoptimizer",{"2":{"104":1}}],["juliaicnconfig",{"2":{"104":1}}],["juliaicn",{"2":{"86":1,"104":1,"124":1}}],["juliaidparameterdomain",{"2":{"30":1,"86":1}}],["juliaintersect",{"2":{"24":2,"26":1,"86":2,"124":1}}],["juliaintervals",{"2":{"24":1,"86":1}}],["juliaincsert",{"2":{"16":1,"86":1,"124":1}}],["juliabinarize",{"2":{"86":1,"109":1,"124":1}}],["juliaboolparameterdomain",{"2":{"30":1,"86":1}}],["juliabase",{"2":{"22":13,"24":1,"25":12,"26":1,"27":13,"28":2,"30":4,"31":4,"86":18,"124":2,"125":2}}],["juliamodel",{"2":{"127":1}}],["juliamoi",{"2":{"125":11}}],["juliamoisumequalparam",{"2":{"125":1}}],["juliamoisequentialtasks",{"2":{"125":1}}],["juliamoipredicate",{"2":{"125":1}}],["juliamoiordered",{"2":{"125":1}}],["juliamoiminusequalparam",{"2":{"125":1}}],["juliamoilessthanparam",{"2":{"125":1}}],["juliamoierror",{"2":{"125":1}}],["juliamoieq",{"2":{"125":1}}],["juliamoidistdifferent",{"2":{"125":1}}],["juliamoialwaystrue",{"2":{"125":1}}],["juliamoiallequalparam",{"2":{"125":1}}],["juliamoiallequal",{"2":{"125":1}}],["juliamoialldifferent",{"2":{"125":1}}],["juliamts",{"2":{"127":1}}],["juliamutually",{"2":{"104":1}}],["juliamutable",{"2":{"31":1}}],["juliaminkowski",{"2":{"86":1,"103":1,"124":1}}],["juliamincut",{"2":{"31":1}}],["juliam",{"2":{"74":1}}],["juliamax",{"2":{"127":1}}],["juliamainsolver",{"2":{"127":1}}],["juliamap",{"2":{"86":1,"102":1}}],["juliamanhattan",{"2":{"86":1,"103":1,"124":1}}],["juliamake",{"2":{"35":1,"86":2,"104":3,"119":1}}],["juliamagic",{"2":{"31":1}}],["juliamerge",{"2":{"24":1,"26":1,"86":1,"124":1}}],["juliamdd",{"2":{"8":1,"86":1,"124":1}}],["juliax",{"2":{"22":1,"25":1,"27":1,"127":1}}],["juliaxcsp",{"2":{"1":3,"3":4,"38":4,"40":1,"46":1,"49":1,"52":2,"54":2,"86":19}}],["juliad",{"2":{"127":1}}],["juliadraw",{"2":{"127":1}}],["juliadelete",{"2":{"127":2}}],["juliadebinarize",{"2":{"86":1,"109":1,"124":1}}],["juliadescribe",{"2":{"36":2,"86":2,"124":2,"127":1}}],["juliadist",{"2":{"127":1}}],["juliadiscreteset",{"2":{"125":1}}],["juliadiscretedomain",{"2":{"26":1,"86":1,"124":1}}],["juliadisplay",{"2":{"31":1}}],["juliadimparameterdomain",{"2":{"30":1,"86":1}}],["juliad1",{"2":{"21":1,"24":1,"26":1,"86":1,"124":1}}],["juliadomain",{"2":{"21":6,"24":6,"26":6,"86":6,"104":1,"124":6,"127":1}}],["juliaempty",{"2":{"127":2}}],["juliaemptydomain",{"2":{"21":1,"86":1}}],["juliae",{"2":{"35":1,"86":1}}],["juliaerror",{"2":{"35":1,"86":1,"124":1,"125":1}}],["juliaexclu",{"2":{"86":1,"106":1}}],["juliaexplore",{"2":{"29":1,"86":2,"124":2}}],["juliaexploresettings",{"2":{"29":1,"86":1,"124":1}}],["juliaextract",{"2":{"6":3,"36":3,"86":3,"124":3}}],["juliaδ",{"2":{"14":1,"86":1,"104":1,"124":1}}],["juliaas",{"2":{"86":2,"102":2}}],["juliaaggregation",{"2":{"86":1,"92":1,"124":1}}],["juliaag",{"2":{"86":2,"91":2}}],["juliaarithmetic",{"2":{"86":1,"95":1,"124":1}}],["juliaar",{"2":{"86":2,"94":2}}],["juliaargs",{"2":{"35":1,"86":1,"124":1}}],["juliaarbitrarydomain",{"2":{"26":1,"86":1}}],["juliaadd",{"2":{"26":1,"86":1,"124":1,"127":2}}],["juliaat",{"2":{"8":1,"86":1}}],["juliaaccept",{"2":{"8":1,"30":1,"86":1,"124":1}}],["juliaautomaton",{"2":{"8":1,"86":1,"124":1}}],["juliaabstractsolver",{"2":{"127":1}}],["juliaabstractoptimizer",{"2":{"86":1,"111":1}}],["juliaabstractdomain",{"2":{"21":1,"86":1,"124":1}}],["juliaabstractautomaton",{"2":{"8":1,"86":1}}],["juliaabstractmultivalueddecisiondiagram",{"2":{"8":1,"86":1}}],["juliacompose",{"2":{"86":2,"124":2}}],["juliacompositionalnetworks",{"2":{"104":2}}],["juliacomposition",{"2":{"86":3,"124":3}}],["juliacomparison",{"2":{"86":1,"100":1,"124":1}}],["juliacode",{"2":{"86":1,"124":1}}],["juliaco",{"2":{"86":9,"98":4,"99":3}}],["juliacontinuousdomain",{"2":{"24":1,"86":1,"124":1}}],["juliaconstriction",{"2":{"127":1}}],["juliaconstraint",{"0":{"62":1,"68":1},"1":{"69":1},"2":{"35":1,"63":1,"69":1,"75":1,"86":1,"124":1,"127":3}}],["juliaconstraintcommons",{"2":{"8":1,"30":1,"86":1}}],["juliaconstraints",{"0":{"18":1,"87":1},"1":{"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"88":1,"89":1},"2":{"5":3,"20":1,"32":1,"33":1,"34":1,"36":4,"86":4,"87":6,"124":4}}],["juliaconst",{"2":{"6":2,"43":1,"86":2,"104":2}}],["juliaconcept",{"2":{"1":7,"3":4,"35":5,"36":3,"38":9,"40":1,"44":1,"46":1,"49":1,"52":2,"54":4,"86":37,"124":3}}],["juliachemical",{"2":{"31":1}}],["juliac",{"2":{"1":3,"3":4,"38":4,"40":1,"45":2,"49":1,"52":2,"54":2,"86":18}}],["julia",{"0":{"0":1,"2":1,"20":1,"32":1,"37":1,"39":1,"48":1,"51":1,"53":1,"71":1,"72":1,"73":1,"74":1,"75":1},"1":{"1":1,"3":1,"33":1,"34":1,"35":1,"36":1,"38":1,"40":1,"49":1,"52":1,"54":1,"72":1,"73":1,"74":1},"2":{"4":2,"8":2,"18":1,"26":1,"29":1,"31":5,"33":2,"34":1,"36":2,"44":3,"72":1,"73":7,"74":5,"86":13,"87":8,"98":1,"104":1,"117":1,"119":1,"124":5,"125":14,"127":81}}],["jl",{"0":{"0":1,"2":1,"4":1,"18":1,"31":1,"32":1,"37":1,"39":1,"48":1,"51":1,"53":1,"101":1,"104":1,"107":1,"120":1,"122":1,"125":1,"127":1},"1":{"1":1,"3":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"33":1,"34":1,"35":1,"36":1,"38":1,"40":1,"49":1,"52":1,"54":1,"102":1,"103":1,"108":1},"2":{"4":1,"5":4,"18":1,"19":3,"20":2,"31":1,"32":1,"33":3,"34":3,"36":1,"42":1,"43":1,"44":1,"73":3,"86":1,"87":8,"101":1,"104":1,"106":1,"107":1,"120":1,"121":2,"122":1,"124":1,"125":1,"127":2}}]],"serializationVersion":2}';export{i as default}; diff --git a/dev/assets/chunks/VPLocalSearchBox.B9WZ723L.js b/dev/assets/chunks/VPLocalSearchBox.B9WZ723L.js deleted file mode 100644 index 1ad37f8..0000000 --- a/dev/assets/chunks/VPLocalSearchBox.B9WZ723L.js +++ /dev/null @@ -1,7 +0,0 @@ -var It=Object.defineProperty;var Dt=(o,e,t)=>e in o?It(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t;var Oe=(o,e,t)=>(Dt(o,typeof e!="symbol"?e+"":e,t),t);import{Y as yt,h as oe,y as $e,al as kt,am as Ot,d as _t,H as xe,an as tt,k as Fe,ao as Rt,ap as Mt,z as Lt,aq as zt,l as _e,U as de,S as Ee,ar as Pt,as as Vt,Z as Bt,j as $t,at as Wt,o as ee,b as Kt,m as k,a2 as Jt,p as j,au as Ut,av as jt,aw as Gt,c as re,n as rt,e as Se,G as at,F as nt,a as ve,t as pe,ax as qt,q as Ht,s as Qt,ay as it,az as Yt,ab as Zt,ah as Xt,aA as er,_ as tr}from"./framework.aA95Gx5L.js";import{u as rr,c as ar}from"./theme.DQqwdnSU.js";const nr={root:()=>yt(()=>import("./@localSearchIndexroot.CHYlrtr2.js"),[])};/*! -* tabbable 6.2.0 -* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE -*/var mt=["input:not([inert])","select:not([inert])","textarea:not([inert])","a[href]:not([inert])","button:not([inert])","[tabindex]:not(slot):not([inert])","audio[controls]:not([inert])","video[controls]:not([inert])",'[contenteditable]:not([contenteditable="false"]):not([inert])',"details>summary:first-of-type:not([inert])","details:not([inert])"],Ne=mt.join(","),gt=typeof Element>"u",ue=gt?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,Ce=!gt&&Element.prototype.getRootNode?function(o){var e;return o==null||(e=o.getRootNode)===null||e===void 0?void 0:e.call(o)}:function(o){return o==null?void 0:o.ownerDocument},Ie=function o(e,t){var r;t===void 0&&(t=!0);var n=e==null||(r=e.getAttribute)===null||r===void 0?void 0:r.call(e,"inert"),a=n===""||n==="true",i=a||t&&e&&o(e.parentNode);return i},ir=function(e){var t,r=e==null||(t=e.getAttribute)===null||t===void 0?void 0:t.call(e,"contenteditable");return r===""||r==="true"},bt=function(e,t,r){if(Ie(e))return[];var n=Array.prototype.slice.apply(e.querySelectorAll(Ne));return t&&ue.call(e,Ne)&&n.unshift(e),n=n.filter(r),n},wt=function o(e,t,r){for(var n=[],a=Array.from(e);a.length;){var i=a.shift();if(!Ie(i,!1))if(i.tagName==="SLOT"){var s=i.assignedElements(),u=s.length?s:i.children,l=o(u,!0,r);r.flatten?n.push.apply(n,l):n.push({scopeParent:i,candidates:l})}else{var h=ue.call(i,Ne);h&&r.filter(i)&&(t||!e.includes(i))&&n.push(i);var d=i.shadowRoot||typeof r.getShadowRoot=="function"&&r.getShadowRoot(i),v=!Ie(d,!1)&&(!r.shadowRootFilter||r.shadowRootFilter(i));if(d&&v){var y=o(d===!0?i.children:d.children,!0,r);r.flatten?n.push.apply(n,y):n.push({scopeParent:i,candidates:y})}else a.unshift.apply(a,i.children)}}return n},xt=function(e){return!isNaN(parseInt(e.getAttribute("tabindex"),10))},se=function(e){if(!e)throw new Error("No node provided");return e.tabIndex<0&&(/^(AUDIO|VIDEO|DETAILS)$/.test(e.tagName)||ir(e))&&!xt(e)?0:e.tabIndex},or=function(e,t){var r=se(e);return r<0&&t&&!xt(e)?0:r},sr=function(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex},Ft=function(e){return e.tagName==="INPUT"},ur=function(e){return Ft(e)&&e.type==="hidden"},lr=function(e){var t=e.tagName==="DETAILS"&&Array.prototype.slice.apply(e.children).some(function(r){return r.tagName==="SUMMARY"});return t},cr=function(e,t){for(var r=0;rsummary:first-of-type"),i=a?e.parentElement:e;if(ue.call(i,"details:not([open]) *"))return!0;if(!r||r==="full"||r==="legacy-full"){if(typeof n=="function"){for(var s=e;e;){var u=e.parentElement,l=Ce(e);if(u&&!u.shadowRoot&&n(u)===!0)return ot(e);e.assignedSlot?e=e.assignedSlot:!u&&l!==e.ownerDocument?e=l.host:e=u}e=s}if(vr(e))return!e.getClientRects().length;if(r!=="legacy-full")return!0}else if(r==="non-zero-area")return ot(e);return!1},yr=function(e){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(e.tagName))for(var t=e.parentElement;t;){if(t.tagName==="FIELDSET"&&t.disabled){for(var r=0;r=0)},gr=function o(e){var t=[],r=[];return e.forEach(function(n,a){var i=!!n.scopeParent,s=i?n.scopeParent:n,u=or(s,i),l=i?o(n.candidates):s;u===0?i?t.push.apply(t,l):t.push(s):r.push({documentOrder:a,tabIndex:u,item:n,isScope:i,content:l})}),r.sort(sr).reduce(function(n,a){return a.isScope?n.push.apply(n,a.content):n.push(a.content),n},[]).concat(t)},br=function(e,t){t=t||{};var r;return t.getShadowRoot?r=wt([e],t.includeContainer,{filter:We.bind(null,t),flatten:!1,getShadowRoot:t.getShadowRoot,shadowRootFilter:mr}):r=bt(e,t.includeContainer,We.bind(null,t)),gr(r)},wr=function(e,t){t=t||{};var r;return t.getShadowRoot?r=wt([e],t.includeContainer,{filter:De.bind(null,t),flatten:!0,getShadowRoot:t.getShadowRoot}):r=bt(e,t.includeContainer,De.bind(null,t)),r},le=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return ue.call(e,Ne)===!1?!1:We(t,e)},xr=mt.concat("iframe").join(","),Re=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return ue.call(e,xr)===!1?!1:De(t,e)};/*! -* focus-trap 7.5.4 -* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE -*/function st(o,e){var t=Object.keys(o);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(o);e&&(r=r.filter(function(n){return Object.getOwnPropertyDescriptor(o,n).enumerable})),t.push.apply(t,r)}return t}function ut(o){for(var e=1;e0){var r=e[e.length-1];r!==t&&r.pause()}var n=e.indexOf(t);n===-1||e.splice(n,1),e.push(t)},deactivateTrap:function(e,t){var r=e.indexOf(t);r!==-1&&e.splice(r,1),e.length>0&&e[e.length-1].unpause()}},Ar=function(e){return e.tagName&&e.tagName.toLowerCase()==="input"&&typeof e.select=="function"},Tr=function(e){return(e==null?void 0:e.key)==="Escape"||(e==null?void 0:e.key)==="Esc"||(e==null?void 0:e.keyCode)===27},ge=function(e){return(e==null?void 0:e.key)==="Tab"||(e==null?void 0:e.keyCode)===9},Nr=function(e){return ge(e)&&!e.shiftKey},Cr=function(e){return ge(e)&&e.shiftKey},ct=function(e){return setTimeout(e,0)},ft=function(e,t){var r=-1;return e.every(function(n,a){return t(n)?(r=a,!1):!0}),r},ye=function(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n1?p-1:0),I=1;I=0)c=r.activeElement;else{var f=i.tabbableGroups[0],p=f&&f.firstTabbableNode;c=p||h("fallbackFocus")}if(!c)throw new Error("Your focus-trap needs to have at least one focusable element");return c},v=function(){if(i.containerGroups=i.containers.map(function(c){var f=br(c,a.tabbableOptions),p=wr(c,a.tabbableOptions),C=f.length>0?f[0]:void 0,I=f.length>0?f[f.length-1]:void 0,M=p.find(function(m){return le(m)}),z=p.slice().reverse().find(function(m){return le(m)}),P=!!f.find(function(m){return se(m)>0});return{container:c,tabbableNodes:f,focusableNodes:p,posTabIndexesFound:P,firstTabbableNode:C,lastTabbableNode:I,firstDomTabbableNode:M,lastDomTabbableNode:z,nextTabbableNode:function(x){var $=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,K=f.indexOf(x);return K<0?$?p.slice(p.indexOf(x)+1).find(function(q){return le(q)}):p.slice(0,p.indexOf(x)).reverse().find(function(q){return le(q)}):f[K+($?1:-1)]}}}),i.tabbableGroups=i.containerGroups.filter(function(c){return c.tabbableNodes.length>0}),i.tabbableGroups.length<=0&&!h("fallbackFocus"))throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");if(i.containerGroups.find(function(c){return c.posTabIndexesFound})&&i.containerGroups.length>1)throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.")},y=function w(c){var f=c.activeElement;if(f)return f.shadowRoot&&f.shadowRoot.activeElement!==null?w(f.shadowRoot):f},b=function w(c){if(c!==!1&&c!==y(document)){if(!c||!c.focus){w(d());return}c.focus({preventScroll:!!a.preventScroll}),i.mostRecentlyFocusedNode=c,Ar(c)&&c.select()}},E=function(c){var f=h("setReturnFocus",c);return f||(f===!1?!1:c)},g=function(c){var f=c.target,p=c.event,C=c.isBackward,I=C===void 0?!1:C;f=f||Ae(p),v();var M=null;if(i.tabbableGroups.length>0){var z=l(f,p),P=z>=0?i.containerGroups[z]:void 0;if(z<0)I?M=i.tabbableGroups[i.tabbableGroups.length-1].lastTabbableNode:M=i.tabbableGroups[0].firstTabbableNode;else if(I){var m=ft(i.tabbableGroups,function(V){var U=V.firstTabbableNode;return f===U});if(m<0&&(P.container===f||Re(f,a.tabbableOptions)&&!le(f,a.tabbableOptions)&&!P.nextTabbableNode(f,!1))&&(m=z),m>=0){var x=m===0?i.tabbableGroups.length-1:m-1,$=i.tabbableGroups[x];M=se(f)>=0?$.lastTabbableNode:$.lastDomTabbableNode}else ge(p)||(M=P.nextTabbableNode(f,!1))}else{var K=ft(i.tabbableGroups,function(V){var U=V.lastTabbableNode;return f===U});if(K<0&&(P.container===f||Re(f,a.tabbableOptions)&&!le(f,a.tabbableOptions)&&!P.nextTabbableNode(f))&&(K=z),K>=0){var q=K===i.tabbableGroups.length-1?0:K+1,H=i.tabbableGroups[q];M=se(f)>=0?H.firstTabbableNode:H.firstDomTabbableNode}else ge(p)||(M=P.nextTabbableNode(f))}}else M=h("fallbackFocus");return M},S=function(c){var f=Ae(c);if(!(l(f,c)>=0)){if(ye(a.clickOutsideDeactivates,c)){s.deactivate({returnFocus:a.returnFocusOnDeactivate});return}ye(a.allowOutsideClick,c)||c.preventDefault()}},T=function(c){var f=Ae(c),p=l(f,c)>=0;if(p||f instanceof Document)p&&(i.mostRecentlyFocusedNode=f);else{c.stopImmediatePropagation();var C,I=!0;if(i.mostRecentlyFocusedNode)if(se(i.mostRecentlyFocusedNode)>0){var M=l(i.mostRecentlyFocusedNode),z=i.containerGroups[M].tabbableNodes;if(z.length>0){var P=z.findIndex(function(m){return m===i.mostRecentlyFocusedNode});P>=0&&(a.isKeyForward(i.recentNavEvent)?P+1=0&&(C=z[P-1],I=!1))}}else i.containerGroups.some(function(m){return m.tabbableNodes.some(function(x){return se(x)>0})})||(I=!1);else I=!1;I&&(C=g({target:i.mostRecentlyFocusedNode,isBackward:a.isKeyBackward(i.recentNavEvent)})),b(C||i.mostRecentlyFocusedNode||d())}i.recentNavEvent=void 0},F=function(c){var f=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;i.recentNavEvent=c;var p=g({event:c,isBackward:f});p&&(ge(c)&&c.preventDefault(),b(p))},L=function(c){if(Tr(c)&&ye(a.escapeDeactivates,c)!==!1){c.preventDefault(),s.deactivate();return}(a.isKeyForward(c)||a.isKeyBackward(c))&&F(c,a.isKeyBackward(c))},R=function(c){var f=Ae(c);l(f,c)>=0||ye(a.clickOutsideDeactivates,c)||ye(a.allowOutsideClick,c)||(c.preventDefault(),c.stopImmediatePropagation())},B=function(){if(i.active)return lt.activateTrap(n,s),i.delayInitialFocusTimer=a.delayInitialFocus?ct(function(){b(d())}):b(d()),r.addEventListener("focusin",T,!0),r.addEventListener("mousedown",S,{capture:!0,passive:!1}),r.addEventListener("touchstart",S,{capture:!0,passive:!1}),r.addEventListener("click",R,{capture:!0,passive:!1}),r.addEventListener("keydown",L,{capture:!0,passive:!1}),s},N=function(){if(i.active)return r.removeEventListener("focusin",T,!0),r.removeEventListener("mousedown",S,!0),r.removeEventListener("touchstart",S,!0),r.removeEventListener("click",R,!0),r.removeEventListener("keydown",L,!0),s},_=function(c){var f=c.some(function(p){var C=Array.from(p.removedNodes);return C.some(function(I){return I===i.mostRecentlyFocusedNode})});f&&b(d())},A=typeof window<"u"&&"MutationObserver"in window?new MutationObserver(_):void 0,O=function(){A&&(A.disconnect(),i.active&&!i.paused&&i.containers.map(function(c){A.observe(c,{subtree:!0,childList:!0})}))};return s={get active(){return i.active},get paused(){return i.paused},activate:function(c){if(i.active)return this;var f=u(c,"onActivate"),p=u(c,"onPostActivate"),C=u(c,"checkCanFocusTrap");C||v(),i.active=!0,i.paused=!1,i.nodeFocusedBeforeActivation=r.activeElement,f==null||f();var I=function(){C&&v(),B(),O(),p==null||p()};return C?(C(i.containers.concat()).then(I,I),this):(I(),this)},deactivate:function(c){if(!i.active)return this;var f=ut({onDeactivate:a.onDeactivate,onPostDeactivate:a.onPostDeactivate,checkCanReturnFocus:a.checkCanReturnFocus},c);clearTimeout(i.delayInitialFocusTimer),i.delayInitialFocusTimer=void 0,N(),i.active=!1,i.paused=!1,O(),lt.deactivateTrap(n,s);var p=u(f,"onDeactivate"),C=u(f,"onPostDeactivate"),I=u(f,"checkCanReturnFocus"),M=u(f,"returnFocus","returnFocusOnDeactivate");p==null||p();var z=function(){ct(function(){M&&b(E(i.nodeFocusedBeforeActivation)),C==null||C()})};return M&&I?(I(E(i.nodeFocusedBeforeActivation)).then(z,z),this):(z(),this)},pause:function(c){if(i.paused||!i.active)return this;var f=u(c,"onPause"),p=u(c,"onPostPause");return i.paused=!0,f==null||f(),N(),O(),p==null||p(),this},unpause:function(c){if(!i.paused||!i.active)return this;var f=u(c,"onUnpause"),p=u(c,"onPostUnpause");return i.paused=!1,f==null||f(),v(),B(),O(),p==null||p(),this},updateContainerElements:function(c){var f=[].concat(c).filter(Boolean);return i.containers=f.map(function(p){return typeof p=="string"?r.querySelector(p):p}),i.active&&v(),O(),this}},s.updateContainerElements(e),s};function kr(o,e={}){let t;const{immediate:r,...n}=e,a=oe(!1),i=oe(!1),s=d=>t&&t.activate(d),u=d=>t&&t.deactivate(d),l=()=>{t&&(t.pause(),i.value=!0)},h=()=>{t&&(t.unpause(),i.value=!1)};return $e(()=>kt(o),d=>{d&&(t=Dr(d,{...n,onActivate(){a.value=!0,e.onActivate&&e.onActivate()},onDeactivate(){a.value=!1,e.onDeactivate&&e.onDeactivate()}}),r&&s())},{flush:"post"}),Ot(()=>u()),{hasFocus:a,isPaused:i,activate:s,deactivate:u,pause:l,unpause:h}}class fe{constructor(e,t=!0,r=[],n=5e3){this.ctx=e,this.iframes=t,this.exclude=r,this.iframesTimeout=n}static matches(e,t){const r=typeof t=="string"?[t]:t,n=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(n){let a=!1;return r.every(i=>n.call(e,i)?(a=!0,!1):!0),a}else return!1}getContexts(){let e,t=[];return typeof this.ctx>"u"||!this.ctx?e=[]:NodeList.prototype.isPrototypeOf(this.ctx)?e=Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?e=this.ctx:typeof this.ctx=="string"?e=Array.prototype.slice.call(document.querySelectorAll(this.ctx)):e=[this.ctx],e.forEach(r=>{const n=t.filter(a=>a.contains(r)).length>0;t.indexOf(r)===-1&&!n&&t.push(r)}),t}getIframeContents(e,t,r=()=>{}){let n;try{const a=e.contentWindow;if(n=a.document,!a||!n)throw new Error("iframe inaccessible")}catch{r()}n&&t(n)}isIframeBlank(e){const t="about:blank",r=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&r!==t&&r}observeIframeLoad(e,t,r){let n=!1,a=null;const i=()=>{if(!n){n=!0,clearTimeout(a);try{this.isIframeBlank(e)||(e.removeEventListener("load",i),this.getIframeContents(e,t,r))}catch{r()}}};e.addEventListener("load",i),a=setTimeout(i,this.iframesTimeout)}onIframeReady(e,t,r){try{e.contentWindow.document.readyState==="complete"?this.isIframeBlank(e)?this.observeIframeLoad(e,t,r):this.getIframeContents(e,t,r):this.observeIframeLoad(e,t,r)}catch{r()}}waitForIframes(e,t){let r=0;this.forEachIframe(e,()=>!0,n=>{r++,this.waitForIframes(n.querySelector("html"),()=>{--r||t()})},n=>{n||t()})}forEachIframe(e,t,r,n=()=>{}){let a=e.querySelectorAll("iframe"),i=a.length,s=0;a=Array.prototype.slice.call(a);const u=()=>{--i<=0&&n(s)};i||u(),a.forEach(l=>{fe.matches(l,this.exclude)?u():this.onIframeReady(l,h=>{t(l)&&(s++,r(h)),u()},u)})}createIterator(e,t,r){return document.createNodeIterator(e,t,r,!1)}createInstanceOnIframe(e){return new fe(e.querySelector("html"),this.iframes)}compareNodeIframe(e,t,r){const n=e.compareDocumentPosition(r),a=Node.DOCUMENT_POSITION_PRECEDING;if(n&a)if(t!==null){const i=t.compareDocumentPosition(r),s=Node.DOCUMENT_POSITION_FOLLOWING;if(i&s)return!0}else return!0;return!1}getIteratorNode(e){const t=e.previousNode();let r;return t===null?r=e.nextNode():r=e.nextNode()&&e.nextNode(),{prevNode:t,node:r}}checkIframeFilter(e,t,r,n){let a=!1,i=!1;return n.forEach((s,u)=>{s.val===r&&(a=u,i=s.handled)}),this.compareNodeIframe(e,t,r)?(a===!1&&!i?n.push({val:r,handled:!0}):a!==!1&&!i&&(n[a].handled=!0),!0):(a===!1&&n.push({val:r,handled:!1}),!1)}handleOpenIframes(e,t,r,n){e.forEach(a=>{a.handled||this.getIframeContents(a.val,i=>{this.createInstanceOnIframe(i).forEachNode(t,r,n)})})}iterateThroughNodes(e,t,r,n,a){const i=this.createIterator(t,e,n);let s=[],u=[],l,h,d=()=>({prevNode:h,node:l}=this.getIteratorNode(i),l);for(;d();)this.iframes&&this.forEachIframe(t,v=>this.checkIframeFilter(l,h,v,s),v=>{this.createInstanceOnIframe(v).forEachNode(e,y=>u.push(y),n)}),u.push(l);u.forEach(v=>{r(v)}),this.iframes&&this.handleOpenIframes(s,e,r,n),a()}forEachNode(e,t,r,n=()=>{}){const a=this.getContexts();let i=a.length;i||n(),a.forEach(s=>{const u=()=>{this.iterateThroughNodes(e,s,t,r,()=>{--i<=0&&n()})};this.iframes?this.waitForIframes(s,u):u()})}}let Or=class{constructor(e){this.ctx=e,this.ie=!1;const t=window.navigator.userAgent;(t.indexOf("MSIE")>-1||t.indexOf("Trident")>-1)&&(this.ie=!0)}set opt(e){this._opt=Object.assign({},{element:"",className:"",exclude:[],iframes:!1,iframesTimeout:5e3,separateWordSearch:!0,diacritics:!0,synonyms:{},accuracy:"partially",acrossElements:!1,caseSensitive:!1,ignoreJoiners:!1,ignoreGroups:0,ignorePunctuation:[],wildcards:"disabled",each:()=>{},noMatch:()=>{},filter:()=>!0,done:()=>{},debug:!1,log:window.console},e)}get opt(){return this._opt}get iterator(){return new fe(this.ctx,this.opt.iframes,this.opt.exclude,this.opt.iframesTimeout)}log(e,t="debug"){const r=this.opt.log;this.opt.debug&&typeof r=="object"&&typeof r[t]=="function"&&r[t](`mark.js: ${e}`)}escapeStr(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}createRegExp(e){return this.opt.wildcards!=="disabled"&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),this.opt.wildcards!=="disabled"&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e),e}createSynonymsRegExp(e){const t=this.opt.synonyms,r=this.opt.caseSensitive?"":"i",n=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(let a in t)if(t.hasOwnProperty(a)){const i=t[a],s=this.opt.wildcards!=="disabled"?this.setupWildcardsRegExp(a):this.escapeStr(a),u=this.opt.wildcards!=="disabled"?this.setupWildcardsRegExp(i):this.escapeStr(i);s!==""&&u!==""&&(e=e.replace(new RegExp(`(${this.escapeStr(s)}|${this.escapeStr(u)})`,`gm${r}`),n+`(${this.processSynomyms(s)}|${this.processSynomyms(u)})`+n))}return e}processSynomyms(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}setupWildcardsRegExp(e){return e=e.replace(/(?:\\)*\?/g,t=>t.charAt(0)==="\\"?"?":""),e.replace(/(?:\\)*\*/g,t=>t.charAt(0)==="\\"?"*":"")}createWildcardsRegExp(e){let t=this.opt.wildcards==="withSpaces";return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}setupIgnoreJoinersRegExp(e){return e.replace(/[^(|)\\]/g,(t,r,n)=>{let a=n.charAt(r+1);return/[(|)\\]/.test(a)||a===""?t:t+"\0"})}createJoinersRegExp(e){let t=[];const r=this.opt.ignorePunctuation;return Array.isArray(r)&&r.length&&t.push(this.escapeStr(r.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join(`[${t.join("")}]*`):e}createDiacriticsRegExp(e){const t=this.opt.caseSensitive?"":"i",r=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"];let n=[];return e.split("").forEach(a=>{r.every(i=>{if(i.indexOf(a)!==-1){if(n.indexOf(i)>-1)return!1;e=e.replace(new RegExp(`[${i}]`,`gm${t}`),`[${i}]`),n.push(i)}return!0})}),e}createMergedBlanksRegExp(e){return e.replace(/[\s]+/gmi,"[\\s]+")}createAccuracyRegExp(e){const t="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿";let r=this.opt.accuracy,n=typeof r=="string"?r:r.value,a=typeof r=="string"?[]:r.limiters,i="";switch(a.forEach(s=>{i+=`|${this.escapeStr(s)}`}),n){case"partially":default:return`()(${e})`;case"complementary":return i="\\s"+(i||this.escapeStr(t)),`()([^${i}]*${e}[^${i}]*)`;case"exactly":return`(^|\\s${i})(${e})(?=$|\\s${i})`}}getSeparatedKeywords(e){let t=[];return e.forEach(r=>{this.opt.separateWordSearch?r.split(" ").forEach(n=>{n.trim()&&t.indexOf(n)===-1&&t.push(n)}):r.trim()&&t.indexOf(r)===-1&&t.push(r)}),{keywords:t.sort((r,n)=>n.length-r.length),length:t.length}}isNumeric(e){return Number(parseFloat(e))==e}checkRanges(e){if(!Array.isArray(e)||Object.prototype.toString.call(e[0])!=="[object Object]")return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];const t=[];let r=0;return e.sort((n,a)=>n.start-a.start).forEach(n=>{let{start:a,end:i,valid:s}=this.callNoMatchOnInvalidRanges(n,r);s&&(n.start=a,n.length=i-a,t.push(n),r=i)}),t}callNoMatchOnInvalidRanges(e,t){let r,n,a=!1;return e&&typeof e.start<"u"?(r=parseInt(e.start,10),n=r+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&n-t>0&&n-r>0?a=!0:(this.log(`Ignoring invalid or overlapping range: ${JSON.stringify(e)}`),this.opt.noMatch(e))):(this.log(`Ignoring invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)),{start:r,end:n,valid:a}}checkWhitespaceRanges(e,t,r){let n,a=!0,i=r.length,s=t-i,u=parseInt(e.start,10)-s;return u=u>i?i:u,n=u+parseInt(e.length,10),n>i&&(n=i,this.log(`End range automatically set to the max value of ${i}`)),u<0||n-u<0||u>i||n>i?(a=!1,this.log(`Invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)):r.substring(u,n).replace(/\s+/g,"")===""&&(a=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:u,end:n,valid:a}}getTextNodes(e){let t="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,n=>{r.push({start:t.length,end:(t+=n.textContent).length,node:n})},n=>this.matchesExclude(n.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT,()=>{e({value:t,nodes:r})})}matchesExclude(e){return fe.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}wrapRangeInTextNode(e,t,r){const n=this.opt.element?this.opt.element:"mark",a=e.splitText(t),i=a.splitText(r-t);let s=document.createElement(n);return s.setAttribute("data-markjs","true"),this.opt.className&&s.setAttribute("class",this.opt.className),s.textContent=a.textContent,a.parentNode.replaceChild(s,a),i}wrapRangeInMappedTextNode(e,t,r,n,a){e.nodes.every((i,s)=>{const u=e.nodes[s+1];if(typeof u>"u"||u.start>t){if(!n(i.node))return!1;const l=t-i.start,h=(r>i.end?i.end:r)-i.start,d=e.value.substr(0,i.start),v=e.value.substr(h+i.start);if(i.node=this.wrapRangeInTextNode(i.node,l,h),e.value=d+v,e.nodes.forEach((y,b)=>{b>=s&&(e.nodes[b].start>0&&b!==s&&(e.nodes[b].start-=h),e.nodes[b].end-=h)}),r-=h,a(i.node.previousSibling,i.start),r>i.end)t=i.end;else return!1}return!0})}wrapMatches(e,t,r,n,a){const i=t===0?0:t+1;this.getTextNodes(s=>{s.nodes.forEach(u=>{u=u.node;let l;for(;(l=e.exec(u.textContent))!==null&&l[i]!=="";){if(!r(l[i],u))continue;let h=l.index;if(i!==0)for(let d=1;d{let u;for(;(u=e.exec(s.value))!==null&&u[i]!=="";){let l=u.index;if(i!==0)for(let d=1;dr(u[i],d),(d,v)=>{e.lastIndex=v,n(d)})}a()})}wrapRangeFromIndex(e,t,r,n){this.getTextNodes(a=>{const i=a.value.length;e.forEach((s,u)=>{let{start:l,end:h,valid:d}=this.checkWhitespaceRanges(s,i,a.value);d&&this.wrapRangeInMappedTextNode(a,l,h,v=>t(v,s,a.value.substring(l,h),u),v=>{r(v,s)})}),n()})}unwrapMatches(e){const t=e.parentNode;let r=document.createDocumentFragment();for(;e.firstChild;)r.appendChild(e.removeChild(e.firstChild));t.replaceChild(r,e),this.ie?this.normalizeTextNode(t):t.normalize()}normalizeTextNode(e){if(e){if(e.nodeType===3)for(;e.nextSibling&&e.nextSibling.nodeType===3;)e.nodeValue+=e.nextSibling.nodeValue,e.parentNode.removeChild(e.nextSibling);else this.normalizeTextNode(e.firstChild);this.normalizeTextNode(e.nextSibling)}}markRegExp(e,t){this.opt=t,this.log(`Searching with expression "${e}"`);let r=0,n="wrapMatches";const a=i=>{r++,this.opt.each(i)};this.opt.acrossElements&&(n="wrapMatchesAcrossElements"),this[n](e,this.opt.ignoreGroups,(i,s)=>this.opt.filter(s,i,r),a,()=>{r===0&&this.opt.noMatch(e),this.opt.done(r)})}mark(e,t){this.opt=t;let r=0,n="wrapMatches";const{keywords:a,length:i}=this.getSeparatedKeywords(typeof e=="string"?[e]:e),s=this.opt.caseSensitive?"":"i",u=l=>{let h=new RegExp(this.createRegExp(l),`gm${s}`),d=0;this.log(`Searching with expression "${h}"`),this[n](h,1,(v,y)=>this.opt.filter(y,l,r,d),v=>{d++,r++,this.opt.each(v)},()=>{d===0&&this.opt.noMatch(l),a[i-1]===l?this.opt.done(r):u(a[a.indexOf(l)+1])})};this.opt.acrossElements&&(n="wrapMatchesAcrossElements"),i===0?this.opt.done(r):u(a[0])}markRanges(e,t){this.opt=t;let r=0,n=this.checkRanges(e);n&&n.length?(this.log("Starting to mark with the following ranges: "+JSON.stringify(n)),this.wrapRangeFromIndex(n,(a,i,s,u)=>this.opt.filter(a,i,s,u),(a,i)=>{r++,this.opt.each(a,i)},()=>{this.opt.done(r)})):this.opt.done(r)}unmark(e){this.opt=e;let t=this.opt.element?this.opt.element:"*";t+="[data-markjs]",this.opt.className&&(t+=`.${this.opt.className}`),this.log(`Removal selector "${t}"`),this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT,r=>{this.unwrapMatches(r)},r=>{const n=fe.matches(r,t),a=this.matchesExclude(r);return!n||a?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},this.opt.done)}};function _r(o){const e=new Or(o);return this.mark=(t,r)=>(e.mark(t,r),this),this.markRegExp=(t,r)=>(e.markRegExp(t,r),this),this.markRanges=(t,r)=>(e.markRanges(t,r),this),this.unmark=t=>(e.unmark(t),this),this}var W=function(){return W=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])&&(l[0]===6||l[0]===2)){t=0;continue}if(l[0]===3&&(!a||l[1]>a[0]&&l[1]=o.length&&(o=void 0),{value:o&&o[r++],done:!o}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function J(o,e){var t=typeof Symbol=="function"&&o[Symbol.iterator];if(!t)return o;var r=t.call(o),n,a=[],i;try{for(;(e===void 0||e-- >0)&&!(n=r.next()).done;)a.push(n.value)}catch(s){i={error:s}}finally{try{n&&!n.done&&(t=r.return)&&t.call(r)}finally{if(i)throw i.error}}return a}var Lr="ENTRIES",Et="KEYS",St="VALUES",G="",Me=function(){function o(e,t){var r=e._tree,n=Array.from(r.keys());this.set=e,this._type=t,this._path=n.length>0?[{node:r,keys:n}]:[]}return o.prototype.next=function(){var e=this.dive();return this.backtrack(),e},o.prototype.dive=function(){if(this._path.length===0)return{done:!0,value:void 0};var e=ce(this._path),t=e.node,r=e.keys;if(ce(r)===G)return{done:!1,value:this.result()};var n=t.get(ce(r));return this._path.push({node:n,keys:Array.from(n.keys())}),this.dive()},o.prototype.backtrack=function(){if(this._path.length!==0){var e=ce(this._path).keys;e.pop(),!(e.length>0)&&(this._path.pop(),this.backtrack())}},o.prototype.key=function(){return this.set._prefix+this._path.map(function(e){var t=e.keys;return ce(t)}).filter(function(e){return e!==G}).join("")},o.prototype.value=function(){return ce(this._path).node.get(G)},o.prototype.result=function(){switch(this._type){case St:return this.value();case Et:return this.key();default:return[this.key(),this.value()]}},o.prototype[Symbol.iterator]=function(){return this},o}(),ce=function(o){return o[o.length-1]},zr=function(o,e,t){var r=new Map;if(e===void 0)return r;for(var n=e.length+1,a=n+t,i=new Uint8Array(a*n).fill(t+1),s=0;st)continue e}At(o.get(y),e,t,r,n,E,i,s+y)}}}catch(f){u={error:f}}finally{try{v&&!v.done&&(l=d.return)&&l.call(d)}finally{if(u)throw u.error}}},Le=function(){function o(e,t){e===void 0&&(e=new Map),t===void 0&&(t=""),this._size=void 0,this._tree=e,this._prefix=t}return o.prototype.atPrefix=function(e){var t,r;if(!e.startsWith(this._prefix))throw new Error("Mismatched prefix");var n=J(ke(this._tree,e.slice(this._prefix.length)),2),a=n[0],i=n[1];if(a===void 0){var s=J(je(i),2),u=s[0],l=s[1];try{for(var h=D(u.keys()),d=h.next();!d.done;d=h.next()){var v=d.value;if(v!==G&&v.startsWith(l)){var y=new Map;return y.set(v.slice(l.length),u.get(v)),new o(y,e)}}}catch(b){t={error:b}}finally{try{d&&!d.done&&(r=h.return)&&r.call(h)}finally{if(t)throw t.error}}}return new o(a,e)},o.prototype.clear=function(){this._size=void 0,this._tree.clear()},o.prototype.delete=function(e){return this._size=void 0,Pr(this._tree,e)},o.prototype.entries=function(){return new Me(this,Lr)},o.prototype.forEach=function(e){var t,r;try{for(var n=D(this),a=n.next();!a.done;a=n.next()){var i=J(a.value,2),s=i[0],u=i[1];e(s,u,this)}}catch(l){t={error:l}}finally{try{a&&!a.done&&(r=n.return)&&r.call(n)}finally{if(t)throw t.error}}},o.prototype.fuzzyGet=function(e,t){return zr(this._tree,e,t)},o.prototype.get=function(e){var t=Ke(this._tree,e);return t!==void 0?t.get(G):void 0},o.prototype.has=function(e){var t=Ke(this._tree,e);return t!==void 0&&t.has(G)},o.prototype.keys=function(){return new Me(this,Et)},o.prototype.set=function(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;var r=ze(this._tree,e);return r.set(G,t),this},Object.defineProperty(o.prototype,"size",{get:function(){if(this._size)return this._size;this._size=0;for(var e=this.entries();!e.next().done;)this._size+=1;return this._size},enumerable:!1,configurable:!0}),o.prototype.update=function(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;var r=ze(this._tree,e);return r.set(G,t(r.get(G))),this},o.prototype.fetch=function(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;var r=ze(this._tree,e),n=r.get(G);return n===void 0&&r.set(G,n=t()),n},o.prototype.values=function(){return new Me(this,St)},o.prototype[Symbol.iterator]=function(){return this.entries()},o.from=function(e){var t,r,n=new o;try{for(var a=D(e),i=a.next();!i.done;i=a.next()){var s=J(i.value,2),u=s[0],l=s[1];n.set(u,l)}}catch(h){t={error:h}}finally{try{i&&!i.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}return n},o.fromObject=function(e){return o.from(Object.entries(e))},o}(),ke=function(o,e,t){var r,n;if(t===void 0&&(t=[]),e.length===0||o==null)return[o,t];try{for(var a=D(o.keys()),i=a.next();!i.done;i=a.next()){var s=i.value;if(s!==G&&e.startsWith(s))return t.push([o,s]),ke(o.get(s),e.slice(s.length),t)}}catch(u){r={error:u}}finally{try{i&&!i.done&&(n=a.return)&&n.call(a)}finally{if(r)throw r.error}}return t.push([o,e]),ke(void 0,"",t)},Ke=function(o,e){var t,r;if(e.length===0||o==null)return o;try{for(var n=D(o.keys()),a=n.next();!a.done;a=n.next()){var i=a.value;if(i!==G&&e.startsWith(i))return Ke(o.get(i),e.slice(i.length))}}catch(s){t={error:s}}finally{try{a&&!a.done&&(r=n.return)&&r.call(n)}finally{if(t)throw t.error}}},ze=function(o,e){var t,r,n=e.length;e:for(var a=0;o&&a0)throw new Error("Expected documents to be present. Omit the argument to remove all documents.");this._index=new Le,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldLength=new Map,this._avgFieldLength=[],this._storedFields=new Map,this._nextId=0}},o.prototype.discard=function(e){var t=this,r=this._idToShortId.get(e);if(r==null)throw new Error("MiniSearch: cannot discard document with ID ".concat(e,": it is not in the index"));this._idToShortId.delete(e),this._documentIds.delete(r),this._storedFields.delete(r),(this._fieldLength.get(r)||[]).forEach(function(n,a){t.removeFieldLength(r,a,t._documentCount,n)}),this._fieldLength.delete(r),this._documentCount-=1,this._dirtCount+=1,this.maybeAutoVacuum()},o.prototype.maybeAutoVacuum=function(){if(this._options.autoVacuum!==!1){var e=this._options.autoVacuum,t=e.minDirtFactor,r=e.minDirtCount,n=e.batchSize,a=e.batchWait;this.conditionalVacuum({batchSize:n,batchWait:a},{minDirtCount:r,minDirtFactor:t})}},o.prototype.discardAll=function(e){var t,r,n=this._options.autoVacuum;try{this._options.autoVacuum=!1;try{for(var a=D(e),i=a.next();!i.done;i=a.next()){var s=i.value;this.discard(s)}}catch(u){t={error:u}}finally{try{i&&!i.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}}finally{this._options.autoVacuum=n}this.maybeAutoVacuum()},o.prototype.replace=function(e){var t=this._options,r=t.idField,n=t.extractField,a=n(e,r);this.discard(a),this.add(e)},o.prototype.vacuum=function(e){return e===void 0&&(e={}),this.conditionalVacuum(e)},o.prototype.conditionalVacuum=function(e,t){var r=this;return this._currentVacuum?(this._enqueuedVacuumConditions=this._enqueuedVacuumConditions&&t,this._enqueuedVacuum!=null?this._enqueuedVacuum:(this._enqueuedVacuum=this._currentVacuum.then(function(){var n=r._enqueuedVacuumConditions;return r._enqueuedVacuumConditions=Ue,r.performVacuuming(e,n)}),this._enqueuedVacuum)):this.vacuumConditionsMet(t)===!1?Promise.resolve():(this._currentVacuum=this.performVacuuming(e),this._currentVacuum)},o.prototype.performVacuuming=function(e,t){return Rr(this,void 0,void 0,function(){var r,n,a,i,s,u,l,h,d,v,y,b,E,g,S,T,F,L,R,B,N,_,A,O,w;return Mr(this,function(c){switch(c.label){case 0:if(r=this._dirtCount,!this.vacuumConditionsMet(t))return[3,10];n=e.batchSize||Je.batchSize,a=e.batchWait||Je.batchWait,i=1,c.label=1;case 1:c.trys.push([1,7,8,9]),s=D(this._index),u=s.next(),c.label=2;case 2:if(u.done)return[3,6];l=J(u.value,2),h=l[0],d=l[1];try{for(v=(_=void 0,D(d)),y=v.next();!y.done;y=v.next()){b=J(y.value,2),E=b[0],g=b[1];try{for(S=(O=void 0,D(g)),T=S.next();!T.done;T=S.next())F=J(T.value,1),L=F[0],!this._documentIds.has(L)&&(g.size<=1?d.delete(E):g.delete(L))}catch(f){O={error:f}}finally{try{T&&!T.done&&(w=S.return)&&w.call(S)}finally{if(O)throw O.error}}}}catch(f){_={error:f}}finally{try{y&&!y.done&&(A=v.return)&&A.call(v)}finally{if(_)throw _.error}}return this._index.get(h).size===0&&this._index.delete(h),i%n!==0?[3,4]:[4,new Promise(function(f){return setTimeout(f,a)})];case 3:c.sent(),c.label=4;case 4:i+=1,c.label=5;case 5:return u=s.next(),[3,2];case 6:return[3,9];case 7:return R=c.sent(),B={error:R},[3,9];case 8:try{u&&!u.done&&(N=s.return)&&N.call(s)}finally{if(B)throw B.error}return[7];case 9:this._dirtCount-=r,c.label=10;case 10:return[4,null];case 11:return c.sent(),this._currentVacuum=this._enqueuedVacuum,this._enqueuedVacuum=null,[2]}})})},o.prototype.vacuumConditionsMet=function(e){if(e==null)return!0;var t=e.minDirtCount,r=e.minDirtFactor;return t=t||Be.minDirtCount,r=r||Be.minDirtFactor,this.dirtCount>=t&&this.dirtFactor>=r},Object.defineProperty(o.prototype,"isVacuuming",{get:function(){return this._currentVacuum!=null},enumerable:!1,configurable:!0}),Object.defineProperty(o.prototype,"dirtCount",{get:function(){return this._dirtCount},enumerable:!1,configurable:!0}),Object.defineProperty(o.prototype,"dirtFactor",{get:function(){return this._dirtCount/(1+this._documentCount+this._dirtCount)},enumerable:!1,configurable:!0}),o.prototype.has=function(e){return this._idToShortId.has(e)},o.prototype.getStoredFields=function(e){var t=this._idToShortId.get(e);if(t!=null)return this._storedFields.get(t)},o.prototype.search=function(e,t){var r,n;t===void 0&&(t={});var a=this.executeQuery(e,t),i=[];try{for(var s=D(a),u=s.next();!u.done;u=s.next()){var l=J(u.value,2),h=l[0],d=l[1],v=d.score,y=d.terms,b=d.match,E=y.length||1,g={id:this._documentIds.get(h),score:v*E,terms:Object.keys(b),queryTerms:y,match:b};Object.assign(g,this._storedFields.get(h)),(t.filter==null||t.filter(g))&&i.push(g)}}catch(S){r={error:S}}finally{try{u&&!u.done&&(n=s.return)&&n.call(s)}finally{if(r)throw r.error}}return e===o.wildcard&&t.boostDocument==null&&this._options.searchOptions.boostDocument==null||i.sort(vt),i},o.prototype.autoSuggest=function(e,t){var r,n,a,i;t===void 0&&(t={}),t=W(W({},this._options.autoSuggestOptions),t);var s=new Map;try{for(var u=D(this.search(e,t)),l=u.next();!l.done;l=u.next()){var h=l.value,d=h.score,v=h.terms,y=v.join(" "),b=s.get(y);b!=null?(b.score+=d,b.count+=1):s.set(y,{score:d,terms:v,count:1})}}catch(R){r={error:R}}finally{try{l&&!l.done&&(n=u.return)&&n.call(u)}finally{if(r)throw r.error}}var E=[];try{for(var g=D(s),S=g.next();!S.done;S=g.next()){var T=J(S.value,2),b=T[0],F=T[1],d=F.score,v=F.terms,L=F.count;E.push({suggestion:b,terms:v,score:d/L})}}catch(R){a={error:R}}finally{try{S&&!S.done&&(i=g.return)&&i.call(g)}finally{if(a)throw a.error}}return E.sort(vt),E},Object.defineProperty(o.prototype,"documentCount",{get:function(){return this._documentCount},enumerable:!1,configurable:!0}),Object.defineProperty(o.prototype,"termCount",{get:function(){return this._index.size},enumerable:!1,configurable:!0}),o.loadJSON=function(e,t){if(t==null)throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");return this.loadJS(JSON.parse(e),t)},o.getDefault=function(e){if(Ve.hasOwnProperty(e))return Pe(Ve,e);throw new Error('MiniSearch: unknown option "'.concat(e,'"'))},o.loadJS=function(e,t){var r,n,a,i,s,u,l=e.index,h=e.documentCount,d=e.nextId,v=e.documentIds,y=e.fieldIds,b=e.fieldLength,E=e.averageFieldLength,g=e.storedFields,S=e.dirtCount,T=e.serializationVersion;if(T!==1&&T!==2)throw new Error("MiniSearch: cannot deserialize an index created with an incompatible version");var F=new o(t);F._documentCount=h,F._nextId=d,F._documentIds=Te(v),F._idToShortId=new Map,F._fieldIds=y,F._fieldLength=Te(b),F._avgFieldLength=E,F._storedFields=Te(g),F._dirtCount=S||0,F._index=new Le;try{for(var L=D(F._documentIds),R=L.next();!R.done;R=L.next()){var B=J(R.value,2),N=B[0],_=B[1];F._idToShortId.set(_,N)}}catch(P){r={error:P}}finally{try{R&&!R.done&&(n=L.return)&&n.call(L)}finally{if(r)throw r.error}}try{for(var A=D(l),O=A.next();!O.done;O=A.next()){var w=J(O.value,2),c=w[0],f=w[1],p=new Map;try{for(var C=(s=void 0,D(Object.keys(f))),I=C.next();!I.done;I=C.next()){var M=I.value,z=f[M];T===1&&(z=z.ds),p.set(parseInt(M,10),Te(z))}}catch(P){s={error:P}}finally{try{I&&!I.done&&(u=C.return)&&u.call(C)}finally{if(s)throw s.error}}F._index.set(c,p)}}catch(P){a={error:P}}finally{try{O&&!O.done&&(i=A.return)&&i.call(A)}finally{if(a)throw a.error}}return F},o.prototype.executeQuery=function(e,t){var r=this;if(t===void 0&&(t={}),e===o.wildcard)return this.executeWildcardQuery(t);if(typeof e!="string"){var n=W(W(W({},t),e),{queries:void 0}),a=e.queries.map(function(g){return r.executeQuery(g,n)});return this.combineResults(a,n.combineWith)}var i=this._options,s=i.tokenize,u=i.processTerm,l=i.searchOptions,h=W(W({tokenize:s,processTerm:u},l),t),d=h.tokenize,v=h.processTerm,y=d(e).flatMap(function(g){return v(g)}).filter(function(g){return!!g}),b=y.map(Jr(h)),E=b.map(function(g){return r.executeQuerySpec(g,h)});return this.combineResults(E,h.combineWith)},o.prototype.executeQuerySpec=function(e,t){var r,n,a,i,s=W(W({},this._options.searchOptions),t),u=(s.fields||this._options.fields).reduce(function(M,z){var P;return W(W({},M),(P={},P[z]=Pe(s.boost,z)||1,P))},{}),l=s.boostDocument,h=s.weights,d=s.maxFuzzy,v=s.bm25,y=W(W({},ht.weights),h),b=y.fuzzy,E=y.prefix,g=this._index.get(e.term),S=this.termResults(e.term,e.term,1,g,u,l,v),T,F;if(e.prefix&&(T=this._index.atPrefix(e.term)),e.fuzzy){var L=e.fuzzy===!0?.2:e.fuzzy,R=L<1?Math.min(d,Math.round(e.term.length*L)):L;R&&(F=this._index.fuzzyGet(e.term,R))}if(T)try{for(var B=D(T),N=B.next();!N.done;N=B.next()){var _=J(N.value,2),A=_[0],O=_[1],w=A.length-e.term.length;if(w){F==null||F.delete(A);var c=E*A.length/(A.length+.3*w);this.termResults(e.term,A,c,O,u,l,v,S)}}}catch(M){r={error:M}}finally{try{N&&!N.done&&(n=B.return)&&n.call(B)}finally{if(r)throw r.error}}if(F)try{for(var f=D(F.keys()),p=f.next();!p.done;p=f.next()){var A=p.value,C=J(F.get(A),2),I=C[0],w=C[1];if(w){var c=b*A.length/(A.length+w);this.termResults(e.term,A,c,I,u,l,v,S)}}}catch(M){a={error:M}}finally{try{p&&!p.done&&(i=f.return)&&i.call(f)}finally{if(a)throw a.error}}return S},o.prototype.executeWildcardQuery=function(e){var t,r,n=new Map,a=W(W({},this._options.searchOptions),e);try{for(var i=D(this._documentIds),s=i.next();!s.done;s=i.next()){var u=J(s.value,2),l=u[0],h=u[1],d=a.boostDocument?a.boostDocument(h,"",this._storedFields.get(l)):1;n.set(l,{score:d,terms:[],match:{}})}}catch(v){t={error:v}}finally{try{s&&!s.done&&(r=i.return)&&r.call(i)}finally{if(t)throw t.error}}return n},o.prototype.combineResults=function(e,t){if(t===void 0&&(t=Ge),e.length===0)return new Map;var r=t.toLowerCase();return e.reduce($r[r])||new Map},o.prototype.toJSON=function(){var e,t,r,n,a=[];try{for(var i=D(this._index),s=i.next();!s.done;s=i.next()){var u=J(s.value,2),l=u[0],h=u[1],d={};try{for(var v=(r=void 0,D(h)),y=v.next();!y.done;y=v.next()){var b=J(y.value,2),E=b[0],g=b[1];d[E]=Object.fromEntries(g)}}catch(S){r={error:S}}finally{try{y&&!y.done&&(n=v.return)&&n.call(v)}finally{if(r)throw r.error}}a.push([l,d])}}catch(S){e={error:S}}finally{try{s&&!s.done&&(t=i.return)&&t.call(i)}finally{if(e)throw e.error}}return{documentCount:this._documentCount,nextId:this._nextId,documentIds:Object.fromEntries(this._documentIds),fieldIds:this._fieldIds,fieldLength:Object.fromEntries(this._fieldLength),averageFieldLength:this._avgFieldLength,storedFields:Object.fromEntries(this._storedFields),dirtCount:this._dirtCount,index:a,serializationVersion:2}},o.prototype.termResults=function(e,t,r,n,a,i,s,u){var l,h,d,v,y;if(u===void 0&&(u=new Map),n==null)return u;try{for(var b=D(Object.keys(a)),E=b.next();!E.done;E=b.next()){var g=E.value,S=a[g],T=this._fieldIds[g],F=n.get(T);if(F!=null){var L=F.size,R=this._avgFieldLength[T];try{for(var B=(d=void 0,D(F.keys())),N=B.next();!N.done;N=B.next()){var _=N.value;if(!this._documentIds.has(_)){this.removeTerm(T,_,t),L-=1;continue}var A=i?i(this._documentIds.get(_),t,this._storedFields.get(_)):1;if(A){var O=F.get(_),w=this._fieldLength.get(_)[T],c=Kr(O,L,this._documentCount,w,R,s),f=r*S*A*c,p=u.get(_);if(p){p.score+=f,jr(p.terms,e);var C=Pe(p.match,t);C?C.push(g):p.match[t]=[g]}else u.set(_,{score:f,terms:[e],match:(y={},y[t]=[g],y)})}}}catch(I){d={error:I}}finally{try{N&&!N.done&&(v=B.return)&&v.call(B)}finally{if(d)throw d.error}}}}}catch(I){l={error:I}}finally{try{E&&!E.done&&(h=b.return)&&h.call(b)}finally{if(l)throw l.error}}return u},o.prototype.addTerm=function(e,t,r){var n=this._index.fetch(r,pt),a=n.get(e);if(a==null)a=new Map,a.set(t,1),n.set(e,a);else{var i=a.get(t);a.set(t,(i||0)+1)}},o.prototype.removeTerm=function(e,t,r){if(!this._index.has(r)){this.warnDocumentChanged(t,e,r);return}var n=this._index.fetch(r,pt),a=n.get(e);a==null||a.get(t)==null?this.warnDocumentChanged(t,e,r):a.get(t)<=1?a.size<=1?n.delete(e):a.delete(t):a.set(t,a.get(t)-1),this._index.get(r).size===0&&this._index.delete(r)},o.prototype.warnDocumentChanged=function(e,t,r){var n,a;try{for(var i=D(Object.keys(this._fieldIds)),s=i.next();!s.done;s=i.next()){var u=s.value;if(this._fieldIds[u]===t){this._options.logger("warn","MiniSearch: document with ID ".concat(this._documentIds.get(e),' has changed before removal: term "').concat(r,'" was not present in field "').concat(u,'". Removing a document after it has changed can corrupt the index!'),"version_conflict");return}}}catch(l){n={error:l}}finally{try{s&&!s.done&&(a=i.return)&&a.call(i)}finally{if(n)throw n.error}}},o.prototype.addDocumentId=function(e){var t=this._nextId;return this._idToShortId.set(e,t),this._documentIds.set(t,e),this._documentCount+=1,this._nextId+=1,t},o.prototype.addFields=function(e){for(var t=0;t(Ht("data-v-f5c68218"),o=o(),Qt(),o),Hr=["aria-owns"],Qr={class:"shell"},Yr=["title"],Zr=Y(()=>k("span",{"aria-hidden":"true",class:"vpi-search search-icon local-search-icon"},null,-1)),Xr=[Zr],ea={class:"search-actions before"},ta=["title"],ra=Y(()=>k("span",{class:"vpi-arrow-left local-search-icon"},null,-1)),aa=[ra],na=["placeholder"],ia={class:"search-actions"},oa=["title"],sa=Y(()=>k("span",{class:"vpi-layout-list local-search-icon"},null,-1)),ua=[sa],la=["disabled","title"],ca=Y(()=>k("span",{class:"vpi-delete local-search-icon"},null,-1)),fa=[ca],ha=["id","role","aria-labelledby"],da=["aria-selected"],va=["href","aria-label","onMouseenter","onFocusin"],pa={class:"titles"},ya=Y(()=>k("span",{class:"title-icon"},"#",-1)),ma=["innerHTML"],ga=Y(()=>k("span",{class:"vpi-chevron-right local-search-icon"},null,-1)),ba={class:"title main"},wa=["innerHTML"],xa={key:0,class:"excerpt-wrapper"},Fa={key:0,class:"excerpt",inert:""},Ea=["innerHTML"],Sa=Y(()=>k("div",{class:"excerpt-gradient-bottom"},null,-1)),Aa=Y(()=>k("div",{class:"excerpt-gradient-top"},null,-1)),Ta={key:0,class:"no-results"},Na={class:"search-keyboard-shortcuts"},Ca=["aria-label"],Ia=Y(()=>k("span",{class:"vpi-arrow-up navigate-icon"},null,-1)),Da=[Ia],ka=["aria-label"],Oa=Y(()=>k("span",{class:"vpi-arrow-down navigate-icon"},null,-1)),_a=[Oa],Ra=["aria-label"],Ma=Y(()=>k("span",{class:"vpi-corner-down-left navigate-icon"},null,-1)),La=[Ma],za=["aria-label"],Pa=_t({__name:"VPLocalSearchBox",emits:["close"],setup(o,{emit:e}){var z,P;const t=e,r=xe(),n=xe(),a=xe(nr),i=rr(),{activate:s}=kr(r,{immediate:!0,allowOutsideClick:!0,clickOutsideDeactivates:!0,escapeDeactivates:!0}),{localeIndex:u,theme:l}=i,h=tt(async()=>{var m,x,$,K,q,H,V,U,Z;return it(Br.loadJSON(($=await((x=(m=a.value)[u.value])==null?void 0:x.call(m)))==null?void 0:$.default,{fields:["title","titles","text"],storeFields:["title","titles"],searchOptions:{fuzzy:.2,prefix:!0,boost:{title:4,text:2,titles:1},...((K=l.value.search)==null?void 0:K.provider)==="local"&&((H=(q=l.value.search.options)==null?void 0:q.miniSearch)==null?void 0:H.searchOptions)},...((V=l.value.search)==null?void 0:V.provider)==="local"&&((Z=(U=l.value.search.options)==null?void 0:U.miniSearch)==null?void 0:Z.options)}))}),v=Fe(()=>{var m,x;return((m=l.value.search)==null?void 0:m.provider)==="local"&&((x=l.value.search.options)==null?void 0:x.disableQueryPersistence)===!0}).value?oe(""):Rt("vitepress:local-search-filter",""),y=Mt("vitepress:local-search-detailed-list",((z=l.value.search)==null?void 0:z.provider)==="local"&&((P=l.value.search.options)==null?void 0:P.detailedView)===!0),b=Fe(()=>{var m,x,$;return((m=l.value.search)==null?void 0:m.provider)==="local"&&(((x=l.value.search.options)==null?void 0:x.disableDetailedView)===!0||(($=l.value.search.options)==null?void 0:$.detailedView)===!1)}),E=Fe(()=>{var x,$,K,q,H,V,U;const m=((x=l.value.search)==null?void 0:x.options)??l.value.algolia;return((H=(q=(K=($=m==null?void 0:m.locales)==null?void 0:$[u.value])==null?void 0:K.translations)==null?void 0:q.button)==null?void 0:H.buttonText)||((U=(V=m==null?void 0:m.translations)==null?void 0:V.button)==null?void 0:U.buttonText)||"Search"});Lt(()=>{b.value&&(y.value=!1)});const g=xe([]),S=oe(!1);$e(v,()=>{S.value=!1});const T=tt(async()=>{if(n.value)return it(new _r(n.value))},null),F=new qr(16);zt(()=>[h.value,v.value,y.value],async([m,x,$],K,q)=>{var be,qe,He,Qe;(K==null?void 0:K[0])!==m&&F.clear();let H=!1;if(q(()=>{H=!0}),!m)return;g.value=m.search(x).slice(0,16),S.value=!0;const V=$?await Promise.all(g.value.map(Q=>L(Q.id))):[];if(H)return;for(const{id:Q,mod:ae}of V){const ne=Q.slice(0,Q.indexOf("#"));let te=F.get(ne);if(te)continue;te=new Map,F.set(ne,te);const X=ae.default??ae;if(X!=null&&X.render||X!=null&&X.setup){const ie=Yt(X);ie.config.warnHandler=()=>{},ie.provide(Zt,i),Object.defineProperties(ie.config.globalProperties,{$frontmatter:{get(){return i.frontmatter.value}},$params:{get(){return i.page.value.params}}});const Ye=document.createElement("div");ie.mount(Ye),Ye.querySelectorAll("h1, h2, h3, h4, h5, h6").forEach(he=>{var et;const we=(et=he.querySelector("a"))==null?void 0:et.getAttribute("href"),Ze=(we==null?void 0:we.startsWith("#"))&&we.slice(1);if(!Ze)return;let Xe="";for(;(he=he.nextElementSibling)&&!/^h[1-6]$/i.test(he.tagName);)Xe+=he.outerHTML;te.set(Ze,Xe)}),ie.unmount()}if(H)return}const U=new Set;if(g.value=g.value.map(Q=>{const[ae,ne]=Q.id.split("#"),te=F.get(ae),X=(te==null?void 0:te.get(ne))??"";for(const ie in Q.match)U.add(ie);return{...Q,text:X}}),await de(),H)return;await new Promise(Q=>{var ae;(ae=T.value)==null||ae.unmark({done:()=>{var ne;(ne=T.value)==null||ne.markRegExp(M(U),{done:Q})}})});const Z=((be=r.value)==null?void 0:be.querySelectorAll(".result .excerpt"))??[];for(const Q of Z)(qe=Q.querySelector('mark[data-markjs="true"]'))==null||qe.scrollIntoView({block:"center"});(Qe=(He=n.value)==null?void 0:He.firstElementChild)==null||Qe.scrollIntoView({block:"start"})},{debounce:200,immediate:!0});async function L(m){const x=Xt(m.slice(0,m.indexOf("#")));try{if(!x)throw new Error(`Cannot find file for id: ${m}`);return{id:m,mod:await yt(()=>import(x),[])}}catch($){return console.error($),{id:m,mod:{}}}}const R=oe(),B=Fe(()=>{var m;return((m=v.value)==null?void 0:m.length)<=0});function N(m=!0){var x,$;(x=R.value)==null||x.focus(),m&&(($=R.value)==null||$.select())}_e(()=>{N()});function _(m){m.pointerType==="mouse"&&N()}const A=oe(-1),O=oe(!1);$e(g,m=>{A.value=m.length?0:-1,w()});function w(){de(()=>{const m=document.querySelector(".result.selected");m&&m.scrollIntoView({block:"nearest"})})}Ee("ArrowUp",m=>{m.preventDefault(),A.value--,A.value<0&&(A.value=g.value.length-1),O.value=!0,w()}),Ee("ArrowDown",m=>{m.preventDefault(),A.value++,A.value>=g.value.length&&(A.value=0),O.value=!0,w()});const c=Pt();Ee("Enter",m=>{if(m.isComposing||m.target instanceof HTMLButtonElement&&m.target.type!=="submit")return;const x=g.value[A.value];if(m.target instanceof HTMLInputElement&&!x){m.preventDefault();return}x&&(c.go(x.id),t("close"))}),Ee("Escape",()=>{t("close")});const p=ar({modal:{displayDetails:"Display detailed list",resetButtonTitle:"Reset search",backButtonTitle:"Close search",noResultsText:"No results for",footer:{selectText:"to select",selectKeyAriaLabel:"enter",navigateText:"to navigate",navigateUpKeyAriaLabel:"up arrow",navigateDownKeyAriaLabel:"down arrow",closeText:"to close",closeKeyAriaLabel:"escape"}}});_e(()=>{window.history.pushState(null,"",null)}),Vt("popstate",m=>{m.preventDefault(),t("close")});const C=Bt($t?document.body:null);_e(()=>{de(()=>{C.value=!0,de().then(()=>s())})}),Wt(()=>{C.value=!1});function I(){v.value="",de().then(()=>N(!1))}function M(m){return new RegExp([...m].sort((x,$)=>$.length-x.length).map(x=>`(${er(x)})`).join("|"),"gi")}return(m,x)=>{var $,K,q,H;return ee(),Kt(qt,{to:"body"},[k("div",{ref_key:"el",ref:r,role:"button","aria-owns":($=g.value)!=null&&$.length?"localsearch-list":void 0,"aria-expanded":"true","aria-haspopup":"listbox","aria-labelledby":"localsearch-label",class:"VPLocalSearchBox"},[k("div",{class:"backdrop",onClick:x[0]||(x[0]=V=>m.$emit("close"))}),k("div",Qr,[k("form",{class:"search-bar",onPointerup:x[4]||(x[4]=V=>_(V)),onSubmit:x[5]||(x[5]=Jt(()=>{},["prevent"]))},[k("label",{title:E.value,id:"localsearch-label",for:"localsearch-input"},Xr,8,Yr),k("div",ea,[k("button",{class:"back-button",title:j(p)("modal.backButtonTitle"),onClick:x[1]||(x[1]=V=>m.$emit("close"))},aa,8,ta)]),Ut(k("input",{ref_key:"searchInput",ref:R,"onUpdate:modelValue":x[2]||(x[2]=V=>Gt(v)?v.value=V:null),placeholder:E.value,id:"localsearch-input","aria-labelledby":"localsearch-label",class:"search-input"},null,8,na),[[jt,j(v)]]),k("div",ia,[b.value?Se("",!0):(ee(),re("button",{key:0,class:rt(["toggle-layout-button",{"detailed-list":j(y)}]),type:"button",title:j(p)("modal.displayDetails"),onClick:x[3]||(x[3]=V=>A.value>-1&&(y.value=!j(y)))},ua,10,oa)),k("button",{class:"clear-button",type:"reset",disabled:B.value,title:j(p)("modal.resetButtonTitle"),onClick:I},fa,8,la)])],32),k("ul",{ref_key:"resultsEl",ref:n,id:(K=g.value)!=null&&K.length?"localsearch-list":void 0,role:(q=g.value)!=null&&q.length?"listbox":void 0,"aria-labelledby":(H=g.value)!=null&&H.length?"localsearch-label":void 0,class:"results",onMousemove:x[7]||(x[7]=V=>O.value=!1)},[(ee(!0),re(nt,null,at(g.value,(V,U)=>(ee(),re("li",{key:V.id,role:"option","aria-selected":A.value===U?"true":"false"},[k("a",{href:V.id,class:rt(["result",{selected:A.value===U}]),"aria-label":[...V.titles,V.title].join(" > "),onMouseenter:Z=>!O.value&&(A.value=U),onFocusin:Z=>A.value=U,onClick:x[6]||(x[6]=Z=>m.$emit("close"))},[k("div",null,[k("div",pa,[ya,(ee(!0),re(nt,null,at(V.titles,(Z,be)=>(ee(),re("span",{key:be,class:"title"},[k("span",{class:"text",innerHTML:Z},null,8,ma),ga]))),128)),k("span",ba,[k("span",{class:"text",innerHTML:V.title},null,8,wa)])]),j(y)?(ee(),re("div",xa,[V.text?(ee(),re("div",Fa,[k("div",{class:"vp-doc",innerHTML:V.text},null,8,Ea)])):Se("",!0),Sa,Aa])):Se("",!0)])],42,va)],8,da))),128)),j(v)&&!g.value.length&&S.value?(ee(),re("li",Ta,[ve(pe(j(p)("modal.noResultsText"))+' "',1),k("strong",null,pe(j(v)),1),ve('" ')])):Se("",!0)],40,ha),k("div",Na,[k("span",null,[k("kbd",{"aria-label":j(p)("modal.footer.navigateUpKeyAriaLabel")},Da,8,Ca),k("kbd",{"aria-label":j(p)("modal.footer.navigateDownKeyAriaLabel")},_a,8,ka),ve(" "+pe(j(p)("modal.footer.navigateText")),1)]),k("span",null,[k("kbd",{"aria-label":j(p)("modal.footer.selectKeyAriaLabel")},La,8,Ra),ve(" "+pe(j(p)("modal.footer.selectText")),1)]),k("span",null,[k("kbd",{"aria-label":j(p)("modal.footer.closeKeyAriaLabel")},"esc",8,za),ve(" "+pe(j(p)("modal.footer.closeText")),1)])])])],8,Hr)])}}}),Ja=tr(Pa,[["__scopeId","data-v-f5c68218"]]);export{Ja as default}; diff --git a/dev/assets/chunks/framework.aA95Gx5L.js b/dev/assets/chunks/framework.aA95Gx5L.js deleted file mode 100644 index da43fae..0000000 --- a/dev/assets/chunks/framework.aA95Gx5L.js +++ /dev/null @@ -1,17 +0,0 @@ -/** -* @vue/shared v3.4.21 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function Sr(e,t){const n=new Set(e.split(","));return t?r=>n.has(r.toLowerCase()):r=>n.has(r)}const ee={},_t=[],xe=()=>{},Ti=()=>!1,Wt=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Tr=e=>e.startsWith("onUpdate:"),ce=Object.assign,Ar=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Ai=Object.prototype.hasOwnProperty,Y=(e,t)=>Ai.call(e,t),B=Array.isArray,vt=e=>Rn(e)==="[object Map]",eo=e=>Rn(e)==="[object Set]",q=e=>typeof e=="function",ne=e=>typeof e=="string",At=e=>typeof e=="symbol",Z=e=>e!==null&&typeof e=="object",to=e=>(Z(e)||q(e))&&q(e.then)&&q(e.catch),no=Object.prototype.toString,Rn=e=>no.call(e),Ri=e=>Rn(e).slice(8,-1),ro=e=>Rn(e)==="[object Object]",Rr=e=>ne(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,bt=Sr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ln=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Li=/-(\w)/g,Fe=Ln(e=>e.replace(Li,(t,n)=>n?n.toUpperCase():"")),Oi=/\B([A-Z])/g,ft=Ln(e=>e.replace(Oi,"-$1").toLowerCase()),On=Ln(e=>e.charAt(0).toUpperCase()+e.slice(1)),hn=Ln(e=>e?`on${On(e)}`:""),Ze=(e,t)=>!Object.is(e,t),pn=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},ur=e=>{const t=parseFloat(e);return isNaN(t)?e:t},Ii=e=>{const t=ne(e)?Number(e):NaN;return isNaN(t)?e:t};let rs;const so=()=>rs||(rs=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Lr(e){if(B(e)){const t={};for(let n=0;n{if(n){const r=n.split(Pi);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function Or(e){let t="";if(ne(e))t=e;else if(B(e))for(let n=0;nne(e)?e:e==null?"":B(e)||Z(e)&&(e.toString===no||!q(e.toString))?JSON.stringify(e,io,2):String(e),io=(e,t)=>t&&t.__v_isRef?io(e,t.value):vt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[r,s],o)=>(n[Gn(r,o)+" =>"]=s,n),{})}:eo(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>Gn(n))}:At(t)?Gn(t):Z(t)&&!B(t)&&!ro(t)?String(t):t,Gn=(e,t="")=>{var n;return At(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** -* @vue/reactivity v3.4.21 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let ve;class ji{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=ve,!t&&ve&&(this.index=(ve.scopes||(ve.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=ve;try{return ve=this,t()}finally{ve=n}}}on(){ve=this}off(){ve=this.parent}stop(t){if(this._active){let n,r;for(n=0,r=this.effects.length;n=4))break}this._dirtyLevel===1&&(this._dirtyLevel=0),ht()}return this._dirtyLevel>=4}set dirty(t){this._dirtyLevel=t?4:0}run(){if(this._dirtyLevel=0,!this.active)return this.fn();let t=Ye,n=ct;try{return Ye=!0,ct=this,this._runnings++,ss(this),this.fn()}finally{os(this),this._runnings--,ct=n,Ye=t}}stop(){var t;this.active&&(ss(this),os(this),(t=this.onStop)==null||t.call(this),this.active=!1)}}function Ui(e){return e.value}function ss(e){e._trackId++,e._depsLength=0}function os(e){if(e.deps.length>e._depsLength){for(let t=e._depsLength;t{const n=new Map;return n.cleanup=e,n.computed=t,n},vn=new WeakMap,at=Symbol(""),hr=Symbol("");function ye(e,t,n){if(Ye&&ct){let r=vn.get(e);r||vn.set(e,r=new Map);let s=r.get(n);s||r.set(n,s=ho(()=>r.delete(n))),uo(ct,s)}}function je(e,t,n,r,s,o){const i=vn.get(e);if(!i)return;let l=[];if(t==="clear")l=[...i.values()];else if(n==="length"&&B(e)){const c=Number(r);i.forEach((a,f)=>{(f==="length"||!At(f)&&f>=c)&&l.push(a)})}else switch(n!==void 0&&l.push(i.get(n)),t){case"add":B(e)?Rr(n)&&l.push(i.get("length")):(l.push(i.get(at)),vt(e)&&l.push(i.get(hr)));break;case"delete":B(e)||(l.push(i.get(at)),vt(e)&&l.push(i.get(hr)));break;case"set":vt(e)&&l.push(i.get(at));break}Mr();for(const c of l)c&&fo(c,4);Pr()}function Bi(e,t){var n;return(n=vn.get(e))==null?void 0:n.get(t)}const ki=Sr("__proto__,__v_isRef,__isVue"),po=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(At)),is=Ki();function Ki(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const r=J(this);for(let o=0,i=this.length;o{e[t]=function(...n){dt(),Mr();const r=J(this)[t].apply(this,n);return Pr(),ht(),r}}),e}function Wi(e){const t=J(this);return ye(t,"has",e),t.hasOwnProperty(e)}class go{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,r){const s=this._isReadonly,o=this._isShallow;if(n==="__v_isReactive")return!s;if(n==="__v_isReadonly")return s;if(n==="__v_isShallow")return o;if(n==="__v_raw")return r===(s?o?sl:vo:o?_o:yo).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(r)?t:void 0;const i=B(t);if(!s){if(i&&Y(is,n))return Reflect.get(is,n,r);if(n==="hasOwnProperty")return Wi}const l=Reflect.get(t,n,r);return(At(n)?po.has(n):ki(n))||(s||ye(t,"get",n),o)?l:de(l)?i&&Rr(n)?l:l.value:Z(l)?s?Pn(l):Mn(l):l}}class mo extends go{constructor(t=!1){super(!1,t)}set(t,n,r,s){let o=t[n];if(!this._isShallow){const c=St(o);if(!bn(r)&&!St(r)&&(o=J(o),r=J(r)),!B(t)&&de(o)&&!de(r))return c?!1:(o.value=r,!0)}const i=B(t)&&Rr(n)?Number(n)e,In=e=>Reflect.getPrototypeOf(e);function Qt(e,t,n=!1,r=!1){e=e.__v_raw;const s=J(e),o=J(t);n||(Ze(t,o)&&ye(s,"get",t),ye(s,"get",o));const{has:i}=In(s),l=r?Nr:n?Hr:Dt;if(i.call(s,t))return l(e.get(t));if(i.call(s,o))return l(e.get(o));e!==s&&e.get(t)}function Zt(e,t=!1){const n=this.__v_raw,r=J(n),s=J(e);return t||(Ze(e,s)&&ye(r,"has",e),ye(r,"has",s)),e===s?n.has(e):n.has(e)||n.has(s)}function en(e,t=!1){return e=e.__v_raw,!t&&ye(J(e),"iterate",at),Reflect.get(e,"size",e)}function ls(e){e=J(e);const t=J(this);return In(t).has.call(t,e)||(t.add(e),je(t,"add",e,e)),this}function cs(e,t){t=J(t);const n=J(this),{has:r,get:s}=In(n);let o=r.call(n,e);o||(e=J(e),o=r.call(n,e));const i=s.call(n,e);return n.set(e,t),o?Ze(t,i)&&je(n,"set",e,t):je(n,"add",e,t),this}function as(e){const t=J(this),{has:n,get:r}=In(t);let s=n.call(t,e);s||(e=J(e),s=n.call(t,e)),r&&r.call(t,e);const o=t.delete(e);return s&&je(t,"delete",e,void 0),o}function us(){const e=J(this),t=e.size!==0,n=e.clear();return t&&je(e,"clear",void 0,void 0),n}function tn(e,t){return function(r,s){const o=this,i=o.__v_raw,l=J(i),c=t?Nr:e?Hr:Dt;return!e&&ye(l,"iterate",at),i.forEach((a,f)=>r.call(s,c(a),c(f),o))}}function nn(e,t,n){return function(...r){const s=this.__v_raw,o=J(s),i=vt(o),l=e==="entries"||e===Symbol.iterator&&i,c=e==="keys"&&i,a=s[e](...r),f=n?Nr:t?Hr:Dt;return!t&&ye(o,"iterate",c?hr:at),{next(){const{value:h,done:p}=a.next();return p?{value:h,done:p}:{value:l?[f(h[0]),f(h[1])]:f(h),done:p}},[Symbol.iterator](){return this}}}}function Be(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Yi(){const e={get(o){return Qt(this,o)},get size(){return en(this)},has:Zt,add:ls,set:cs,delete:as,clear:us,forEach:tn(!1,!1)},t={get(o){return Qt(this,o,!1,!0)},get size(){return en(this)},has:Zt,add:ls,set:cs,delete:as,clear:us,forEach:tn(!1,!0)},n={get(o){return Qt(this,o,!0)},get size(){return en(this,!0)},has(o){return Zt.call(this,o,!0)},add:Be("add"),set:Be("set"),delete:Be("delete"),clear:Be("clear"),forEach:tn(!0,!1)},r={get(o){return Qt(this,o,!0,!0)},get size(){return en(this,!0)},has(o){return Zt.call(this,o,!0)},add:Be("add"),set:Be("set"),delete:Be("delete"),clear:Be("clear"),forEach:tn(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=nn(o,!1,!1),n[o]=nn(o,!0,!1),t[o]=nn(o,!1,!0),r[o]=nn(o,!0,!0)}),[e,n,t,r]}const[Ji,Qi,Zi,el]=Yi();function Fr(e,t){const n=t?e?el:Zi:e?Qi:Ji;return(r,s,o)=>s==="__v_isReactive"?!e:s==="__v_isReadonly"?e:s==="__v_raw"?r:Reflect.get(Y(n,s)&&s in r?n:r,s,o)}const tl={get:Fr(!1,!1)},nl={get:Fr(!1,!0)},rl={get:Fr(!0,!1)},yo=new WeakMap,_o=new WeakMap,vo=new WeakMap,sl=new WeakMap;function ol(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function il(e){return e.__v_skip||!Object.isExtensible(e)?0:ol(Ri(e))}function Mn(e){return St(e)?e:$r(e,!1,Gi,tl,yo)}function ll(e){return $r(e,!1,Xi,nl,_o)}function Pn(e){return $r(e,!0,zi,rl,vo)}function $r(e,t,n,r,s){if(!Z(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const o=s.get(e);if(o)return o;const i=il(e);if(i===0)return e;const l=new Proxy(e,i===2?r:n);return s.set(e,l),l}function wt(e){return St(e)?wt(e.__v_raw):!!(e&&e.__v_isReactive)}function St(e){return!!(e&&e.__v_isReadonly)}function bn(e){return!!(e&&e.__v_isShallow)}function bo(e){return wt(e)||St(e)}function J(e){const t=e&&e.__v_raw;return t?J(t):e}function Mt(e){return Object.isExtensible(e)&&_n(e,"__v_skip",!0),e}const Dt=e=>Z(e)?Mn(e):e,Hr=e=>Z(e)?Pn(e):e;class wo{constructor(t,n,r,s){this.getter=t,this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this.effect=new Ir(()=>t(this._value),()=>Pt(this,this.effect._dirtyLevel===2?2:3)),this.effect.computed=this,this.effect.active=this._cacheable=!s,this.__v_isReadonly=r}get value(){const t=J(this);return(!t._cacheable||t.effect.dirty)&&Ze(t._value,t._value=t.effect.run())&&Pt(t,4),jr(t),t.effect._dirtyLevel>=2&&Pt(t,2),t._value}set value(t){this._setter(t)}get _dirty(){return this.effect.dirty}set _dirty(t){this.effect.dirty=t}}function cl(e,t,n=!1){let r,s;const o=q(e);return o?(r=e,s=xe):(r=e.get,s=e.set),new wo(r,s,o||!s,n)}function jr(e){var t;Ye&&ct&&(e=J(e),uo(ct,(t=e.dep)!=null?t:e.dep=ho(()=>e.dep=void 0,e instanceof wo?e:void 0)))}function Pt(e,t=4,n){e=J(e);const r=e.dep;r&&fo(r,t)}function de(e){return!!(e&&e.__v_isRef===!0)}function se(e){return Eo(e,!1)}function Vr(e){return Eo(e,!0)}function Eo(e,t){return de(e)?e:new al(e,t)}class al{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:J(t),this._value=n?t:Dt(t)}get value(){return jr(this),this._value}set value(t){const n=this.__v_isShallow||bn(t)||St(t);t=n?t:J(t),Ze(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:Dt(t),Pt(this,4))}}function Co(e){return de(e)?e.value:e}const ul={get:(e,t,n)=>Co(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const s=e[t];return de(s)&&!de(n)?(s.value=n,!0):Reflect.set(e,t,n,r)}};function xo(e){return wt(e)?e:new Proxy(e,ul)}class fl{constructor(t){this.dep=void 0,this.__v_isRef=!0;const{get:n,set:r}=t(()=>jr(this),()=>Pt(this));this._get=n,this._set=r}get value(){return this._get()}set value(t){this._set(t)}}function dl(e){return new fl(e)}class hl{constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return Bi(J(this._object),this._key)}}class pl{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function gl(e,t,n){return de(e)?e:q(e)?new pl(e):Z(e)&&arguments.length>1?ml(e,t,n):se(e)}function ml(e,t,n){const r=e[t];return de(r)?r:new hl(e,t,n)}/** -* @vue/runtime-core v3.4.21 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function Je(e,t,n,r){try{return r?e(...r):e()}catch(s){qt(s,t,n)}}function Se(e,t,n,r){if(q(e)){const o=Je(e,t,n,r);return o&&to(o)&&o.catch(i=>{qt(i,t,n)}),o}const s=[];for(let o=0;o>>1,s=he[r],o=Bt(s);oPe&&he.splice(t,1)}function bl(e){B(e)?Et.push(...e):(!qe||!qe.includes(e,e.allowRecurse?ot+1:ot))&&Et.push(e),To()}function fs(e,t,n=Ut?Pe+1:0){for(;nBt(n)-Bt(r));if(Et.length=0,qe){qe.push(...t);return}for(qe=t,ot=0;ote.id==null?1/0:e.id,wl=(e,t)=>{const n=Bt(e)-Bt(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function Ao(e){pr=!1,Ut=!0,he.sort(wl);try{for(Pe=0;Pene(y)?y.trim():y)),h&&(s=n.map(ur))}let l,c=r[l=hn(t)]||r[l=hn(Fe(t))];!c&&o&&(c=r[l=hn(ft(t))]),c&&Se(c,e,6,s);const a=r[l+"Once"];if(a){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Se(a,e,6,s)}}function Ro(e,t,n=!1){const r=t.emitsCache,s=r.get(e);if(s!==void 0)return s;const o=e.emits;let i={},l=!1;if(!q(e)){const c=a=>{const f=Ro(a,t,!0);f&&(l=!0,ce(i,f))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!o&&!l?(Z(e)&&r.set(e,null),null):(B(o)?o.forEach(c=>i[c]=null):ce(i,o),Z(e)&&r.set(e,i),i)}function $n(e,t){return!e||!Wt(t)?!1:(t=t.slice(2).replace(/Once$/,""),Y(e,t[0].toLowerCase()+t.slice(1))||Y(e,ft(t))||Y(e,t))}let le=null,Hn=null;function En(e){const t=le;return le=e,Hn=e&&e.type.__scopeId||null,t}function Za(e){Hn=e}function eu(){Hn=null}function Cl(e,t=le,n){if(!t||e._n)return e;const r=(...s)=>{r._d&&Ss(-1);const o=En(t);let i;try{i=e(...s)}finally{En(o),r._d&&Ss(1)}return i};return r._n=!0,r._c=!0,r._d=!0,r}function zn(e){const{type:t,vnode:n,proxy:r,withProxy:s,props:o,propsOptions:[i],slots:l,attrs:c,emit:a,render:f,renderCache:h,data:p,setupState:y,ctx:v,inheritAttrs:I}=e;let N,K;const k=En(e);try{if(n.shapeFlag&4){const _=s||r,M=_;N=Re(f.call(M,_,h,o,y,p,v)),K=c}else{const _=t;N=Re(_.length>1?_(o,{attrs:c,slots:l,emit:a}):_(o,null)),K=t.props?c:xl(c)}}catch(_){jt.length=0,qt(_,e,1),N=oe(be)}let g=N;if(K&&I!==!1){const _=Object.keys(K),{shapeFlag:M}=g;_.length&&M&7&&(i&&_.some(Tr)&&(K=Sl(K,i)),g=et(g,K))}return n.dirs&&(g=et(g),g.dirs=g.dirs?g.dirs.concat(n.dirs):n.dirs),n.transition&&(g.transition=n.transition),N=g,En(k),N}const xl=e=>{let t;for(const n in e)(n==="class"||n==="style"||Wt(n))&&((t||(t={}))[n]=e[n]);return t},Sl=(e,t)=>{const n={};for(const r in e)(!Tr(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function Tl(e,t,n){const{props:r,children:s,component:o}=e,{props:i,children:l,patchFlag:c}=t,a=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return r?ds(r,i,a):!!i;if(c&8){const f=t.dynamicProps;for(let h=0;he.__isSuspense;function Io(e,t){t&&t.pendingBranch?B(e)?t.effects.push(...e):t.effects.push(e):bl(e)}const Ll=Symbol.for("v-scx"),Ol=()=>xt(Ll);function Br(e,t){return jn(e,null,t)}function ru(e,t){return jn(e,null,{flush:"post"})}const rn={};function Ve(e,t,n){return jn(e,t,n)}function jn(e,t,{immediate:n,deep:r,flush:s,once:o,onTrack:i,onTrigger:l}=ee){if(t&&o){const L=t;t=(...F)=>{L(...F),M()}}const c=ue,a=L=>r===!0?L:lt(L,r===!1?1:void 0);let f,h=!1,p=!1;if(de(e)?(f=()=>e.value,h=bn(e)):wt(e)?(f=()=>a(e),h=!0):B(e)?(p=!0,h=e.some(L=>wt(L)||bn(L)),f=()=>e.map(L=>{if(de(L))return L.value;if(wt(L))return a(L);if(q(L))return Je(L,c,2)})):q(e)?t?f=()=>Je(e,c,2):f=()=>(y&&y(),Se(e,c,3,[v])):f=xe,t&&r){const L=f;f=()=>lt(L())}let y,v=L=>{y=g.onStop=()=>{Je(L,c,4),y=g.onStop=void 0}},I;if(Xt)if(v=xe,t?n&&Se(t,c,3,[f(),p?[]:void 0,v]):f(),s==="sync"){const L=Ol();I=L.__watcherHandles||(L.__watcherHandles=[])}else return xe;let N=p?new Array(e.length).fill(rn):rn;const K=()=>{if(!(!g.active||!g.dirty))if(t){const L=g.run();(r||h||(p?L.some((F,T)=>Ze(F,N[T])):Ze(L,N)))&&(y&&y(),Se(t,c,3,[L,N===rn?void 0:p&&N[0]===rn?[]:N,v]),N=L)}else g.run()};K.allowRecurse=!!t;let k;s==="sync"?k=K:s==="post"?k=()=>ge(K,c&&c.suspense):(K.pre=!0,c&&(K.id=c.uid),k=()=>Fn(K));const g=new Ir(f,xe,k),_=lo(),M=()=>{g.stop(),_&&Ar(_.effects,g)};return t?n?K():N=g.run():s==="post"?ge(g.run.bind(g),c&&c.suspense):g.run(),I&&I.push(M),M}function Il(e,t,n){const r=this.proxy,s=ne(e)?e.includes(".")?Mo(r,e):()=>r[e]:e.bind(r,r);let o;q(t)?o=t:(o=t.handler,n=t);const i=zt(this),l=jn(s,o.bind(r),n);return i(),l}function Mo(e,t){const n=t.split(".");return()=>{let r=e;for(let s=0;s0){if(n>=t)return e;n++}if(r=r||new Set,r.has(e))return e;if(r.add(e),de(e))lt(e.value,t,n,r);else if(B(e))for(let s=0;s{lt(s,t,n,r)});else if(ro(e))for(const s in e)lt(e[s],t,n,r);return e}function su(e,t){if(le===null)return e;const n=kn(le)||le.proxy,r=e.dirs||(e.dirs=[]);for(let s=0;s{e.isMounted=!0}),Ho(()=>{e.isUnmounting=!0}),e}const we=[Function,Array],Po={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:we,onEnter:we,onAfterEnter:we,onEnterCancelled:we,onBeforeLeave:we,onLeave:we,onAfterLeave:we,onLeaveCancelled:we,onBeforeAppear:we,onAppear:we,onAfterAppear:we,onAppearCancelled:we},Pl={name:"BaseTransition",props:Po,setup(e,{slots:t}){const n=Bn(),r=Ml();return()=>{const s=t.default&&Fo(t.default(),!0);if(!s||!s.length)return;let o=s[0];if(s.length>1){for(const p of s)if(p.type!==be){o=p;break}}const i=J(e),{mode:l}=i;if(r.isLeaving)return Xn(o);const c=ps(o);if(!c)return Xn(o);const a=gr(c,i,r,n);mr(c,a);const f=n.subTree,h=f&&ps(f);if(h&&h.type!==be&&!it(c,h)){const p=gr(h,i,r,n);if(mr(h,p),l==="out-in")return r.isLeaving=!0,p.afterLeave=()=>{r.isLeaving=!1,n.update.active!==!1&&(n.effect.dirty=!0,n.update())},Xn(o);l==="in-out"&&c.type!==be&&(p.delayLeave=(y,v,I)=>{const N=No(r,h);N[String(h.key)]=h,y[Ge]=()=>{v(),y[Ge]=void 0,delete a.delayedLeave},a.delayedLeave=I})}return o}}},Nl=Pl;function No(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function gr(e,t,n,r){const{appear:s,mode:o,persisted:i=!1,onBeforeEnter:l,onEnter:c,onAfterEnter:a,onEnterCancelled:f,onBeforeLeave:h,onLeave:p,onAfterLeave:y,onLeaveCancelled:v,onBeforeAppear:I,onAppear:N,onAfterAppear:K,onAppearCancelled:k}=t,g=String(e.key),_=No(n,e),M=(T,$)=>{T&&Se(T,r,9,$)},L=(T,$)=>{const E=$[1];M(T,$),B(T)?T.every(j=>j.length<=1)&&E():T.length<=1&&E()},F={mode:o,persisted:i,beforeEnter(T){let $=l;if(!n.isMounted)if(s)$=I||l;else return;T[Ge]&&T[Ge](!0);const E=_[g];E&&it(e,E)&&E.el[Ge]&&E.el[Ge](),M($,[T])},enter(T){let $=c,E=a,j=f;if(!n.isMounted)if(s)$=N||c,E=K||a,j=k||f;else return;let A=!1;const G=T[sn]=ie=>{A||(A=!0,ie?M(j,[T]):M(E,[T]),F.delayedLeave&&F.delayedLeave(),T[sn]=void 0)};$?L($,[T,G]):G()},leave(T,$){const E=String(e.key);if(T[sn]&&T[sn](!0),n.isUnmounting)return $();M(h,[T]);let j=!1;const A=T[Ge]=G=>{j||(j=!0,$(),G?M(v,[T]):M(y,[T]),T[Ge]=void 0,_[E]===e&&delete _[E])};_[E]=e,p?L(p,[T,A]):A()},clone(T){return gr(T,t,n,r)}};return F}function Xn(e){if(Gt(e))return e=et(e),e.children=null,e}function ps(e){return Gt(e)?e.children?e.children[0]:void 0:e}function mr(e,t){e.shapeFlag&6&&e.component?mr(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Fo(e,t=!1,n){let r=[],s=0;for(let o=0;o1)for(let o=0;o!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function ou(e){q(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:s=200,timeout:o,suspensible:i=!0,onError:l}=e;let c=null,a,f=0;const h=()=>(f++,c=null,p()),p=()=>{let y;return c||(y=c=t().catch(v=>{if(v=v instanceof Error?v:new Error(String(v)),l)return new Promise((I,N)=>{l(v,()=>I(h()),()=>N(v),f+1)});throw v}).then(v=>y!==c&&c?c:(v&&(v.__esModule||v[Symbol.toStringTag]==="Module")&&(v=v.default),a=v,v)))};return kr({name:"AsyncComponentWrapper",__asyncLoader:p,get __asyncResolved(){return a},setup(){const y=ue;if(a)return()=>Yn(a,y);const v=k=>{c=null,qt(k,y,13,!r)};if(i&&y.suspense||Xt)return p().then(k=>()=>Yn(k,y)).catch(k=>(v(k),()=>r?oe(r,{error:k}):null));const I=se(!1),N=se(),K=se(!!s);return s&&setTimeout(()=>{K.value=!1},s),o!=null&&setTimeout(()=>{if(!I.value&&!N.value){const k=new Error(`Async component timed out after ${o}ms.`);v(k),N.value=k}},o),p().then(()=>{I.value=!0,y.parent&&Gt(y.parent.vnode)&&(y.parent.effect.dirty=!0,Fn(y.parent.update))}).catch(k=>{v(k),N.value=k}),()=>{if(I.value&&a)return Yn(a,y);if(N.value&&r)return oe(r,{error:N.value});if(n&&!K.value)return oe(n)}}})}function Yn(e,t){const{ref:n,props:r,children:s,ce:o}=t.vnode,i=oe(e,r,s);return i.ref=n,i.ce=o,delete t.vnode.ce,i}const Gt=e=>e.type.__isKeepAlive;function Fl(e,t){$o(e,"a",t)}function $l(e,t){$o(e,"da",t)}function $o(e,t,n=ue){const r=e.__wdc||(e.__wdc=()=>{let s=n;for(;s;){if(s.isDeactivated)return;s=s.parent}return e()});if(Vn(t,r,n),n){let s=n.parent;for(;s&&s.parent;)Gt(s.parent.vnode)&&Hl(r,t,n,s),s=s.parent}}function Hl(e,t,n,r){const s=Vn(t,e,r,!0);Dn(()=>{Ar(r[t],s)},n)}function Vn(e,t,n=ue,r=!1){if(n){const s=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...i)=>{if(n.isUnmounted)return;dt();const l=zt(n),c=Se(t,n,e,i);return l(),ht(),c});return r?s.unshift(o):s.push(o),o}}const Ue=e=>(t,n=ue)=>(!Xt||e==="sp")&&Vn(e,(...r)=>t(...r),n),jl=Ue("bm"),Rt=Ue("m"),Vl=Ue("bu"),Dl=Ue("u"),Ho=Ue("bum"),Dn=Ue("um"),Ul=Ue("sp"),Bl=Ue("rtg"),kl=Ue("rtc");function Kl(e,t=ue){Vn("ec",e,t)}function iu(e,t,n,r){let s;const o=n&&n[r];if(B(e)||ne(e)){s=new Array(e.length);for(let i=0,l=e.length;it(i,l,void 0,o&&o[l]));else{const i=Object.keys(e);s=new Array(i.length);for(let l=0,c=i.length;lSn(t)?!(t.type===be||t.type===me&&!jo(t.children)):!0)?e:null}function cu(e,t){const n={};for(const r in e)n[t&&/[A-Z]/.test(r)?`on:${r}`:hn(r)]=e[r];return n}const yr=e=>e?ni(e)?kn(e)||e.proxy:yr(e.parent):null,Nt=ce(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>yr(e.parent),$root:e=>yr(e.root),$emit:e=>e.emit,$options:e=>Kr(e),$forceUpdate:e=>e.f||(e.f=()=>{e.effect.dirty=!0,Fn(e.update)}),$nextTick:e=>e.n||(e.n=Nn.bind(e.proxy)),$watch:e=>Il.bind(e)}),Jn=(e,t)=>e!==ee&&!e.__isScriptSetup&&Y(e,t),Wl={get({_:e},t){const{ctx:n,setupState:r,data:s,props:o,accessCache:i,type:l,appContext:c}=e;let a;if(t[0]!=="$"){const y=i[t];if(y!==void 0)switch(y){case 1:return r[t];case 2:return s[t];case 4:return n[t];case 3:return o[t]}else{if(Jn(r,t))return i[t]=1,r[t];if(s!==ee&&Y(s,t))return i[t]=2,s[t];if((a=e.propsOptions[0])&&Y(a,t))return i[t]=3,o[t];if(n!==ee&&Y(n,t))return i[t]=4,n[t];_r&&(i[t]=0)}}const f=Nt[t];let h,p;if(f)return t==="$attrs"&&ye(e,"get",t),f(e);if((h=l.__cssModules)&&(h=h[t]))return h;if(n!==ee&&Y(n,t))return i[t]=4,n[t];if(p=c.config.globalProperties,Y(p,t))return p[t]},set({_:e},t,n){const{data:r,setupState:s,ctx:o}=e;return Jn(s,t)?(s[t]=n,!0):r!==ee&&Y(r,t)?(r[t]=n,!0):Y(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:s,propsOptions:o}},i){let l;return!!n[i]||e!==ee&&Y(e,i)||Jn(t,i)||(l=o[0])&&Y(l,i)||Y(r,i)||Y(Nt,i)||Y(s.config.globalProperties,i)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:Y(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function au(){return ql().slots}function ql(){const e=Bn();return e.setupContext||(e.setupContext=si(e))}function gs(e){return B(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let _r=!0;function Gl(e){const t=Kr(e),n=e.proxy,r=e.ctx;_r=!1,t.beforeCreate&&ms(t.beforeCreate,e,"bc");const{data:s,computed:o,methods:i,watch:l,provide:c,inject:a,created:f,beforeMount:h,mounted:p,beforeUpdate:y,updated:v,activated:I,deactivated:N,beforeDestroy:K,beforeUnmount:k,destroyed:g,unmounted:_,render:M,renderTracked:L,renderTriggered:F,errorCaptured:T,serverPrefetch:$,expose:E,inheritAttrs:j,components:A,directives:G,filters:ie}=t;if(a&&zl(a,r,null),i)for(const X in i){const V=i[X];q(V)&&(r[X]=V.bind(n))}if(s){const X=s.call(n,n);Z(X)&&(e.data=Mn(X))}if(_r=!0,o)for(const X in o){const V=o[X],$e=q(V)?V.bind(n,n):q(V.get)?V.get.bind(n,n):xe,Yt=!q(V)&&q(V.set)?V.set.bind(n):xe,tt=re({get:$e,set:Yt});Object.defineProperty(r,X,{enumerable:!0,configurable:!0,get:()=>tt.value,set:Oe=>tt.value=Oe})}if(l)for(const X in l)Vo(l[X],r,n,X);if(c){const X=q(c)?c.call(n):c;Reflect.ownKeys(X).forEach(V=>{ec(V,X[V])})}f&&ms(f,e,"c");function D(X,V){B(V)?V.forEach($e=>X($e.bind(n))):V&&X(V.bind(n))}if(D(jl,h),D(Rt,p),D(Vl,y),D(Dl,v),D(Fl,I),D($l,N),D(Kl,T),D(kl,L),D(Bl,F),D(Ho,k),D(Dn,_),D(Ul,$),B(E))if(E.length){const X=e.exposed||(e.exposed={});E.forEach(V=>{Object.defineProperty(X,V,{get:()=>n[V],set:$e=>n[V]=$e})})}else e.exposed||(e.exposed={});M&&e.render===xe&&(e.render=M),j!=null&&(e.inheritAttrs=j),A&&(e.components=A),G&&(e.directives=G)}function zl(e,t,n=xe){B(e)&&(e=vr(e));for(const r in e){const s=e[r];let o;Z(s)?"default"in s?o=xt(s.from||r,s.default,!0):o=xt(s.from||r):o=xt(s),de(o)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>o.value,set:i=>o.value=i}):t[r]=o}}function ms(e,t,n){Se(B(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function Vo(e,t,n,r){const s=r.includes(".")?Mo(n,r):()=>n[r];if(ne(e)){const o=t[e];q(o)&&Ve(s,o)}else if(q(e))Ve(s,e.bind(n));else if(Z(e))if(B(e))e.forEach(o=>Vo(o,t,n,r));else{const o=q(e.handler)?e.handler.bind(n):t[e.handler];q(o)&&Ve(s,o,e)}}function Kr(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:s,optionsCache:o,config:{optionMergeStrategies:i}}=e.appContext,l=o.get(t);let c;return l?c=l:!s.length&&!n&&!r?c=t:(c={},s.length&&s.forEach(a=>Cn(c,a,i,!0)),Cn(c,t,i)),Z(t)&&o.set(t,c),c}function Cn(e,t,n,r=!1){const{mixins:s,extends:o}=t;o&&Cn(e,o,n,!0),s&&s.forEach(i=>Cn(e,i,n,!0));for(const i in t)if(!(r&&i==="expose")){const l=Xl[i]||n&&n[i];e[i]=l?l(e[i],t[i]):t[i]}return e}const Xl={data:ys,props:_s,emits:_s,methods:It,computed:It,beforeCreate:pe,created:pe,beforeMount:pe,mounted:pe,beforeUpdate:pe,updated:pe,beforeDestroy:pe,beforeUnmount:pe,destroyed:pe,unmounted:pe,activated:pe,deactivated:pe,errorCaptured:pe,serverPrefetch:pe,components:It,directives:It,watch:Jl,provide:ys,inject:Yl};function ys(e,t){return t?e?function(){return ce(q(e)?e.call(this,this):e,q(t)?t.call(this,this):t)}:t:e}function Yl(e,t){return It(vr(e),vr(t))}function vr(e){if(B(e)){const t={};for(let n=0;n1)return n&&q(t)?t.call(r&&r.proxy):t}}function tc(e,t,n,r=!1){const s={},o={};_n(o,Un,1),e.propsDefaults=Object.create(null),Uo(e,t,s,o);for(const i in e.propsOptions[0])i in s||(s[i]=void 0);n?e.props=r?s:ll(s):e.type.props?e.props=s:e.props=o,e.attrs=o}function nc(e,t,n,r){const{props:s,attrs:o,vnode:{patchFlag:i}}=e,l=J(s),[c]=e.propsOptions;let a=!1;if((r||i>0)&&!(i&16)){if(i&8){const f=e.vnode.dynamicProps;for(let h=0;h{c=!0;const[p,y]=Bo(h,t,!0);ce(i,p),y&&l.push(...y)};!n&&t.mixins.length&&t.mixins.forEach(f),e.extends&&f(e.extends),e.mixins&&e.mixins.forEach(f)}if(!o&&!c)return Z(e)&&r.set(e,_t),_t;if(B(o))for(let f=0;f-1,y[1]=I<0||v-1||Y(y,"default"))&&l.push(h)}}}const a=[i,l];return Z(e)&&r.set(e,a),a}function vs(e){return e[0]!=="$"&&!bt(e)}function bs(e){return e===null?"null":typeof e=="function"?e.name||"":typeof e=="object"&&e.constructor&&e.constructor.name||""}function ws(e,t){return bs(e)===bs(t)}function Es(e,t){return B(t)?t.findIndex(n=>ws(n,e)):q(t)&&ws(t,e)?0:-1}const ko=e=>e[0]==="_"||e==="$stable",Wr=e=>B(e)?e.map(Re):[Re(e)],rc=(e,t,n)=>{if(t._n)return t;const r=Cl((...s)=>Wr(t(...s)),n);return r._c=!1,r},Ko=(e,t,n)=>{const r=e._ctx;for(const s in e){if(ko(s))continue;const o=e[s];if(q(o))t[s]=rc(s,o,r);else if(o!=null){const i=Wr(o);t[s]=()=>i}}},Wo=(e,t)=>{const n=Wr(t);e.slots.default=()=>n},sc=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=J(t),_n(t,"_",n)):Ko(t,e.slots={})}else e.slots={},t&&Wo(e,t);_n(e.slots,Un,1)},oc=(e,t,n)=>{const{vnode:r,slots:s}=e;let o=!0,i=ee;if(r.shapeFlag&32){const l=t._;l?n&&l===1?o=!1:(ce(s,t),!n&&l===1&&delete s._):(o=!t.$stable,Ko(t,s)),i=t}else t&&(Wo(e,t),i={default:1});if(o)for(const l in s)!ko(l)&&i[l]==null&&delete s[l]};function xn(e,t,n,r,s=!1){if(B(e)){e.forEach((p,y)=>xn(p,t&&(B(t)?t[y]:t),n,r,s));return}if(Ct(r)&&!s)return;const o=r.shapeFlag&4?kn(r.component)||r.component.proxy:r.el,i=s?null:o,{i:l,r:c}=e,a=t&&t.r,f=l.refs===ee?l.refs={}:l.refs,h=l.setupState;if(a!=null&&a!==c&&(ne(a)?(f[a]=null,Y(h,a)&&(h[a]=null)):de(a)&&(a.value=null)),q(c))Je(c,l,12,[i,f]);else{const p=ne(c),y=de(c);if(p||y){const v=()=>{if(e.f){const I=p?Y(h,c)?h[c]:f[c]:c.value;s?B(I)&&Ar(I,o):B(I)?I.includes(o)||I.push(o):p?(f[c]=[o],Y(h,c)&&(h[c]=f[c])):(c.value=[o],e.k&&(f[e.k]=c.value))}else p?(f[c]=i,Y(h,c)&&(h[c]=i)):y&&(c.value=i,e.k&&(f[e.k]=i))};i?(v.id=-1,ge(v,n)):v()}}}let ke=!1;const ic=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",lc=e=>e.namespaceURI.includes("MathML"),on=e=>{if(ic(e))return"svg";if(lc(e))return"mathml"},ln=e=>e.nodeType===8;function cc(e){const{mt:t,p:n,o:{patchProp:r,createText:s,nextSibling:o,parentNode:i,remove:l,insert:c,createComment:a}}=e,f=(g,_)=>{if(!_.hasChildNodes()){n(null,g,_),wn(),_._vnode=g;return}ke=!1,h(_.firstChild,g,null,null,null),wn(),_._vnode=g,ke&&console.error("Hydration completed but contains mismatches.")},h=(g,_,M,L,F,T=!1)=>{const $=ln(g)&&g.data==="[",E=()=>I(g,_,M,L,F,$),{type:j,ref:A,shapeFlag:G,patchFlag:ie}=_;let fe=g.nodeType;_.el=g,ie===-2&&(T=!1,_.dynamicChildren=null);let D=null;switch(j){case Tt:fe!==3?_.children===""?(c(_.el=s(""),i(g),g),D=g):D=E():(g.data!==_.children&&(ke=!0,g.data=_.children),D=o(g));break;case be:k(g)?(D=o(g),K(_.el=g.content.firstChild,g,M)):fe!==8||$?D=E():D=o(g);break;case Ht:if($&&(g=o(g),fe=g.nodeType),fe===1||fe===3){D=g;const X=!_.children.length;for(let V=0;V<_.staticCount;V++)X&&(_.children+=D.nodeType===1?D.outerHTML:D.data),V===_.staticCount-1&&(_.anchor=D),D=o(D);return $?o(D):D}else E();break;case me:$?D=v(g,_,M,L,F,T):D=E();break;default:if(G&1)(fe!==1||_.type.toLowerCase()!==g.tagName.toLowerCase())&&!k(g)?D=E():D=p(g,_,M,L,F,T);else if(G&6){_.slotScopeIds=F;const X=i(g);if($?D=N(g):ln(g)&&g.data==="teleport start"?D=N(g,g.data,"teleport end"):D=o(g),t(_,X,null,M,L,on(X),T),Ct(_)){let V;$?(V=oe(me),V.anchor=D?D.previousSibling:X.lastChild):V=g.nodeType===3?ti(""):oe("div"),V.el=g,_.component.subTree=V}}else G&64?fe!==8?D=E():D=_.type.hydrate(g,_,M,L,F,T,e,y):G&128&&(D=_.type.hydrate(g,_,M,L,on(i(g)),F,T,e,h))}return A!=null&&xn(A,null,L,_),D},p=(g,_,M,L,F,T)=>{T=T||!!_.dynamicChildren;const{type:$,props:E,patchFlag:j,shapeFlag:A,dirs:G,transition:ie}=_,fe=$==="input"||$==="option";if(fe||j!==-1){G&&Me(_,null,M,"created");let D=!1;if(k(g)){D=Go(L,ie)&&M&&M.vnode.props&&M.vnode.props.appear;const V=g.content.firstChild;D&&ie.beforeEnter(V),K(V,g,M),_.el=g=V}if(A&16&&!(E&&(E.innerHTML||E.textContent))){let V=y(g.firstChild,_,g,M,L,F,T);for(;V;){ke=!0;const $e=V;V=V.nextSibling,l($e)}}else A&8&&g.textContent!==_.children&&(ke=!0,g.textContent=_.children);if(E)if(fe||!T||j&48)for(const V in E)(fe&&(V.endsWith("value")||V==="indeterminate")||Wt(V)&&!bt(V)||V[0]===".")&&r(g,V,null,E[V],void 0,void 0,M);else E.onClick&&r(g,"onClick",null,E.onClick,void 0,void 0,M);let X;(X=E&&E.onVnodeBeforeMount)&&Ee(X,M,_),G&&Me(_,null,M,"beforeMount"),((X=E&&E.onVnodeMounted)||G||D)&&Io(()=>{X&&Ee(X,M,_),D&&ie.enter(g),G&&Me(_,null,M,"mounted")},L)}return g.nextSibling},y=(g,_,M,L,F,T,$)=>{$=$||!!_.dynamicChildren;const E=_.children,j=E.length;for(let A=0;A{const{slotScopeIds:$}=_;$&&(F=F?F.concat($):$);const E=i(g),j=y(o(g),_,E,M,L,F,T);return j&&ln(j)&&j.data==="]"?o(_.anchor=j):(ke=!0,c(_.anchor=a("]"),E,j),j)},I=(g,_,M,L,F,T)=>{if(ke=!0,_.el=null,T){const j=N(g);for(;;){const A=o(g);if(A&&A!==j)l(A);else break}}const $=o(g),E=i(g);return l(g),n(null,_,E,$,M,L,on(E),F),$},N=(g,_="[",M="]")=>{let L=0;for(;g;)if(g=o(g),g&&ln(g)&&(g.data===_&&L++,g.data===M)){if(L===0)return o(g);L--}return g},K=(g,_,M)=>{const L=_.parentNode;L&&L.replaceChild(g,_);let F=M;for(;F;)F.vnode.el===_&&(F.vnode.el=F.subTree.el=g),F=F.parent},k=g=>g.nodeType===1&&g.tagName.toLowerCase()==="template";return[f,h]}const ge=Io;function ac(e){return qo(e)}function uc(e){return qo(e,cc)}function qo(e,t){const n=so();n.__VUE__=!0;const{insert:r,remove:s,patchProp:o,createElement:i,createText:l,createComment:c,setText:a,setElementText:f,parentNode:h,nextSibling:p,setScopeId:y=xe,insertStaticContent:v}=e,I=(u,d,m,b=null,w=null,S=null,O=void 0,x=null,R=!!d.dynamicChildren)=>{if(u===d)return;u&&!it(u,d)&&(b=Jt(u),Oe(u,w,S,!0),u=null),d.patchFlag===-2&&(R=!1,d.dynamicChildren=null);const{type:C,ref:P,shapeFlag:U}=d;switch(C){case Tt:N(u,d,m,b);break;case be:K(u,d,m,b);break;case Ht:u==null&&k(d,m,b,O);break;case me:A(u,d,m,b,w,S,O,x,R);break;default:U&1?M(u,d,m,b,w,S,O,x,R):U&6?G(u,d,m,b,w,S,O,x,R):(U&64||U&128)&&C.process(u,d,m,b,w,S,O,x,R,pt)}P!=null&&w&&xn(P,u&&u.ref,S,d||u,!d)},N=(u,d,m,b)=>{if(u==null)r(d.el=l(d.children),m,b);else{const w=d.el=u.el;d.children!==u.children&&a(w,d.children)}},K=(u,d,m,b)=>{u==null?r(d.el=c(d.children||""),m,b):d.el=u.el},k=(u,d,m,b)=>{[u.el,u.anchor]=v(u.children,d,m,b,u.el,u.anchor)},g=({el:u,anchor:d},m,b)=>{let w;for(;u&&u!==d;)w=p(u),r(u,m,b),u=w;r(d,m,b)},_=({el:u,anchor:d})=>{let m;for(;u&&u!==d;)m=p(u),s(u),u=m;s(d)},M=(u,d,m,b,w,S,O,x,R)=>{d.type==="svg"?O="svg":d.type==="math"&&(O="mathml"),u==null?L(d,m,b,w,S,O,x,R):$(u,d,w,S,O,x,R)},L=(u,d,m,b,w,S,O,x)=>{let R,C;const{props:P,shapeFlag:U,transition:H,dirs:W}=u;if(R=u.el=i(u.type,S,P&&P.is,P),U&8?f(R,u.children):U&16&&T(u.children,R,null,b,w,Qn(u,S),O,x),W&&Me(u,null,b,"created"),F(R,u,u.scopeId,O,b),P){for(const Q in P)Q!=="value"&&!bt(Q)&&o(R,Q,null,P[Q],S,u.children,b,w,He);"value"in P&&o(R,"value",null,P.value,S),(C=P.onVnodeBeforeMount)&&Ee(C,b,u)}W&&Me(u,null,b,"beforeMount");const z=Go(w,H);z&&H.beforeEnter(R),r(R,d,m),((C=P&&P.onVnodeMounted)||z||W)&&ge(()=>{C&&Ee(C,b,u),z&&H.enter(R),W&&Me(u,null,b,"mounted")},w)},F=(u,d,m,b,w)=>{if(m&&y(u,m),b)for(let S=0;S{for(let C=R;C{const x=d.el=u.el;let{patchFlag:R,dynamicChildren:C,dirs:P}=d;R|=u.patchFlag&16;const U=u.props||ee,H=d.props||ee;let W;if(m&&nt(m,!1),(W=H.onVnodeBeforeUpdate)&&Ee(W,m,d,u),P&&Me(d,u,m,"beforeUpdate"),m&&nt(m,!0),C?E(u.dynamicChildren,C,x,m,b,Qn(d,w),S):O||V(u,d,x,null,m,b,Qn(d,w),S,!1),R>0){if(R&16)j(x,d,U,H,m,b,w);else if(R&2&&U.class!==H.class&&o(x,"class",null,H.class,w),R&4&&o(x,"style",U.style,H.style,w),R&8){const z=d.dynamicProps;for(let Q=0;Q{W&&Ee(W,m,d,u),P&&Me(d,u,m,"updated")},b)},E=(u,d,m,b,w,S,O)=>{for(let x=0;x{if(m!==b){if(m!==ee)for(const x in m)!bt(x)&&!(x in b)&&o(u,x,m[x],null,O,d.children,w,S,He);for(const x in b){if(bt(x))continue;const R=b[x],C=m[x];R!==C&&x!=="value"&&o(u,x,C,R,O,d.children,w,S,He)}"value"in b&&o(u,"value",m.value,b.value,O)}},A=(u,d,m,b,w,S,O,x,R)=>{const C=d.el=u?u.el:l(""),P=d.anchor=u?u.anchor:l("");let{patchFlag:U,dynamicChildren:H,slotScopeIds:W}=d;W&&(x=x?x.concat(W):W),u==null?(r(C,m,b),r(P,m,b),T(d.children||[],m,P,w,S,O,x,R)):U>0&&U&64&&H&&u.dynamicChildren?(E(u.dynamicChildren,H,m,w,S,O,x),(d.key!=null||w&&d===w.subTree)&&qr(u,d,!0)):V(u,d,m,P,w,S,O,x,R)},G=(u,d,m,b,w,S,O,x,R)=>{d.slotScopeIds=x,u==null?d.shapeFlag&512?w.ctx.activate(d,m,b,O,R):ie(d,m,b,w,S,O,R):fe(u,d,R)},ie=(u,d,m,b,w,S,O)=>{const x=u.component=wc(u,b,w);if(Gt(u)&&(x.ctx.renderer=pt),Ec(x),x.asyncDep){if(w&&w.registerDep(x,D),!u.el){const R=x.subTree=oe(be);K(null,R,d,m)}}else D(x,u,d,m,w,S,O)},fe=(u,d,m)=>{const b=d.component=u.component;if(Tl(u,d,m))if(b.asyncDep&&!b.asyncResolved){X(b,d,m);return}else b.next=d,vl(b.update),b.effect.dirty=!0,b.update();else d.el=u.el,b.vnode=d},D=(u,d,m,b,w,S,O)=>{const x=()=>{if(u.isMounted){let{next:P,bu:U,u:H,parent:W,vnode:z}=u;{const gt=zo(u);if(gt){P&&(P.el=z.el,X(u,P,O)),gt.asyncDep.then(()=>{u.isUnmounted||x()});return}}let Q=P,te;nt(u,!1),P?(P.el=z.el,X(u,P,O)):P=z,U&&pn(U),(te=P.props&&P.props.onVnodeBeforeUpdate)&&Ee(te,W,P,z),nt(u,!0);const ae=zn(u),Ae=u.subTree;u.subTree=ae,I(Ae,ae,h(Ae.el),Jt(Ae),u,w,S),P.el=ae.el,Q===null&&Al(u,ae.el),H&&ge(H,w),(te=P.props&&P.props.onVnodeUpdated)&&ge(()=>Ee(te,W,P,z),w)}else{let P;const{el:U,props:H}=d,{bm:W,m:z,parent:Q}=u,te=Ct(d);if(nt(u,!1),W&&pn(W),!te&&(P=H&&H.onVnodeBeforeMount)&&Ee(P,Q,d),nt(u,!0),U&&qn){const ae=()=>{u.subTree=zn(u),qn(U,u.subTree,u,w,null)};te?d.type.__asyncLoader().then(()=>!u.isUnmounted&&ae()):ae()}else{const ae=u.subTree=zn(u);I(null,ae,m,b,u,w,S),d.el=ae.el}if(z&&ge(z,w),!te&&(P=H&&H.onVnodeMounted)){const ae=d;ge(()=>Ee(P,Q,ae),w)}(d.shapeFlag&256||Q&&Ct(Q.vnode)&&Q.vnode.shapeFlag&256)&&u.a&&ge(u.a,w),u.isMounted=!0,d=m=b=null}},R=u.effect=new Ir(x,xe,()=>Fn(C),u.scope),C=u.update=()=>{R.dirty&&R.run()};C.id=u.uid,nt(u,!0),C()},X=(u,d,m)=>{d.component=u;const b=u.vnode.props;u.vnode=d,u.next=null,nc(u,d.props,b,m),oc(u,d.children,m),dt(),fs(u),ht()},V=(u,d,m,b,w,S,O,x,R=!1)=>{const C=u&&u.children,P=u?u.shapeFlag:0,U=d.children,{patchFlag:H,shapeFlag:W}=d;if(H>0){if(H&128){Yt(C,U,m,b,w,S,O,x,R);return}else if(H&256){$e(C,U,m,b,w,S,O,x,R);return}}W&8?(P&16&&He(C,w,S),U!==C&&f(m,U)):P&16?W&16?Yt(C,U,m,b,w,S,O,x,R):He(C,w,S,!0):(P&8&&f(m,""),W&16&&T(U,m,b,w,S,O,x,R))},$e=(u,d,m,b,w,S,O,x,R)=>{u=u||_t,d=d||_t;const C=u.length,P=d.length,U=Math.min(C,P);let H;for(H=0;HP?He(u,w,S,!0,!1,U):T(d,m,b,w,S,O,x,R,U)},Yt=(u,d,m,b,w,S,O,x,R)=>{let C=0;const P=d.length;let U=u.length-1,H=P-1;for(;C<=U&&C<=H;){const W=u[C],z=d[C]=R?ze(d[C]):Re(d[C]);if(it(W,z))I(W,z,m,null,w,S,O,x,R);else break;C++}for(;C<=U&&C<=H;){const W=u[U],z=d[H]=R?ze(d[H]):Re(d[H]);if(it(W,z))I(W,z,m,null,w,S,O,x,R);else break;U--,H--}if(C>U){if(C<=H){const W=H+1,z=WH)for(;C<=U;)Oe(u[C],w,S,!0),C++;else{const W=C,z=C,Q=new Map;for(C=z;C<=H;C++){const _e=d[C]=R?ze(d[C]):Re(d[C]);_e.key!=null&&Q.set(_e.key,C)}let te,ae=0;const Ae=H-z+1;let gt=!1,es=0;const Lt=new Array(Ae);for(C=0;C=Ae){Oe(_e,w,S,!0);continue}let Ie;if(_e.key!=null)Ie=Q.get(_e.key);else for(te=z;te<=H;te++)if(Lt[te-z]===0&&it(_e,d[te])){Ie=te;break}Ie===void 0?Oe(_e,w,S,!0):(Lt[Ie-z]=C+1,Ie>=es?es=Ie:gt=!0,I(_e,d[Ie],m,null,w,S,O,x,R),ae++)}const ts=gt?fc(Lt):_t;for(te=ts.length-1,C=Ae-1;C>=0;C--){const _e=z+C,Ie=d[_e],ns=_e+1{const{el:S,type:O,transition:x,children:R,shapeFlag:C}=u;if(C&6){tt(u.component.subTree,d,m,b);return}if(C&128){u.suspense.move(d,m,b);return}if(C&64){O.move(u,d,m,pt);return}if(O===me){r(S,d,m);for(let U=0;Ux.enter(S),w);else{const{leave:U,delayLeave:H,afterLeave:W}=x,z=()=>r(S,d,m),Q=()=>{U(S,()=>{z(),W&&W()})};H?H(S,z,Q):Q()}else r(S,d,m)},Oe=(u,d,m,b=!1,w=!1)=>{const{type:S,props:O,ref:x,children:R,dynamicChildren:C,shapeFlag:P,patchFlag:U,dirs:H}=u;if(x!=null&&xn(x,null,m,u,!0),P&256){d.ctx.deactivate(u);return}const W=P&1&&H,z=!Ct(u);let Q;if(z&&(Q=O&&O.onVnodeBeforeUnmount)&&Ee(Q,d,u),P&6)Si(u.component,m,b);else{if(P&128){u.suspense.unmount(m,b);return}W&&Me(u,null,d,"beforeUnmount"),P&64?u.type.remove(u,d,m,w,pt,b):C&&(S!==me||U>0&&U&64)?He(C,d,m,!1,!0):(S===me&&U&384||!w&&P&16)&&He(R,d,m),b&&Qr(u)}(z&&(Q=O&&O.onVnodeUnmounted)||W)&&ge(()=>{Q&&Ee(Q,d,u),W&&Me(u,null,d,"unmounted")},m)},Qr=u=>{const{type:d,el:m,anchor:b,transition:w}=u;if(d===me){xi(m,b);return}if(d===Ht){_(u);return}const S=()=>{s(m),w&&!w.persisted&&w.afterLeave&&w.afterLeave()};if(u.shapeFlag&1&&w&&!w.persisted){const{leave:O,delayLeave:x}=w,R=()=>O(m,S);x?x(u.el,S,R):R()}else S()},xi=(u,d)=>{let m;for(;u!==d;)m=p(u),s(u),u=m;s(d)},Si=(u,d,m)=>{const{bum:b,scope:w,update:S,subTree:O,um:x}=u;b&&pn(b),w.stop(),S&&(S.active=!1,Oe(O,u,d,m)),x&&ge(x,d),ge(()=>{u.isUnmounted=!0},d),d&&d.pendingBranch&&!d.isUnmounted&&u.asyncDep&&!u.asyncResolved&&u.suspenseId===d.pendingId&&(d.deps--,d.deps===0&&d.resolve())},He=(u,d,m,b=!1,w=!1,S=0)=>{for(let O=S;Ou.shapeFlag&6?Jt(u.component.subTree):u.shapeFlag&128?u.suspense.next():p(u.anchor||u.el);let Kn=!1;const Zr=(u,d,m)=>{u==null?d._vnode&&Oe(d._vnode,null,null,!0):I(d._vnode||null,u,d,null,null,null,m),Kn||(Kn=!0,fs(),wn(),Kn=!1),d._vnode=u},pt={p:I,um:Oe,m:tt,r:Qr,mt:ie,mc:T,pc:V,pbc:E,n:Jt,o:e};let Wn,qn;return t&&([Wn,qn]=t(pt)),{render:Zr,hydrate:Wn,createApp:Zl(Zr,Wn)}}function Qn({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function nt({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function Go(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function qr(e,t,n=!1){const r=e.children,s=t.children;if(B(r)&&B(s))for(let o=0;o>1,e[n[l]]0&&(t[r]=n[o-1]),n[o]=r)}}for(o=n.length,i=n[o-1];o-- >0;)n[o]=i,i=t[i];return n}function zo(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:zo(t)}const dc=e=>e.__isTeleport,$t=e=>e&&(e.disabled||e.disabled===""),Cs=e=>typeof SVGElement<"u"&&e instanceof SVGElement,xs=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,wr=(e,t)=>{const n=e&&e.to;return ne(n)?t?t(n):null:n},hc={name:"Teleport",__isTeleport:!0,process(e,t,n,r,s,o,i,l,c,a){const{mc:f,pc:h,pbc:p,o:{insert:y,querySelector:v,createText:I,createComment:N}}=a,K=$t(t.props);let{shapeFlag:k,children:g,dynamicChildren:_}=t;if(e==null){const M=t.el=I(""),L=t.anchor=I("");y(M,n,r),y(L,n,r);const F=t.target=wr(t.props,v),T=t.targetAnchor=I("");F&&(y(T,F),i==="svg"||Cs(F)?i="svg":(i==="mathml"||xs(F))&&(i="mathml"));const $=(E,j)=>{k&16&&f(g,E,j,s,o,i,l,c)};K?$(n,L):F&&$(F,T)}else{t.el=e.el;const M=t.anchor=e.anchor,L=t.target=e.target,F=t.targetAnchor=e.targetAnchor,T=$t(e.props),$=T?n:L,E=T?M:F;if(i==="svg"||Cs(L)?i="svg":(i==="mathml"||xs(L))&&(i="mathml"),_?(p(e.dynamicChildren,_,$,s,o,i,l),qr(e,t,!0)):c||h(e,t,$,E,s,o,i,l,!1),K)T?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):cn(t,n,M,a,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const j=t.target=wr(t.props,v);j&&cn(t,j,null,a,0)}else T&&cn(t,L,F,a,1)}Xo(t)},remove(e,t,n,r,{um:s,o:{remove:o}},i){const{shapeFlag:l,children:c,anchor:a,targetAnchor:f,target:h,props:p}=e;if(h&&o(f),i&&o(a),l&16){const y=i||!$t(p);for(let v=0;v0?Le||_t:null,gc(),kt>0&&Le&&Le.push(e),e}function fu(e,t,n,r,s,o){return Jo(ei(e,t,n,r,s,o,!0))}function Qo(e,t,n,r,s){return Jo(oe(e,t,n,r,s,!0))}function Sn(e){return e?e.__v_isVNode===!0:!1}function it(e,t){return e.type===t.type&&e.key===t.key}const Un="__vInternal",Zo=({key:e})=>e??null,gn=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?ne(e)||de(e)||q(e)?{i:le,r:e,k:t,f:!!n}:e:null);function ei(e,t=null,n=null,r=0,s=null,o=e===me?0:1,i=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Zo(t),ref:t&&gn(t),scopeId:Hn,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:r,dynamicProps:s,dynamicChildren:null,appContext:null,ctx:le};return l?(Gr(c,n),o&128&&e.normalize(c)):n&&(c.shapeFlag|=ne(n)?8:16),kt>0&&!i&&Le&&(c.patchFlag>0||o&6)&&c.patchFlag!==32&&Le.push(c),c}const oe=mc;function mc(e,t=null,n=null,r=0,s=null,o=!1){if((!e||e===Lo)&&(e=be),Sn(e)){const l=et(e,t,!0);return n&&Gr(l,n),kt>0&&!o&&Le&&(l.shapeFlag&6?Le[Le.indexOf(e)]=l:Le.push(l)),l.patchFlag|=-2,l}if(Tc(e)&&(e=e.__vccOpts),t){t=yc(t);let{class:l,style:c}=t;l&&!ne(l)&&(t.class=Or(l)),Z(c)&&(bo(c)&&!B(c)&&(c=ce({},c)),t.style=Lr(c))}const i=ne(e)?1:Rl(e)?128:dc(e)?64:Z(e)?4:q(e)?2:0;return ei(e,t,n,r,s,i,o,!0)}function yc(e){return e?bo(e)||Un in e?ce({},e):e:null}function et(e,t,n=!1){const{props:r,ref:s,patchFlag:o,children:i}=e,l=t?_c(r||{},t):r;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&Zo(l),ref:t&&t.ref?n&&s?B(s)?s.concat(gn(t)):[s,gn(t)]:gn(t):s,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==me?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&et(e.ssContent),ssFallback:e.ssFallback&&et(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function ti(e=" ",t=0){return oe(Tt,null,e,t)}function du(e,t){const n=oe(Ht,null,e);return n.staticCount=t,n}function hu(e="",t=!1){return t?(Yo(),Qo(be,null,e)):oe(be,null,e)}function Re(e){return e==null||typeof e=="boolean"?oe(be):B(e)?oe(me,null,e.slice()):typeof e=="object"?ze(e):oe(Tt,null,String(e))}function ze(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:et(e)}function Gr(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(B(t))n=16;else if(typeof t=="object")if(r&65){const s=t.default;s&&(s._c&&(s._d=!1),Gr(e,s()),s._c&&(s._d=!0));return}else{n=32;const s=t._;!s&&!(Un in t)?t._ctx=le:s===3&&le&&(le.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else q(t)?(t={default:t,_ctx:le},n=32):(t=String(t),r&64?(n=16,t=[ti(t)]):n=8);e.children=t,e.shapeFlag|=n}function _c(...e){const t={};for(let n=0;nue||le;let Tn,Er;{const e=so(),t=(n,r)=>{let s;return(s=e[n])||(s=e[n]=[]),s.push(r),o=>{s.length>1?s.forEach(i=>i(o)):s[0](o)}};Tn=t("__VUE_INSTANCE_SETTERS__",n=>ue=n),Er=t("__VUE_SSR_SETTERS__",n=>Xt=n)}const zt=e=>{const t=ue;return Tn(e),e.scope.on(),()=>{e.scope.off(),Tn(t)}},Ts=()=>{ue&&ue.scope.off(),Tn(null)};function ni(e){return e.vnode.shapeFlag&4}let Xt=!1;function Ec(e,t=!1){t&&Er(t);const{props:n,children:r}=e.vnode,s=ni(e);tc(e,n,s,t),sc(e,r);const o=s?Cc(e,t):void 0;return t&&Er(!1),o}function Cc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=Mt(new Proxy(e.ctx,Wl));const{setup:r}=n;if(r){const s=e.setupContext=r.length>1?si(e):null,o=zt(e);dt();const i=Je(r,e,0,[e.props,s]);if(ht(),o(),to(i)){if(i.then(Ts,Ts),t)return i.then(l=>{As(e,l,t)}).catch(l=>{qt(l,e,0)});e.asyncDep=i}else As(e,i,t)}else ri(e,t)}function As(e,t,n){q(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Z(t)&&(e.setupState=xo(t)),ri(e,n)}let Rs;function ri(e,t,n){const r=e.type;if(!e.render){if(!t&&Rs&&!r.render){const s=r.template||Kr(e).template;if(s){const{isCustomElement:o,compilerOptions:i}=e.appContext.config,{delimiters:l,compilerOptions:c}=r,a=ce(ce({isCustomElement:o,delimiters:l},i),c);r.render=Rs(s,a)}}e.render=r.render||xe}{const s=zt(e);dt();try{Gl(e)}finally{ht(),s()}}}function xc(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return ye(e,"get","$attrs"),t[n]}}))}function si(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return xc(e)},slots:e.slots,emit:e.emit,expose:t}}function kn(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(xo(Mt(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Nt)return Nt[n](e)},has(t,n){return n in t||n in Nt}}))}function Sc(e,t=!0){return q(e)?e.displayName||e.name:e.name||t&&e.__name}function Tc(e){return q(e)&&"__vccOpts"in e}const re=(e,t)=>cl(e,t,Xt);function Cr(e,t,n){const r=arguments.length;return r===2?Z(t)&&!B(t)?Sn(t)?oe(e,null,[t]):oe(e,t):oe(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&Sn(n)&&(n=[n]),oe(e,t,n))}const Ac="3.4.21";/** -* @vue/runtime-dom v3.4.21 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/const Rc="http://www.w3.org/2000/svg",Lc="http://www.w3.org/1998/Math/MathML",Xe=typeof document<"u"?document:null,Ls=Xe&&Xe.createElement("template"),Oc={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const s=t==="svg"?Xe.createElementNS(Rc,e):t==="mathml"?Xe.createElementNS(Lc,e):Xe.createElement(e,n?{is:n}:void 0);return e==="select"&&r&&r.multiple!=null&&s.setAttribute("multiple",r.multiple),s},createText:e=>Xe.createTextNode(e),createComment:e=>Xe.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Xe.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,s,o){const i=n?n.previousSibling:t.lastChild;if(s&&(s===o||s.nextSibling))for(;t.insertBefore(s.cloneNode(!0),n),!(s===o||!(s=s.nextSibling)););else{Ls.innerHTML=r==="svg"?`${e}`:r==="mathml"?`${e}`:e;const l=Ls.content;if(r==="svg"||r==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Ke="transition",Ot="animation",Kt=Symbol("_vtc"),oi=(e,{slots:t})=>Cr(Nl,Ic(e),t);oi.displayName="Transition";const ii={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};oi.props=ce({},Po,ii);const rt=(e,t=[])=>{B(e)?e.forEach(n=>n(...t)):e&&e(...t)},Os=e=>e?B(e)?e.some(t=>t.length>1):e.length>1:!1;function Ic(e){const t={};for(const A in e)A in ii||(t[A]=e[A]);if(e.css===!1)return t;const{name:n="v",type:r,duration:s,enterFromClass:o=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=o,appearActiveClass:a=i,appearToClass:f=l,leaveFromClass:h=`${n}-leave-from`,leaveActiveClass:p=`${n}-leave-active`,leaveToClass:y=`${n}-leave-to`}=e,v=Mc(s),I=v&&v[0],N=v&&v[1],{onBeforeEnter:K,onEnter:k,onEnterCancelled:g,onLeave:_,onLeaveCancelled:M,onBeforeAppear:L=K,onAppear:F=k,onAppearCancelled:T=g}=t,$=(A,G,ie)=>{st(A,G?f:l),st(A,G?a:i),ie&&ie()},E=(A,G)=>{A._isLeaving=!1,st(A,h),st(A,y),st(A,p),G&&G()},j=A=>(G,ie)=>{const fe=A?F:k,D=()=>$(G,A,ie);rt(fe,[G,D]),Is(()=>{st(G,A?c:o),We(G,A?f:l),Os(fe)||Ms(G,r,I,D)})};return ce(t,{onBeforeEnter(A){rt(K,[A]),We(A,o),We(A,i)},onBeforeAppear(A){rt(L,[A]),We(A,c),We(A,a)},onEnter:j(!1),onAppear:j(!0),onLeave(A,G){A._isLeaving=!0;const ie=()=>E(A,G);We(A,h),Fc(),We(A,p),Is(()=>{A._isLeaving&&(st(A,h),We(A,y),Os(_)||Ms(A,r,N,ie))}),rt(_,[A,ie])},onEnterCancelled(A){$(A,!1),rt(g,[A])},onAppearCancelled(A){$(A,!0),rt(T,[A])},onLeaveCancelled(A){E(A),rt(M,[A])}})}function Mc(e){if(e==null)return null;if(Z(e))return[Zn(e.enter),Zn(e.leave)];{const t=Zn(e);return[t,t]}}function Zn(e){return Ii(e)}function We(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Kt]||(e[Kt]=new Set)).add(t)}function st(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[Kt];n&&(n.delete(t),n.size||(e[Kt]=void 0))}function Is(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Pc=0;function Ms(e,t,n,r){const s=e._endId=++Pc,o=()=>{s===e._endId&&r()};if(n)return setTimeout(o,n);const{type:i,timeout:l,propCount:c}=Nc(e,t);if(!i)return r();const a=i+"end";let f=0;const h=()=>{e.removeEventListener(a,p),o()},p=y=>{y.target===e&&++f>=c&&h()};setTimeout(()=>{f(n[v]||"").split(", "),s=r(`${Ke}Delay`),o=r(`${Ke}Duration`),i=Ps(s,o),l=r(`${Ot}Delay`),c=r(`${Ot}Duration`),a=Ps(l,c);let f=null,h=0,p=0;t===Ke?i>0&&(f=Ke,h=i,p=o.length):t===Ot?a>0&&(f=Ot,h=a,p=c.length):(h=Math.max(i,a),f=h>0?i>a?Ke:Ot:null,p=f?f===Ke?o.length:c.length:0);const y=f===Ke&&/\b(transform|all)(,|$)/.test(r(`${Ke}Property`).toString());return{type:f,timeout:h,propCount:p,hasTransform:y}}function Ps(e,t){for(;e.lengthNs(n)+Ns(e[r])))}function Ns(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Fc(){return document.body.offsetHeight}function $c(e,t,n){const r=e[Kt];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Fs=Symbol("_vod"),Hc=Symbol("_vsh"),jc=Symbol(""),Vc=/(^|;)\s*display\s*:/;function Dc(e,t,n){const r=e.style,s=ne(n);let o=!1;if(n&&!s){if(t)if(ne(t))for(const i of t.split(";")){const l=i.slice(0,i.indexOf(":")).trim();n[l]==null&&mn(r,l,"")}else for(const i in t)n[i]==null&&mn(r,i,"");for(const i in n)i==="display"&&(o=!0),mn(r,i,n[i])}else if(s){if(t!==n){const i=r[jc];i&&(n+=";"+i),r.cssText=n,o=Vc.test(n)}}else t&&e.removeAttribute("style");Fs in e&&(e[Fs]=o?r.display:"",e[Hc]&&(r.display="none"))}const $s=/\s*!important$/;function mn(e,t,n){if(B(n))n.forEach(r=>mn(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=Uc(e,t);$s.test(n)?e.setProperty(ft(r),n.replace($s,""),"important"):e[r]=n}}const Hs=["Webkit","Moz","ms"],er={};function Uc(e,t){const n=er[t];if(n)return n;let r=Fe(t);if(r!=="filter"&&r in e)return er[t]=r;r=On(r);for(let s=0;str||(Gc.then(()=>tr=0),tr=Date.now());function Xc(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;Se(Yc(r,n.value),t,5,[r])};return n.value=e,n.attached=zc(),n}function Yc(e,t){if(B(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>s=>!s._stopped&&r&&r(s))}else return t}const Us=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Jc=(e,t,n,r,s,o,i,l,c)=>{const a=s==="svg";t==="class"?$c(e,r,a):t==="style"?Dc(e,n,r):Wt(t)?Tr(t)||Wc(e,t,n,r,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Qc(e,t,r,a))?kc(e,t,r,o,i,l,c):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Bc(e,t,r,a))};function Qc(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&Us(t)&&q(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const s=e.tagName;if(s==="IMG"||s==="VIDEO"||s==="CANVAS"||s==="SOURCE")return!1}return Us(t)&&ne(n)?!1:t in e}const Bs=e=>{const t=e.props["onUpdate:modelValue"]||!1;return B(t)?n=>pn(t,n):t};function Zc(e){e.target.composing=!0}function ks(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const nr=Symbol("_assign"),pu={created(e,{modifiers:{lazy:t,trim:n,number:r}},s){e[nr]=Bs(s);const o=r||s.props&&s.props.type==="number";mt(e,t?"change":"input",i=>{if(i.target.composing)return;let l=e.value;n&&(l=l.trim()),o&&(l=ur(l)),e[nr](l)}),n&&mt(e,"change",()=>{e.value=e.value.trim()}),t||(mt(e,"compositionstart",Zc),mt(e,"compositionend",ks),mt(e,"change",ks))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,modifiers:{lazy:n,trim:r,number:s}},o){if(e[nr]=Bs(o),e.composing)return;const i=s||e.type==="number"?ur(e.value):e.value,l=t??"";i!==l&&(document.activeElement===e&&e.type!=="range"&&(n||r&&e.value.trim()===l)||(e.value=l))}},ea=["ctrl","shift","alt","meta"],ta={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>ea.some(n=>e[`${n}Key`]&&!t.includes(n))},gu=(e,t)=>{const n=e._withMods||(e._withMods={}),r=t.join(".");return n[r]||(n[r]=(s,...o)=>{for(let i=0;i{const n=e._withKeys||(e._withKeys={}),r=t.join(".");return n[r]||(n[r]=s=>{if(!("key"in s))return;const o=ft(s.key);if(t.some(i=>i===o||na[i]===o))return e(s)})},li=ce({patchProp:Jc},Oc);let Vt,Ks=!1;function ra(){return Vt||(Vt=ac(li))}function sa(){return Vt=Ks?Vt:uc(li),Ks=!0,Vt}const yu=(...e)=>{const t=ra().createApp(...e),{mount:n}=t;return t.mount=r=>{const s=ai(r);if(!s)return;const o=t._component;!q(o)&&!o.render&&!o.template&&(o.template=s.innerHTML),s.innerHTML="";const i=n(s,!1,ci(s));return s instanceof Element&&(s.removeAttribute("v-cloak"),s.setAttribute("data-v-app","")),i},t},_u=(...e)=>{const t=sa().createApp(...e),{mount:n}=t;return t.mount=r=>{const s=ai(r);if(s)return n(s,!0,ci(s))},t};function ci(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function ai(e){return ne(e)?document.querySelector(e):e}const vu=(e,t)=>{const n=e.__vccOpts||e;for(const[r,s]of t)n[r]=s;return n},oa="modulepreload",ia=function(e){return"/dev/"+e},Ws={},bu=function(t,n,r){let s=Promise.resolve();if(n&&n.length>0){const o=document.getElementsByTagName("link"),i=document.querySelector("meta[property=csp-nonce]"),l=(i==null?void 0:i.nonce)||(i==null?void 0:i.getAttribute("nonce"));s=Promise.all(n.map(c=>{if(c=ia(c),c in Ws)return;Ws[c]=!0;const a=c.endsWith(".css"),f=a?'[rel="stylesheet"]':"";if(!!r)for(let y=o.length-1;y>=0;y--){const v=o[y];if(v.href===c&&(!a||v.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${c}"]${f}`))return;const p=document.createElement("link");if(p.rel=a?"stylesheet":oa,a||(p.as="script",p.crossOrigin=""),p.href=c,l&&p.setAttribute("nonce",l),document.head.appendChild(p),a)return new Promise((y,v)=>{p.addEventListener("load",y),p.addEventListener("error",()=>v(new Error(`Unable to preload CSS for ${c}`)))})}))}return s.then(()=>t()).catch(o=>{const i=new Event("vite:preloadError",{cancelable:!0});if(i.payload=o,window.dispatchEvent(i),!i.defaultPrevented)throw o})},la=window.__VP_SITE_DATA__;function zr(e){return lo()?(Di(e),!0):!1}function Ne(e){return typeof e=="function"?e():Co(e)}const ui=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const ca=Object.prototype.toString,aa=e=>ca.call(e)==="[object Object]",Qe=()=>{},xr=ua();function ua(){var e,t;return ui&&((e=window==null?void 0:window.navigator)==null?void 0:e.userAgent)&&(/iP(ad|hone|od)/.test(window.navigator.userAgent)||((t=window==null?void 0:window.navigator)==null?void 0:t.maxTouchPoints)>2&&/iPad|Macintosh/.test(window==null?void 0:window.navigator.userAgent))}function fa(e,t){function n(...r){return new Promise((s,o)=>{Promise.resolve(e(()=>t.apply(this,r),{fn:t,thisArg:this,args:r})).then(s).catch(o)})}return n}const fi=e=>e();function da(e,t={}){let n,r,s=Qe;const o=l=>{clearTimeout(l),s(),s=Qe};return l=>{const c=Ne(e),a=Ne(t.maxWait);return n&&o(n),c<=0||a!==void 0&&a<=0?(r&&(o(r),r=null),Promise.resolve(l())):new Promise((f,h)=>{s=t.rejectOnCancel?h:f,a&&!r&&(r=setTimeout(()=>{n&&o(n),r=null,f(l())},a)),n=setTimeout(()=>{r&&o(r),r=null,f(l())},c)})}}function ha(e=fi){const t=se(!0);function n(){t.value=!1}function r(){t.value=!0}const s=(...o)=>{t.value&&e(...o)};return{isActive:Pn(t),pause:n,resume:r,eventFilter:s}}function pa(e){return e||Bn()}function di(...e){if(e.length!==1)return gl(...e);const t=e[0];return typeof t=="function"?Pn(dl(()=>({get:t,set:Qe}))):se(t)}function hi(e,t,n={}){const{eventFilter:r=fi,...s}=n;return Ve(e,fa(r,t),s)}function ga(e,t,n={}){const{eventFilter:r,...s}=n,{eventFilter:o,pause:i,resume:l,isActive:c}=ha(r);return{stop:hi(e,t,{...s,eventFilter:o}),pause:i,resume:l,isActive:c}}function Xr(e,t=!0,n){pa()?Rt(e,n):t?e():Nn(e)}function wu(e,t,n={}){const{debounce:r=0,maxWait:s=void 0,...o}=n;return hi(e,t,{...o,eventFilter:da(r,{maxWait:s})})}function Eu(e,t,n){let r;de(n)?r={evaluating:n}:r=n||{};const{lazy:s=!1,evaluating:o=void 0,shallow:i=!0,onError:l=Qe}=r,c=se(!s),a=i?Vr(t):se(t);let f=0;return Br(async h=>{if(!c.value)return;f++;const p=f;let y=!1;o&&Promise.resolve().then(()=>{o.value=!0});try{const v=await e(I=>{h(()=>{o&&(o.value=!1),y||I()})});p===f&&(a.value=v)}catch(v){l(v)}finally{o&&p===f&&(o.value=!1),y=!0}}),s?re(()=>(c.value=!0,a.value)):a}function yt(e){var t;const n=Ne(e);return(t=n==null?void 0:n.$el)!=null?t:n}const Te=ui?window:void 0;function De(...e){let t,n,r,s;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,r,s]=e,t=Te):[t,n,r,s]=e,!t)return Qe;Array.isArray(n)||(n=[n]),Array.isArray(r)||(r=[r]);const o=[],i=()=>{o.forEach(f=>f()),o.length=0},l=(f,h,p,y)=>(f.addEventListener(h,p,y),()=>f.removeEventListener(h,p,y)),c=Ve(()=>[yt(t),Ne(s)],([f,h])=>{if(i(),!f)return;const p=aa(h)?{...h}:h;o.push(...n.flatMap(y=>r.map(v=>l(f,y,v,p))))},{immediate:!0,flush:"post"}),a=()=>{c(),i()};return zr(a),a}let qs=!1;function Cu(e,t,n={}){const{window:r=Te,ignore:s=[],capture:o=!0,detectIframe:i=!1}=n;if(!r)return Qe;xr&&!qs&&(qs=!0,Array.from(r.document.body.children).forEach(p=>p.addEventListener("click",Qe)),r.document.documentElement.addEventListener("click",Qe));let l=!0;const c=p=>s.some(y=>{if(typeof y=="string")return Array.from(r.document.querySelectorAll(y)).some(v=>v===p.target||p.composedPath().includes(v));{const v=yt(y);return v&&(p.target===v||p.composedPath().includes(v))}}),f=[De(r,"click",p=>{const y=yt(e);if(!(!y||y===p.target||p.composedPath().includes(y))){if(p.detail===0&&(l=!c(p)),!l){l=!0;return}t(p)}},{passive:!0,capture:o}),De(r,"pointerdown",p=>{const y=yt(e);l=!c(p)&&!!(y&&!p.composedPath().includes(y))},{passive:!0}),i&&De(r,"blur",p=>{setTimeout(()=>{var y;const v=yt(e);((y=r.document.activeElement)==null?void 0:y.tagName)==="IFRAME"&&!(v!=null&&v.contains(r.document.activeElement))&&t(p)},0)})].filter(Boolean);return()=>f.forEach(p=>p())}function ma(e){return typeof e=="function"?e:typeof e=="string"?t=>t.key===e:Array.isArray(e)?t=>e.includes(t.key):()=>!0}function xu(...e){let t,n,r={};e.length===3?(t=e[0],n=e[1],r=e[2]):e.length===2?typeof e[1]=="object"?(t=!0,n=e[0],r=e[1]):(t=e[0],n=e[1]):(t=!0,n=e[0]);const{target:s=Te,eventName:o="keydown",passive:i=!1,dedupe:l=!1}=r,c=ma(t);return De(s,o,f=>{f.repeat&&Ne(l)||c(f)&&n(f)},i)}function ya(){const e=se(!1),t=Bn();return t&&Rt(()=>{e.value=!0},t),e}function _a(e){const t=ya();return re(()=>(t.value,!!e()))}function pi(e,t={}){const{window:n=Te}=t,r=_a(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let s;const o=se(!1),i=a=>{o.value=a.matches},l=()=>{s&&("removeEventListener"in s?s.removeEventListener("change",i):s.removeListener(i))},c=Br(()=>{r.value&&(l(),s=n.matchMedia(Ne(e)),"addEventListener"in s?s.addEventListener("change",i):s.addListener(i),o.value=s.matches)});return zr(()=>{c(),l(),s=void 0}),o}const an=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},un="__vueuse_ssr_handlers__",va=ba();function ba(){return un in an||(an[un]=an[un]||{}),an[un]}function gi(e,t){return va[e]||t}function wa(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const Ea={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},Gs="vueuse-storage";function Yr(e,t,n,r={}){var s;const{flush:o="pre",deep:i=!0,listenToStorageChanges:l=!0,writeDefaults:c=!0,mergeDefaults:a=!1,shallow:f,window:h=Te,eventFilter:p,onError:y=E=>{console.error(E)},initOnMounted:v}=r,I=(f?Vr:se)(typeof t=="function"?t():t);if(!n)try{n=gi("getDefaultStorage",()=>{var E;return(E=Te)==null?void 0:E.localStorage})()}catch(E){y(E)}if(!n)return I;const N=Ne(t),K=wa(N),k=(s=r.serializer)!=null?s:Ea[K],{pause:g,resume:_}=ga(I,()=>L(I.value),{flush:o,deep:i,eventFilter:p});h&&l&&Xr(()=>{De(h,"storage",T),De(h,Gs,$),v&&T()}),v||T();function M(E,j){h&&h.dispatchEvent(new CustomEvent(Gs,{detail:{key:e,oldValue:E,newValue:j,storageArea:n}}))}function L(E){try{const j=n.getItem(e);if(E==null)M(j,null),n.removeItem(e);else{const A=k.write(E);j!==A&&(n.setItem(e,A),M(j,A))}}catch(j){y(j)}}function F(E){const j=E?E.newValue:n.getItem(e);if(j==null)return c&&N!=null&&n.setItem(e,k.write(N)),N;if(!E&&a){const A=k.read(j);return typeof a=="function"?a(A,N):K==="object"&&!Array.isArray(A)?{...N,...A}:A}else return typeof j!="string"?j:k.read(j)}function T(E){if(!(E&&E.storageArea!==n)){if(E&&E.key==null){I.value=N;return}if(!(E&&E.key!==e)){g();try{(E==null?void 0:E.newValue)!==k.write(I.value)&&(I.value=F(E))}catch(j){y(j)}finally{E?Nn(_):_()}}}}function $(E){T(E.detail)}return I}function mi(e){return pi("(prefers-color-scheme: dark)",e)}function Ca(e={}){const{selector:t="html",attribute:n="class",initialValue:r="auto",window:s=Te,storage:o,storageKey:i="vueuse-color-scheme",listenToStorageChanges:l=!0,storageRef:c,emitAuto:a,disableTransition:f=!0}=e,h={auto:"",light:"light",dark:"dark",...e.modes||{}},p=mi({window:s}),y=re(()=>p.value?"dark":"light"),v=c||(i==null?di(r):Yr(i,r,o,{window:s,listenToStorageChanges:l})),I=re(()=>v.value==="auto"?y.value:v.value),N=gi("updateHTMLAttrs",(_,M,L)=>{const F=typeof _=="string"?s==null?void 0:s.document.querySelector(_):yt(_);if(!F)return;let T;if(f&&(T=s.document.createElement("style"),T.appendChild(document.createTextNode("*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}")),s.document.head.appendChild(T)),M==="class"){const $=L.split(/\s/g);Object.values(h).flatMap(E=>(E||"").split(/\s/g)).filter(Boolean).forEach(E=>{$.includes(E)?F.classList.add(E):F.classList.remove(E)})}else F.setAttribute(M,L);f&&(s.getComputedStyle(T).opacity,document.head.removeChild(T))});function K(_){var M;N(t,n,(M=h[_])!=null?M:_)}function k(_){e.onChanged?e.onChanged(_,K):K(_)}Ve(I,k,{flush:"post",immediate:!0}),Xr(()=>k(I.value));const g=re({get(){return a?v.value:I.value},set(_){v.value=_}});try{return Object.assign(g,{store:v,system:y,state:I})}catch{return g}}function xa(e={}){const{valueDark:t="dark",valueLight:n="",window:r=Te}=e,s=Ca({...e,onChanged:(l,c)=>{var a;e.onChanged?(a=e.onChanged)==null||a.call(e,l==="dark",c,l):c(l)},modes:{dark:t,light:n}}),o=re(()=>s.system?s.system.value:mi({window:r}).value?"dark":"light");return re({get(){return s.value==="dark"},set(l){const c=l?"dark":"light";o.value===c?s.value="auto":s.value=c}})}function rr(e){return typeof Window<"u"&&e instanceof Window?e.document.documentElement:typeof Document<"u"&&e instanceof Document?e.documentElement:e}function Su(e,t,n={}){const{window:r=Te}=n;return Yr(e,t,r==null?void 0:r.localStorage,n)}function yi(e){const t=window.getComputedStyle(e);if(t.overflowX==="scroll"||t.overflowY==="scroll"||t.overflowX==="auto"&&e.clientWidth1?!0:(t.preventDefault&&t.preventDefault(),!1)}const fn=new WeakMap;function Tu(e,t=!1){const n=se(t);let r=null;Ve(di(e),i=>{const l=rr(Ne(i));if(l){const c=l;fn.get(c)||fn.set(c,c.style.overflow),n.value&&(c.style.overflow="hidden")}},{immediate:!0});const s=()=>{const i=rr(Ne(e));!i||n.value||(xr&&(r=De(i,"touchmove",l=>{Sa(l)},{passive:!1})),i.style.overflow="hidden",n.value=!0)},o=()=>{var i;const l=rr(Ne(e));!l||!n.value||(xr&&(r==null||r()),l.style.overflow=(i=fn.get(l))!=null?i:"",fn.delete(l),n.value=!1)};return zr(o),re({get(){return n.value},set(i){i?s():o()}})}function Au(e,t,n={}){const{window:r=Te}=n;return Yr(e,t,r==null?void 0:r.sessionStorage,n)}function Ru(e={}){const{window:t=Te,behavior:n="auto"}=e;if(!t)return{x:se(0),y:se(0)};const r=se(t.scrollX),s=se(t.scrollY),o=re({get(){return r.value},set(l){scrollTo({left:l,behavior:n})}}),i=re({get(){return s.value},set(l){scrollTo({top:l,behavior:n})}});return De(t,"scroll",()=>{r.value=t.scrollX,s.value=t.scrollY},{capture:!1,passive:!0}),{x:o,y:i}}function Lu(e={}){const{window:t=Te,initialWidth:n=Number.POSITIVE_INFINITY,initialHeight:r=Number.POSITIVE_INFINITY,listenOrientation:s=!0,includeScrollbar:o=!0}=e,i=se(n),l=se(r),c=()=>{t&&(o?(i.value=t.innerWidth,l.value=t.innerHeight):(i.value=t.document.documentElement.clientWidth,l.value=t.document.documentElement.clientHeight))};if(c(),Xr(c),De("resize",c,{passive:!0}),s){const a=pi("(orientation: portrait)");Ve(a,()=>c())}return{width:i,height:l}}var sr={BASE_URL:"/dev/",MODE:"production",DEV:!1,PROD:!0,SSR:!1},or={};const _i=/^(?:[a-z]+:|\/\/)/i,Ta="vitepress-theme-appearance",Aa=/#.*$/,Ra=/[?#].*$/,La=/(?:(^|\/)index)?\.(?:md|html)$/,Ce=typeof document<"u",vi={relativePath:"",filePath:"",title:"404",description:"Not Found",headers:[],frontmatter:{sidebar:!1,layout:"page"},lastUpdated:0,isNotFound:!0};function Oa(e,t,n=!1){if(t===void 0)return!1;if(e=zs(`/${e}`),n)return new RegExp(t).test(e);if(zs(t)!==e)return!1;const r=t.match(Aa);return r?(Ce?location.hash:"")===r[0]:!0}function zs(e){return decodeURI(e).replace(Ra,"").replace(La,"$1")}function Ia(e){return _i.test(e)}function Ma(e,t){var r,s,o,i,l,c,a;const n=Object.keys(e.locales).find(f=>f!=="root"&&!Ia(f)&&Oa(t,`/${f}/`,!0))||"root";return Object.assign({},e,{localeIndex:n,lang:((r=e.locales[n])==null?void 0:r.lang)??e.lang,dir:((s=e.locales[n])==null?void 0:s.dir)??e.dir,title:((o=e.locales[n])==null?void 0:o.title)??e.title,titleTemplate:((i=e.locales[n])==null?void 0:i.titleTemplate)??e.titleTemplate,description:((l=e.locales[n])==null?void 0:l.description)??e.description,head:wi(e.head,((c=e.locales[n])==null?void 0:c.head)??[]),themeConfig:{...e.themeConfig,...(a=e.locales[n])==null?void 0:a.themeConfig}})}function bi(e,t){const n=t.title||e.title,r=t.titleTemplate??e.titleTemplate;if(typeof r=="string"&&r.includes(":title"))return r.replace(/:title/g,n);const s=Pa(e.title,r);return n===s.slice(3)?n:`${n}${s}`}function Pa(e,t){return t===!1?"":t===!0||t===void 0?` | ${e}`:e===t?"":` | ${t}`}function Na(e,t){const[n,r]=t;if(n!=="meta")return!1;const s=Object.entries(r)[0];return s==null?!1:e.some(([o,i])=>o===n&&i[s[0]]===s[1])}function wi(e,t){return[...e.filter(n=>!Na(t,n)),...t]}const Fa=/[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g,$a=/^[a-z]:/i;function Xs(e){const t=$a.exec(e),n=t?t[0]:"";return n+e.slice(n.length).replace(Fa,"_").replace(/(^|\/)_+(?=[^/]*$)/,"$1")}const ir=new Set;function Ha(e){if(ir.size===0){const n=typeof process=="object"&&(or==null?void 0:or.VITE_EXTRA_EXTENSIONS)||(sr==null?void 0:sr.VITE_EXTRA_EXTENSIONS)||"";("3g2,3gp,aac,ai,apng,au,avif,bin,bmp,cer,class,conf,crl,css,csv,dll,doc,eps,epub,exe,gif,gz,ics,ief,jar,jpe,jpeg,jpg,js,json,jsonld,m4a,man,mid,midi,mjs,mov,mp2,mp3,mp4,mpe,mpeg,mpg,mpp,oga,ogg,ogv,ogx,opus,otf,p10,p7c,p7m,p7s,pdf,png,ps,qt,roff,rtf,rtx,ser,svg,t,tif,tiff,tr,ts,tsv,ttf,txt,vtt,wav,weba,webm,webp,woff,woff2,xhtml,xml,yaml,yml,zip"+(n&&typeof n=="string"?","+n:"")).split(",").forEach(r=>ir.add(r))}const t=e.split(".").pop();return t==null||!ir.has(t.toLowerCase())}function Ou(e){return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}const ja=Symbol(),ut=Vr(la);function Iu(e){const t=re(()=>Ma(ut.value,e.data.relativePath)),n=t.value.appearance,r=n==="force-dark"?se(!0):n?xa({storageKey:Ta,initialValue:()=>typeof n=="string"?n:"auto",...typeof n=="object"?n:{}}):se(!1);return{site:t,theme:re(()=>t.value.themeConfig),page:re(()=>e.data),frontmatter:re(()=>e.data.frontmatter),params:re(()=>e.data.params),lang:re(()=>t.value.lang),dir:re(()=>e.data.frontmatter.dir||t.value.dir),localeIndex:re(()=>t.value.localeIndex||"root"),title:re(()=>bi(t.value,e.data)),description:re(()=>e.data.description||t.value.description),isDark:r}}function Va(){const e=xt(ja);if(!e)throw new Error("vitepress data not properly injected in app");return e}function Da(e,t){return`${e}${t}`.replace(/\/+/g,"/")}function Ys(e){return _i.test(e)||!e.startsWith("/")?e:Da(ut.value.base,e)}function Ua(e){let t=e.replace(/\.html$/,"");if(t=decodeURIComponent(t),t=t.replace(/\/$/,"/index"),Ce){const n="/dev/";t=Xs(t.slice(n.length).replace(/\//g,"_")||"index")+".md";let r=__VP_HASH_MAP__[t.toLowerCase()];if(r||(t=t.endsWith("_index.md")?t.slice(0,-9)+".md":t.slice(0,-3)+"_index.md",r=__VP_HASH_MAP__[t.toLowerCase()]),!r)return null;t=`${n}assets/${t}.${r}.js`}else t=`./${Xs(t.slice(1).replace(/\//g,"_"))}.md.js`;return t}let yn=[];function Mu(e){yn.push(e),Dn(()=>{yn=yn.filter(t=>t!==e)})}function Ba(){let e=ut.value.scrollOffset,t=0,n=24;if(typeof e=="object"&&"padding"in e&&(n=e.padding,e=e.selector),typeof e=="number")t=e;else if(typeof e=="string")t=Js(e,n);else if(Array.isArray(e))for(const r of e){const s=Js(r,n);if(s){t=s;break}}return t}function Js(e,t){const n=document.querySelector(e);if(!n)return 0;const r=n.getBoundingClientRect().bottom;return r<0?0:r+t}const ka=Symbol(),Jr="http://a.com",Ka=()=>({path:"/",component:null,data:vi});function Pu(e,t){const n=Mn(Ka()),r={route:n,go:s};async function s(l=Ce?location.href:"/"){var c,a;l=An(l),await((c=r.onBeforeRouteChange)==null?void 0:c.call(r,l))!==!1&&(Zs(l),await i(l),await((a=r.onAfterRouteChanged)==null?void 0:a.call(r,l)))}let o=null;async function i(l,c=0,a=!1){var p;if(await((p=r.onBeforePageLoad)==null?void 0:p.call(r,l))===!1)return;const f=new URL(l,Jr),h=o=f.pathname;try{let y=await e(h);if(!y)throw new Error(`Page not found: ${h}`);if(o===h){o=null;const{default:v,__pageData:I}=y;if(!v)throw new Error(`Invalid route component: ${v}`);n.path=Ce?h:Ys(h),n.component=Mt(v),n.data=Mt(I),Ce&&Nn(()=>{let N=ut.value.base+I.relativePath.replace(/(?:(^|\/)index)?\.md$/,"$1");if(!ut.value.cleanUrls&&!N.endsWith("/")&&(N+=".html"),N!==f.pathname&&(f.pathname=N,l=N+f.search+f.hash,history.replaceState(null,"",l)),f.hash&&!c){let K=null;try{K=document.getElementById(decodeURIComponent(f.hash).slice(1))}catch(k){console.warn(k)}if(K){Qs(K,f.hash);return}}window.scrollTo(0,c)})}}catch(y){if(!/fetch|Page not found/.test(y.message)&&!/^\/404(\.html|\/)?$/.test(l)&&console.error(y),!a)try{const v=await fetch(ut.value.base+"hashmap.json");window.__VP_HASH_MAP__=await v.json(),await i(l,c,!0);return}catch{}o===h&&(o=null,n.path=Ce?h:Ys(h),n.component=t?Mt(t):null,n.data=vi)}}return Ce&&(window.addEventListener("click",l=>{if(l.target.closest("button"))return;const a=l.target.closest("a");if(a&&!a.closest(".vp-raw")&&(a instanceof SVGElement||!a.download)){const{target:f}=a,{href:h,origin:p,pathname:y,hash:v,search:I}=new URL(a.href instanceof SVGAnimatedString?a.href.animVal:a.href,a.baseURI),N=new URL(window.location.href);!l.ctrlKey&&!l.shiftKey&&!l.altKey&&!l.metaKey&&!f&&p===N.origin&&Ha(y)&&(l.preventDefault(),y===N.pathname&&I===N.search?(v!==N.hash&&(history.pushState(null,"",v),window.dispatchEvent(new Event("hashchange"))),v?Qs(a,v,a.classList.contains("header-anchor")):(Zs(h,!1),window.scrollTo(0,0))):s(h))}},{capture:!0}),window.addEventListener("popstate",async l=>{var c;await i(An(location.href),l.state&&l.state.scrollPosition||0),(c=r.onAfterRouteChanged)==null||c.call(r,location.href)}),window.addEventListener("hashchange",l=>{l.preventDefault()})),r}function Wa(){const e=xt(ka);if(!e)throw new Error("useRouter() is called without provider.");return e}function Ei(){return Wa().route}function Qs(e,t,n=!1){let r=null;try{r=e.classList.contains("header-anchor")?e:document.getElementById(decodeURIComponent(t).slice(1))}catch(s){console.warn(s)}if(r){let s=function(){!n||Math.abs(i-window.scrollY)>window.innerHeight?window.scrollTo(0,i):window.scrollTo({left:0,top:i,behavior:"smooth"})};const o=parseInt(window.getComputedStyle(r).paddingTop,10),i=window.scrollY+r.getBoundingClientRect().top-Ba()+o;requestAnimationFrame(s)}}function Zs(e,t=!0){if(Ce&&An(e)!==An(location.href)){const n=location.hash;history.replaceState({scrollPosition:window.scrollY},document.title),history.pushState(null,"",e),t&&new URL(e,Jr).hash!==n&&window.dispatchEvent(new Event("hashchange"))}}function An(e){const t=new URL(e,Jr);return t.pathname=t.pathname.replace(/(^|\/)index(\.html)?$/,"$1"),ut.value.cleanUrls?t.pathname=t.pathname.replace(/\.html$/,""):!t.pathname.endsWith("/")&&!t.pathname.endsWith(".html")&&(t.pathname+=".html"),t.pathname+t.search+t.hash}const lr=()=>yn.forEach(e=>e()),Nu=kr({name:"VitePressContent",props:{as:{type:[Object,String],default:"div"}},setup(e){const t=Ei(),{site:n}=Va();return()=>Cr(e.as,n.value.contentProps??{style:{position:"relative"}},[t.component?Cr(t.component,{onVnodeMounted:lr,onVnodeUpdated:lr,onVnodeUnmounted:lr}):"404 Page Not Found"])}}),Fu=kr({setup(e,{slots:t}){const n=se(!1);return Rt(()=>{n.value=!0}),()=>n.value&&t.default?t.default():null}});function $u(){Ce&&window.addEventListener("click",e=>{var n;const t=e.target;if(t.matches(".vp-code-group input")){const r=(n=t.parentElement)==null?void 0:n.parentElement;if(!r)return;const s=Array.from(r.querySelectorAll("input")).indexOf(t);if(s<0)return;const o=r.querySelector(".blocks");if(!o)return;const i=Array.from(o.children).find(a=>a.classList.contains("active"));if(!i)return;const l=o.children[s];if(!l||i===l)return;i.classList.remove("active"),l.classList.add("active");const c=r==null?void 0:r.querySelector(`label[for="${t.id}"]`);c==null||c.scrollIntoView({block:"nearest"})}})}function Hu(){if(Ce){const e=new WeakMap;window.addEventListener("click",t=>{var r;const n=t.target;if(n.matches('div[class*="language-"] > button.copy')){const s=n.parentElement,o=(r=n.nextElementSibling)==null?void 0:r.nextElementSibling;if(!s||!o)return;const i=/language-(shellscript|shell|bash|sh|zsh)/.test(s.className),l=[".vp-copy-ignore",".diff.remove"],c=o.cloneNode(!0);c.querySelectorAll(l.join(",")).forEach(f=>f.remove());let a=c.textContent||"";i&&(a=a.replace(/^ *(\$|>) /gm,"").trim()),qa(a).then(()=>{n.classList.add("copied"),clearTimeout(e.get(n));const f=setTimeout(()=>{n.classList.remove("copied"),n.blur(),e.delete(n)},2e3);e.set(n,f)})}})}}async function qa(e){try{return navigator.clipboard.writeText(e)}catch{const t=document.createElement("textarea"),n=document.activeElement;t.value=e,t.setAttribute("readonly",""),t.style.contain="strict",t.style.position="absolute",t.style.left="-9999px",t.style.fontSize="12pt";const r=document.getSelection(),s=r?r.rangeCount>0&&r.getRangeAt(0):null;document.body.appendChild(t),t.select(),t.selectionStart=0,t.selectionEnd=e.length,document.execCommand("copy"),document.body.removeChild(t),s&&(r.removeAllRanges(),r.addRange(s)),n&&n.focus()}}function ju(e,t){let n=!0,r=[];const s=o=>{if(n){n=!1,o.forEach(l=>{const c=cr(l);for(const a of document.head.children)if(a.isEqualNode(c)){r.push(a);return}});return}const i=o.map(cr);r.forEach((l,c)=>{const a=i.findIndex(f=>f==null?void 0:f.isEqualNode(l??null));a!==-1?delete i[a]:(l==null||l.remove(),delete r[c])}),i.forEach(l=>l&&document.head.appendChild(l)),r=[...r,...i].filter(Boolean)};Br(()=>{const o=e.data,i=t.value,l=o&&o.description,c=o&&o.frontmatter.head||[],a=bi(i,o);a!==document.title&&(document.title=a);const f=l||i.description;let h=document.querySelector("meta[name=description]");h?h.getAttribute("content")!==f&&h.setAttribute("content",f):cr(["meta",{name:"description",content:f}]),s(wi(i.head,za(c)))})}function cr([e,t,n]){const r=document.createElement(e);for(const s in t)r.setAttribute(s,t[s]);return n&&(r.innerHTML=n),e==="script"&&!t.async&&(r.async=!1),r}function Ga(e){return e[0]==="meta"&&e[1]&&e[1].name==="description"}function za(e){return e.filter(t=>!Ga(t))}const ar=new Set,Ci=()=>document.createElement("link"),Xa=e=>{const t=Ci();t.rel="prefetch",t.href=e,document.head.appendChild(t)},Ya=e=>{const t=new XMLHttpRequest;t.open("GET",e,t.withCredentials=!0),t.send()};let dn;const Ja=Ce&&(dn=Ci())&&dn.relList&&dn.relList.supports&&dn.relList.supports("prefetch")?Xa:Ya;function Vu(){if(!Ce||!window.IntersectionObserver)return;let e;if((e=navigator.connection)&&(e.saveData||/2g/.test(e.effectiveType)))return;const t=window.requestIdleCallback||setTimeout;let n=null;const r=()=>{n&&n.disconnect(),n=new IntersectionObserver(o=>{o.forEach(i=>{if(i.isIntersecting){const l=i.target;n.unobserve(l);const{pathname:c}=l;if(!ar.has(c)){ar.add(c);const a=Ua(c);a&&Ja(a)}}})}),t(()=>{document.querySelectorAll("#app a").forEach(o=>{const{hostname:i,pathname:l}=new URL(o.href instanceof SVGAnimatedString?o.href.animVal:o.href,o.baseURI),c=l.match(/\.\w+$/);c&&c[0]!==".html"||o.target!=="_blank"&&i===location.hostname&&(l!==location.pathname?n.observe(o):ar.add(l))})})};Rt(r);const s=Ei();Ve(()=>s.path,r),Dn(()=>{n&&n.disconnect()})}export{ec as $,Dn as A,ru as B,Dl as C,Ba as D,tu as E,me as F,iu as G,Vr as H,Mu as I,oe as J,nu as K,_i as L,Ei as M,_c as N,xt as O,Lu as P,Lr as Q,Cu as R,xu as S,oi as T,Nn as U,Ru as V,Pn as W,ou as X,bu as Y,Tu as Z,vu as _,ti as a,mu as a0,cu as a1,gu as a2,au as a3,Mn as a4,gl as a5,Cr as a6,du as a7,ju as a8,ka as a9,Ou as aA,Iu as aa,ja as ab,Nu as ac,Fu as ad,ut as ae,_u as af,Pu as ag,Ua as ah,Vu as ai,Hu as aj,$u as ak,yt as al,zr as am,Eu as an,Au as ao,Su as ap,wu as aq,Wa as ar,De as as,Ho as at,su as au,pu as av,de as aw,uu as ax,Mt as ay,yu as az,Qo as b,fu as c,kr as d,hu as e,Ha as f,Ys as g,se as h,Ia as i,Ce as j,re as k,Rt as l,ei as m,Or as n,Yo as o,Co as p,Za as q,lu as r,eu as s,Qa as t,Va as u,Oa as v,Cl as w,pi as x,Ve as y,Br as z}; diff --git a/dev/assets/chunks/theme.DQqwdnSU.js b/dev/assets/chunks/theme.DQqwdnSU.js deleted file mode 100644 index 007d582..0000000 --- a/dev/assets/chunks/theme.DQqwdnSU.js +++ /dev/null @@ -1,2 +0,0 @@ -const __vite__fileDeps=["assets/chunks/VPLocalSearchBox.B9WZ723L.js","assets/chunks/framework.aA95Gx5L.js"],__vite__mapDeps=i=>i.map(i=>__vite__fileDeps[i]); -import{d as _,o as a,c as u,r as c,n as N,a as D,t as T,b as y,w as p,T as pe,e as f,_ as $,u as Ye,i as Xe,f as Qe,g as he,h as w,j as q,k as g,l as j,m as h,p as r,q as B,s as H,v as z,x as le,y as G,z as te,A as fe,B as Te,C as Ze,D as xe,E as K,F as M,G as E,H as we,I as se,J as b,K as W,L as Ie,M as oe,N as Z,O as J,P as et,Q as Ne,R as tt,S as ce,U as Me,V as Ae,W as st,X as ot,Y as nt,Z as Ce,$ as _e,a0 as at,a1 as rt,a2 as it,a3 as Be,a4 as lt,a5 as ct,a6 as ut}from"./framework.aA95Gx5L.js";const dt=_({__name:"VPBadge",props:{text:{},type:{default:"tip"}},setup(s){return(t,e)=>(a(),u("span",{class:N(["VPBadge",t.type])},[c(t.$slots,"default",{},()=>[D(T(t.text),1)])],2))}}),vt={key:0,class:"VPBackdrop"},pt=_({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(s){return(t,e)=>(a(),y(pe,{name:"fade"},{default:p(()=>[t.show?(a(),u("div",vt)):f("",!0)]),_:1}))}}),ht=$(pt,[["__scopeId","data-v-b06cdb19"]]),L=Ye;function ft(s,t){let e,o=!1;return()=>{e&&clearTimeout(e),o?e=setTimeout(s,t):(s(),(o=!0)&&setTimeout(()=>o=!1,t))}}function ue(s){return/^\//.test(s)?s:`/${s}`}function me(s){const{pathname:t,search:e,hash:o,protocol:n}=new URL(s,"http://a.com");if(Xe(s)||s.startsWith("#")||!n.startsWith("http")||!Qe(t))return s;const{site:i}=L(),l=t.endsWith("/")||t.endsWith(".html")?s:s.replace(/(?:(^\.+)\/)?.*$/,`$1${t.replace(/(\.md)?$/,i.value.cleanUrls?"":".html")}${e}${o}`);return he(l)}const be=w(q?location.hash:"");q&&window.addEventListener("hashchange",()=>{be.value=location.hash});function X({removeCurrent:s=!0,correspondingLink:t=!1}={}){const{site:e,localeIndex:o,page:n,theme:i}=L(),l=g(()=>{var d,m;return{label:(d=e.value.locales[o.value])==null?void 0:d.label,link:((m=e.value.locales[o.value])==null?void 0:m.link)||(o.value==="root"?"/":`/${o.value}/`)}});return{localeLinks:g(()=>Object.entries(e.value.locales).flatMap(([d,m])=>s&&l.value.label===m.label?[]:{text:m.label,link:_t(m.link||(d==="root"?"/":`/${d}/`),i.value.i18nRouting!==!1&&t,n.value.relativePath.slice(l.value.link.length-1),!e.value.cleanUrls)+be.value})),currentLang:l}}function _t(s,t,e,o){return t?s.replace(/\/$/,"")+ue(e.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,o?".html":"")):s}const mt=s=>(B("data-v-792811ca"),s=s(),H(),s),bt={class:"NotFound"},kt={class:"code"},$t={class:"title"},gt=mt(()=>h("div",{class:"divider"},null,-1)),yt={class:"quote"},Pt={class:"action"},St=["href","aria-label"],Vt=_({__name:"NotFound",setup(s){const{site:t,theme:e}=L(),{localeLinks:o}=X({removeCurrent:!1}),n=w("/");return j(()=>{var l;const i=window.location.pathname.replace(t.value.base,"").replace(/(^.*?\/).*$/,"/$1");o.value.length&&(n.value=((l=o.value.find(({link:v})=>v.startsWith(i)))==null?void 0:l.link)||o.value[0].link)}),(i,l)=>{var v,d,m,P,k;return a(),u("div",bt,[h("p",kt,T(((v=r(e).notFound)==null?void 0:v.code)??"404"),1),h("h1",$t,T(((d=r(e).notFound)==null?void 0:d.title)??"PAGE NOT FOUND"),1),gt,h("blockquote",yt,T(((m=r(e).notFound)==null?void 0:m.quote)??"But if you don't change your direction, and if you keep looking, you may end up where you are heading."),1),h("div",Pt,[h("a",{class:"link",href:r(he)(n.value),"aria-label":((P=r(e).notFound)==null?void 0:P.linkLabel)??"go to home"},T(((k=r(e).notFound)==null?void 0:k.linkText)??"Take me home"),9,St)])])}}}),Lt=$(Vt,[["__scopeId","data-v-792811ca"]]);function He(s,t){if(Array.isArray(s))return x(s);if(s==null)return[];t=ue(t);const e=Object.keys(s).sort((n,i)=>i.split("/").length-n.split("/").length).find(n=>t.startsWith(ue(n))),o=e?s[e]:[];return Array.isArray(o)?x(o):x(o.items,o.base)}function Tt(s){const t=[];let e=0;for(const o in s){const n=s[o];if(n.items){e=t.push(n);continue}t[e]||t.push({items:[]}),t[e].items.push(n)}return t}function wt(s){const t=[];function e(o){for(const n of o)n.text&&n.link&&t.push({text:n.text,link:n.link,docFooterText:n.docFooterText}),n.items&&e(n.items)}return e(s),t}function de(s,t){return Array.isArray(t)?t.some(e=>de(s,e)):z(s,t.link)?!0:t.items?de(s,t.items):!1}function x(s,t){return[...s].map(e=>{const o={...e},n=o.base||t;return n&&o.link&&(o.link=n+o.link),o.items&&(o.items=x(o.items,n)),o})}function O(){const{frontmatter:s,page:t,theme:e}=L(),o=le("(min-width: 960px)"),n=w(!1),i=g(()=>{const C=e.value.sidebar,I=t.value.relativePath;return C?He(C,I):[]}),l=w(i.value);G(i,(C,I)=>{JSON.stringify(C)!==JSON.stringify(I)&&(l.value=i.value)});const v=g(()=>s.value.sidebar!==!1&&l.value.length>0&&s.value.layout!=="home"),d=g(()=>m?s.value.aside==null?e.value.aside==="left":s.value.aside==="left":!1),m=g(()=>s.value.layout==="home"?!1:s.value.aside!=null?!!s.value.aside:e.value.aside!==!1),P=g(()=>v.value&&o.value),k=g(()=>v.value?Tt(l.value):[]);function V(){n.value=!0}function S(){n.value=!1}function A(){n.value?S():V()}return{isOpen:n,sidebar:l,sidebarGroups:k,hasSidebar:v,hasAside:m,leftAside:d,isSidebarEnabled:P,open:V,close:S,toggle:A}}function It(s,t){let e;te(()=>{e=s.value?document.activeElement:void 0}),j(()=>{window.addEventListener("keyup",o)}),fe(()=>{window.removeEventListener("keyup",o)});function o(n){n.key==="Escape"&&s.value&&(t(),e==null||e.focus())}}function Nt(s){const{page:t}=L(),e=w(!1),o=g(()=>s.value.collapsed!=null),n=g(()=>!!s.value.link),i=w(!1),l=()=>{i.value=z(t.value.relativePath,s.value.link)};G([t,s,be],l),j(l);const v=g(()=>i.value?!0:s.value.items?de(t.value.relativePath,s.value.items):!1),d=g(()=>!!(s.value.items&&s.value.items.length));te(()=>{e.value=!!(o.value&&s.value.collapsed)}),Te(()=>{(i.value||v.value)&&(e.value=!1)});function m(){o.value&&(e.value=!e.value)}return{collapsed:e,collapsible:o,isLink:n,isActiveLink:i,hasActiveLink:v,hasChildren:d,toggle:m}}function Mt(){const{hasSidebar:s}=O(),t=le("(min-width: 960px)"),e=le("(min-width: 1280px)");return{isAsideEnabled:g(()=>!e.value&&!t.value?!1:s.value?e.value:t.value)}}const ve=[];function Ee(s){return typeof s.outline=="object"&&!Array.isArray(s.outline)&&s.outline.label||s.outlineTitle||"On this page"}function ke(s){const t=[...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")].filter(e=>e.id&&e.hasChildNodes()).map(e=>{const o=Number(e.tagName[1]);return{element:e,title:At(e),link:"#"+e.id,level:o}});return Ct(t,s)}function At(s){let t="";for(const e of s.childNodes)if(e.nodeType===1){if(e.classList.contains("VPBadge")||e.classList.contains("header-anchor")||e.classList.contains("ignore-header"))continue;t+=e.textContent}else e.nodeType===3&&(t+=e.textContent);return t.trim()}function Ct(s,t){if(t===!1)return[];const e=(typeof t=="object"&&!Array.isArray(t)?t.level:t)||2,[o,n]=typeof e=="number"?[e,e]:e==="deep"?[2,6]:e;s=s.filter(l=>l.level>=o&&l.level<=n),ve.length=0;for(const{element:l,link:v}of s)ve.push({element:l,link:v});const i=[];e:for(let l=0;l=0;d--){const m=s[d];if(m.level{requestAnimationFrame(i),window.addEventListener("scroll",o)}),Ze(()=>{l(location.hash)}),fe(()=>{window.removeEventListener("scroll",o)});function i(){if(!e.value)return;const v=window.scrollY,d=window.innerHeight,m=document.body.offsetHeight,P=Math.abs(v+d-m)<1,k=ve.map(({element:S,link:A})=>({link:A,top:Ht(S)})).filter(({top:S})=>!Number.isNaN(S)).sort((S,A)=>S.top-A.top);if(!k.length){l(null);return}if(v<1){l(null);return}if(P){l(k[k.length-1].link);return}let V=null;for(const{link:S,top:A}of k){if(A>v+xe()+4)break;V=S}l(V)}function l(v){n&&n.classList.remove("active"),v==null?n=null:n=s.value.querySelector(`a[href="${decodeURIComponent(v)}"]`);const d=n;d?(d.classList.add("active"),t.value.style.top=d.offsetTop+39+"px",t.value.style.opacity="1"):(t.value.style.top="33px",t.value.style.opacity="0")}}function Ht(s){let t=0;for(;s!==document.body;){if(s===null)return NaN;t+=s.offsetTop,s=s.offsetParent}return t}const Et=["href","title"],Dt=_({__name:"VPDocOutlineItem",props:{headers:{},root:{type:Boolean}},setup(s){function t({target:e}){const o=e.href.split("#")[1],n=document.getElementById(decodeURIComponent(o));n==null||n.focus({preventScroll:!0})}return(e,o)=>{const n=K("VPDocOutlineItem",!0);return a(),u("ul",{class:N(["VPDocOutlineItem",e.root?"root":"nested"])},[(a(!0),u(M,null,E(e.headers,({children:i,link:l,title:v})=>(a(),u("li",null,[h("a",{class:"outline-link",href:l,onClick:t,title:v},T(v),9,Et),i!=null&&i.length?(a(),y(n,{key:0,headers:i},null,8,["headers"])):f("",!0)]))),256))],2)}}}),De=$(Dt,[["__scopeId","data-v-3f927ebe"]]),Ft=s=>(B("data-v-c14bfc45"),s=s(),H(),s),Ot={class:"content"},Ut={class:"outline-title",role:"heading","aria-level":"2"},jt={"aria-labelledby":"doc-outline-aria-label"},Gt=Ft(()=>h("span",{class:"visually-hidden",id:"doc-outline-aria-label"}," Table of Contents for current page ",-1)),zt=_({__name:"VPDocAsideOutline",setup(s){const{frontmatter:t,theme:e}=L(),o=we([]);se(()=>{o.value=ke(t.value.outline??e.value.outline)});const n=w(),i=w();return Bt(n,i),(l,v)=>(a(),u("div",{class:N(["VPDocAsideOutline",{"has-outline":o.value.length>0}]),ref_key:"container",ref:n,role:"navigation"},[h("div",Ot,[h("div",{class:"outline-marker",ref_key:"marker",ref:i},null,512),h("div",Ut,T(r(Ee)(r(e))),1),h("nav",jt,[Gt,b(De,{headers:o.value,root:!0},null,8,["headers"])])])],2))}}),Kt=$(zt,[["__scopeId","data-v-c14bfc45"]]),Rt={class:"VPDocAsideCarbonAds"},Wt=_({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(s){const t=()=>null;return(e,o)=>(a(),u("div",Rt,[b(r(t),{"carbon-ads":e.carbonAds},null,8,["carbon-ads"])]))}}),qt=s=>(B("data-v-6d7b3c46"),s=s(),H(),s),Jt={class:"VPDocAside"},Yt=qt(()=>h("div",{class:"spacer"},null,-1)),Xt=_({__name:"VPDocAside",setup(s){const{theme:t}=L();return(e,o)=>(a(),u("div",Jt,[c(e.$slots,"aside-top",{},void 0,!0),c(e.$slots,"aside-outline-before",{},void 0,!0),b(Kt),c(e.$slots,"aside-outline-after",{},void 0,!0),Yt,c(e.$slots,"aside-ads-before",{},void 0,!0),r(t).carbonAds?(a(),y(Wt,{key:0,"carbon-ads":r(t).carbonAds},null,8,["carbon-ads"])):f("",!0),c(e.$slots,"aside-ads-after",{},void 0,!0),c(e.$slots,"aside-bottom",{},void 0,!0)]))}}),Qt=$(Xt,[["__scopeId","data-v-6d7b3c46"]]);function Zt(){const{theme:s,page:t}=L();return g(()=>{const{text:e="Edit this page",pattern:o=""}=s.value.editLink||{};let n;return typeof o=="function"?n=o(t.value):n=o.replace(/:path/g,t.value.filePath),{url:n,text:e}})}function xt(){const{page:s,theme:t,frontmatter:e}=L();return g(()=>{var d,m,P,k,V,S,A,C;const o=He(t.value.sidebar,s.value.relativePath),n=wt(o),i=n.findIndex(I=>z(s.value.relativePath,I.link)),l=((d=t.value.docFooter)==null?void 0:d.prev)===!1&&!e.value.prev||e.value.prev===!1,v=((m=t.value.docFooter)==null?void 0:m.next)===!1&&!e.value.next||e.value.next===!1;return{prev:l?void 0:{text:(typeof e.value.prev=="string"?e.value.prev:typeof e.value.prev=="object"?e.value.prev.text:void 0)??((P=n[i-1])==null?void 0:P.docFooterText)??((k=n[i-1])==null?void 0:k.text),link:(typeof e.value.prev=="object"?e.value.prev.link:void 0)??((V=n[i-1])==null?void 0:V.link)},next:v?void 0:{text:(typeof e.value.next=="string"?e.value.next:typeof e.value.next=="object"?e.value.next.text:void 0)??((S=n[i+1])==null?void 0:S.docFooterText)??((A=n[i+1])==null?void 0:A.text),link:(typeof e.value.next=="object"?e.value.next.link:void 0)??((C=n[i+1])==null?void 0:C.link)}}})}const F=_({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(s){const t=s,e=g(()=>t.tag??(t.href?"a":"span")),o=g(()=>t.href&&Ie.test(t.href));return(n,i)=>(a(),y(W(e.value),{class:N(["VPLink",{link:n.href,"vp-external-link-icon":o.value,"no-icon":n.noIcon}]),href:n.href?r(me)(n.href):void 0,target:n.target??(o.value?"_blank":void 0),rel:n.rel??(o.value?"noreferrer":void 0)},{default:p(()=>[c(n.$slots,"default")]),_:3},8,["class","href","target","rel"]))}}),es={class:"VPLastUpdated"},ts=["datetime"],ss=_({__name:"VPDocFooterLastUpdated",setup(s){const{theme:t,page:e,frontmatter:o,lang:n}=L(),i=g(()=>new Date(o.value.lastUpdated??e.value.lastUpdated)),l=g(()=>i.value.toISOString()),v=w("");return j(()=>{te(()=>{var d,m,P;v.value=new Intl.DateTimeFormat((m=(d=t.value.lastUpdated)==null?void 0:d.formatOptions)!=null&&m.forceLocale?n.value:void 0,((P=t.value.lastUpdated)==null?void 0:P.formatOptions)??{dateStyle:"short",timeStyle:"short"}).format(i.value)})}),(d,m)=>{var P;return a(),u("p",es,[D(T(((P=r(t).lastUpdated)==null?void 0:P.text)||r(t).lastUpdatedText||"Last updated")+": ",1),h("time",{datetime:l.value},T(v.value),9,ts)])}}}),os=$(ss,[["__scopeId","data-v-9da12f1d"]]),ns=s=>(B("data-v-87be45d1"),s=s(),H(),s),as={key:0,class:"VPDocFooter"},rs={key:0,class:"edit-info"},is={key:0,class:"edit-link"},ls=ns(()=>h("span",{class:"vpi-square-pen edit-link-icon"},null,-1)),cs={key:1,class:"last-updated"},us={key:1,class:"prev-next"},ds={class:"pager"},vs=["innerHTML"],ps=["innerHTML"],hs={class:"pager"},fs=["innerHTML"],_s=["innerHTML"],ms=_({__name:"VPDocFooter",setup(s){const{theme:t,page:e,frontmatter:o}=L(),n=Zt(),i=xt(),l=g(()=>t.value.editLink&&o.value.editLink!==!1),v=g(()=>e.value.lastUpdated&&o.value.lastUpdated!==!1),d=g(()=>l.value||v.value||i.value.prev||i.value.next);return(m,P)=>{var k,V,S,A;return d.value?(a(),u("footer",as,[c(m.$slots,"doc-footer-before",{},void 0,!0),l.value||v.value?(a(),u("div",rs,[l.value?(a(),u("div",is,[b(F,{class:"edit-link-button",href:r(n).url,"no-icon":!0},{default:p(()=>[ls,D(" "+T(r(n).text),1)]),_:1},8,["href"])])):f("",!0),v.value?(a(),u("div",cs,[b(os)])):f("",!0)])):f("",!0),(k=r(i).prev)!=null&&k.link||(V=r(i).next)!=null&&V.link?(a(),u("nav",us,[h("div",ds,[(S=r(i).prev)!=null&&S.link?(a(),y(F,{key:0,class:"pager-link prev",href:r(i).prev.link},{default:p(()=>{var C;return[h("span",{class:"desc",innerHTML:((C=r(t).docFooter)==null?void 0:C.prev)||"Previous page"},null,8,vs),h("span",{class:"title",innerHTML:r(i).prev.text},null,8,ps)]}),_:1},8,["href"])):f("",!0)]),h("div",hs,[(A=r(i).next)!=null&&A.link?(a(),y(F,{key:0,class:"pager-link next",href:r(i).next.link},{default:p(()=>{var C;return[h("span",{class:"desc",innerHTML:((C=r(t).docFooter)==null?void 0:C.next)||"Next page"},null,8,fs),h("span",{class:"title",innerHTML:r(i).next.text},null,8,_s)]}),_:1},8,["href"])):f("",!0)])])):f("",!0)])):f("",!0)}}}),bs=$(ms,[["__scopeId","data-v-87be45d1"]]),ks=s=>(B("data-v-83890dd9"),s=s(),H(),s),$s={class:"container"},gs=ks(()=>h("div",{class:"aside-curtain"},null,-1)),ys={class:"aside-container"},Ps={class:"aside-content"},Ss={class:"content"},Vs={class:"content-container"},Ls={class:"main"},Ts=_({__name:"VPDoc",setup(s){const{theme:t}=L(),e=oe(),{hasSidebar:o,hasAside:n,leftAside:i}=O(),l=g(()=>e.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(v,d)=>{const m=K("Content");return a(),u("div",{class:N(["VPDoc",{"has-sidebar":r(o),"has-aside":r(n)}])},[c(v.$slots,"doc-top",{},void 0,!0),h("div",$s,[r(n)?(a(),u("div",{key:0,class:N(["aside",{"left-aside":r(i)}])},[gs,h("div",ys,[h("div",Ps,[b(Qt,null,{"aside-top":p(()=>[c(v.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":p(()=>[c(v.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":p(()=>[c(v.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":p(()=>[c(v.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":p(()=>[c(v.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":p(()=>[c(v.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):f("",!0),h("div",Ss,[h("div",Vs,[c(v.$slots,"doc-before",{},void 0,!0),h("main",Ls,[b(m,{class:N(["vp-doc",[l.value,r(t).externalLinkIcon&&"external-link-icon-enabled"]])},null,8,["class"])]),b(bs,null,{"doc-footer-before":p(()=>[c(v.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),c(v.$slots,"doc-after",{},void 0,!0)])])]),c(v.$slots,"doc-bottom",{},void 0,!0)],2)}}}),ws=$(Ts,[["__scopeId","data-v-83890dd9"]]),Is=_({__name:"VPButton",props:{tag:{},size:{default:"medium"},theme:{default:"brand"},text:{},href:{},target:{},rel:{}},setup(s){const t=s,e=g(()=>t.href&&Ie.test(t.href)),o=g(()=>t.tag||t.href?"a":"button");return(n,i)=>(a(),y(W(o.value),{class:N(["VPButton",[n.size,n.theme]]),href:n.href?r(me)(n.href):void 0,target:t.target??(e.value?"_blank":void 0),rel:t.rel??(e.value?"noreferrer":void 0)},{default:p(()=>[D(T(n.text),1)]),_:1},8,["class","href","target","rel"]))}}),Ns=$(Is,[["__scopeId","data-v-14206e74"]]),Ms=["src","alt"],As=_({inheritAttrs:!1,__name:"VPImage",props:{image:{},alt:{}},setup(s){return(t,e)=>{const o=K("VPImage",!0);return t.image?(a(),u(M,{key:0},[typeof t.image=="string"||"src"in t.image?(a(),u("img",Z({key:0,class:"VPImage"},typeof t.image=="string"?t.$attrs:{...t.image,...t.$attrs},{src:r(he)(typeof t.image=="string"?t.image:t.image.src),alt:t.alt??(typeof t.image=="string"?"":t.image.alt||"")}),null,16,Ms)):(a(),u(M,{key:1},[b(o,Z({class:"dark",image:t.image.dark,alt:t.image.alt},t.$attrs),null,16,["image","alt"]),b(o,Z({class:"light",image:t.image.light,alt:t.image.alt},t.$attrs),null,16,["image","alt"])],64))],64)):f("",!0)}}}),ee=$(As,[["__scopeId","data-v-35a7d0b8"]]),Cs=s=>(B("data-v-955009fc"),s=s(),H(),s),Bs={class:"container"},Hs={class:"main"},Es={key:0,class:"name"},Ds=["innerHTML"],Fs=["innerHTML"],Os=["innerHTML"],Us={key:0,class:"actions"},js={key:0,class:"image"},Gs={class:"image-container"},zs=Cs(()=>h("div",{class:"image-bg"},null,-1)),Ks=_({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(s){const t=J("hero-image-slot-exists");return(e,o)=>(a(),u("div",{class:N(["VPHero",{"has-image":e.image||r(t)}])},[h("div",Bs,[h("div",Hs,[c(e.$slots,"home-hero-info-before",{},void 0,!0),c(e.$slots,"home-hero-info",{},()=>[e.name?(a(),u("h1",Es,[h("span",{innerHTML:e.name,class:"clip"},null,8,Ds)])):f("",!0),e.text?(a(),u("p",{key:1,innerHTML:e.text,class:"text"},null,8,Fs)):f("",!0),e.tagline?(a(),u("p",{key:2,innerHTML:e.tagline,class:"tagline"},null,8,Os)):f("",!0)],!0),c(e.$slots,"home-hero-info-after",{},void 0,!0),e.actions?(a(),u("div",Us,[(a(!0),u(M,null,E(e.actions,n=>(a(),u("div",{key:n.link,class:"action"},[b(Ns,{tag:"a",size:"medium",theme:n.theme,text:n.text,href:n.link,target:n.target,rel:n.rel},null,8,["theme","text","href","target","rel"])]))),128))])):f("",!0),c(e.$slots,"home-hero-actions-after",{},void 0,!0)]),e.image||r(t)?(a(),u("div",js,[h("div",Gs,[zs,c(e.$slots,"home-hero-image",{},()=>[e.image?(a(),y(ee,{key:0,class:"image-src",image:e.image},null,8,["image"])):f("",!0)],!0)])])):f("",!0)])],2))}}),Rs=$(Ks,[["__scopeId","data-v-955009fc"]]),Ws=_({__name:"VPHomeHero",setup(s){const{frontmatter:t}=L();return(e,o)=>r(t).hero?(a(),y(Rs,{key:0,class:"VPHomeHero",name:r(t).hero.name,text:r(t).hero.text,tagline:r(t).hero.tagline,image:r(t).hero.image,actions:r(t).hero.actions},{"home-hero-info-before":p(()=>[c(e.$slots,"home-hero-info-before")]),"home-hero-info":p(()=>[c(e.$slots,"home-hero-info")]),"home-hero-info-after":p(()=>[c(e.$slots,"home-hero-info-after")]),"home-hero-actions-after":p(()=>[c(e.$slots,"home-hero-actions-after")]),"home-hero-image":p(()=>[c(e.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):f("",!0)}}),qs=s=>(B("data-v-f5e9645b"),s=s(),H(),s),Js={class:"box"},Ys={key:0,class:"icon"},Xs=["innerHTML"],Qs=["innerHTML"],Zs=["innerHTML"],xs={key:4,class:"link-text"},eo={class:"link-text-value"},to=qs(()=>h("span",{class:"vpi-arrow-right link-text-icon"},null,-1)),so=_({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{},rel:{},target:{}},setup(s){return(t,e)=>(a(),y(F,{class:"VPFeature",href:t.link,rel:t.rel,target:t.target,"no-icon":!0,tag:t.link?"a":"div"},{default:p(()=>[h("article",Js,[typeof t.icon=="object"&&t.icon.wrap?(a(),u("div",Ys,[b(ee,{image:t.icon,alt:t.icon.alt,height:t.icon.height||48,width:t.icon.width||48},null,8,["image","alt","height","width"])])):typeof t.icon=="object"?(a(),y(ee,{key:1,image:t.icon,alt:t.icon.alt,height:t.icon.height||48,width:t.icon.width||48},null,8,["image","alt","height","width"])):t.icon?(a(),u("div",{key:2,class:"icon",innerHTML:t.icon},null,8,Xs)):f("",!0),h("h2",{class:"title",innerHTML:t.title},null,8,Qs),t.details?(a(),u("p",{key:3,class:"details",innerHTML:t.details},null,8,Zs)):f("",!0),t.linkText?(a(),u("div",xs,[h("p",eo,[D(T(t.linkText)+" ",1),to])])):f("",!0)])]),_:1},8,["href","rel","target","tag"]))}}),oo=$(so,[["__scopeId","data-v-f5e9645b"]]),no={key:0,class:"VPFeatures"},ao={class:"container"},ro={class:"items"},io=_({__name:"VPFeatures",props:{features:{}},setup(s){const t=s,e=g(()=>{const o=t.features.length;if(o){if(o===2)return"grid-2";if(o===3)return"grid-3";if(o%3===0)return"grid-6";if(o>3)return"grid-4"}else return});return(o,n)=>o.features?(a(),u("div",no,[h("div",ao,[h("div",ro,[(a(!0),u(M,null,E(o.features,i=>(a(),u("div",{key:i.title,class:N(["item",[e.value]])},[b(oo,{icon:i.icon,title:i.title,details:i.details,link:i.link,"link-text":i.linkText,rel:i.rel,target:i.target},null,8,["icon","title","details","link","link-text","rel","target"])],2))),128))])])])):f("",!0)}}),lo=$(io,[["__scopeId","data-v-d0a190d7"]]),co=_({__name:"VPHomeFeatures",setup(s){const{frontmatter:t}=L();return(e,o)=>r(t).features?(a(),y(lo,{key:0,class:"VPHomeFeatures",features:r(t).features},null,8,["features"])):f("",!0)}}),uo=_({__name:"VPHomeContent",setup(s){const{width:t}=et({includeScrollbar:!1});return(e,o)=>(a(),u("div",{class:"vp-doc container",style:Ne(r(t)?{"--vp-offset":`calc(50% - ${r(t)/2}px)`}:{})},[c(e.$slots,"default",{},void 0,!0)],4))}}),vo=$(uo,[["__scopeId","data-v-c43247eb"]]),po={class:"VPHome"},ho=_({__name:"VPHome",setup(s){const{frontmatter:t}=L();return(e,o)=>{const n=K("Content");return a(),u("div",po,[c(e.$slots,"home-hero-before",{},void 0,!0),b(Ws,null,{"home-hero-info-before":p(()=>[c(e.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":p(()=>[c(e.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":p(()=>[c(e.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":p(()=>[c(e.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":p(()=>[c(e.$slots,"home-hero-image",{},void 0,!0)]),_:3}),c(e.$slots,"home-hero-after",{},void 0,!0),c(e.$slots,"home-features-before",{},void 0,!0),b(co),c(e.$slots,"home-features-after",{},void 0,!0),r(t).markdownStyles!==!1?(a(),y(vo,{key:0},{default:p(()=>[b(n)]),_:1})):(a(),y(n,{key:1}))])}}}),fo=$(ho,[["__scopeId","data-v-cbb6ec48"]]),_o={},mo={class:"VPPage"};function bo(s,t){const e=K("Content");return a(),u("div",mo,[c(s.$slots,"page-top"),b(e),c(s.$slots,"page-bottom")])}const ko=$(_o,[["render",bo]]),$o=_({__name:"VPContent",setup(s){const{page:t,frontmatter:e}=L(),{hasSidebar:o}=O();return(n,i)=>(a(),u("div",{class:N(["VPContent",{"has-sidebar":r(o),"is-home":r(e).layout==="home"}]),id:"VPContent"},[r(t).isNotFound?c(n.$slots,"not-found",{key:0},()=>[b(Lt)],!0):r(e).layout==="page"?(a(),y(ko,{key:1},{"page-top":p(()=>[c(n.$slots,"page-top",{},void 0,!0)]),"page-bottom":p(()=>[c(n.$slots,"page-bottom",{},void 0,!0)]),_:3})):r(e).layout==="home"?(a(),y(fo,{key:2},{"home-hero-before":p(()=>[c(n.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":p(()=>[c(n.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":p(()=>[c(n.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":p(()=>[c(n.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":p(()=>[c(n.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":p(()=>[c(n.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":p(()=>[c(n.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":p(()=>[c(n.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":p(()=>[c(n.$slots,"home-features-after",{},void 0,!0)]),_:3})):r(e).layout&&r(e).layout!=="doc"?(a(),y(W(r(e).layout),{key:3})):(a(),y(ws,{key:4},{"doc-top":p(()=>[c(n.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":p(()=>[c(n.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":p(()=>[c(n.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":p(()=>[c(n.$slots,"doc-before",{},void 0,!0)]),"doc-after":p(()=>[c(n.$slots,"doc-after",{},void 0,!0)]),"aside-top":p(()=>[c(n.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":p(()=>[c(n.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":p(()=>[c(n.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":p(()=>[c(n.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":p(()=>[c(n.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":p(()=>[c(n.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}}),go=$($o,[["__scopeId","data-v-91765379"]]),yo={class:"container"},Po=["innerHTML"],So=["innerHTML"],Vo=_({__name:"VPFooter",setup(s){const{theme:t,frontmatter:e}=L(),{hasSidebar:o}=O();return(n,i)=>r(t).footer&&r(e).footer!==!1?(a(),u("footer",{key:0,class:N(["VPFooter",{"has-sidebar":r(o)}])},[h("div",yo,[r(t).footer.message?(a(),u("p",{key:0,class:"message",innerHTML:r(t).footer.message},null,8,Po)):f("",!0),r(t).footer.copyright?(a(),u("p",{key:1,class:"copyright",innerHTML:r(t).footer.copyright},null,8,So)):f("",!0)])],2)):f("",!0)}}),Lo=$(Vo,[["__scopeId","data-v-c970a860"]]);function Fe(){const{theme:s,frontmatter:t}=L(),e=we([]),o=g(()=>e.value.length>0);return se(()=>{e.value=ke(t.value.outline??s.value.outline)}),{headers:e,hasLocalNav:o}}const To=s=>(B("data-v-c9ba27ad"),s=s(),H(),s),wo=To(()=>h("span",{class:"vpi-chevron-right icon"},null,-1)),Io={class:"header"},No={class:"outline"},Mo=_({__name:"VPLocalNavOutlineDropdown",props:{headers:{},navHeight:{}},setup(s){const t=s,{theme:e}=L(),o=w(!1),n=w(0),i=w(),l=w();tt(i,()=>{o.value=!1}),ce("Escape",()=>{o.value=!1}),se(()=>{o.value=!1});function v(){o.value=!o.value,n.value=window.innerHeight+Math.min(window.scrollY-t.navHeight,0)}function d(P){P.target.classList.contains("outline-link")&&(l.value&&(l.value.style.transition="none"),Me(()=>{o.value=!1}))}function m(){o.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(P,k)=>(a(),u("div",{class:"VPLocalNavOutlineDropdown",style:Ne({"--vp-vh":n.value+"px"}),ref_key:"main",ref:i},[P.headers.length>0?(a(),u("button",{key:0,onClick:v,class:N({open:o.value})},[D(T(r(Ee)(r(e)))+" ",1),wo],2)):(a(),u("button",{key:1,onClick:m},T(r(e).returnToTopLabel||"Return to top"),1)),b(pe,{name:"flyout"},{default:p(()=>[o.value?(a(),u("div",{key:0,ref_key:"items",ref:l,class:"items",onClick:d},[h("div",Io,[h("a",{class:"top-link",href:"#",onClick:m},T(r(e).returnToTopLabel||"Return to top"),1)]),h("div",No,[b(De,{headers:P.headers},null,8,["headers"])])],512)):f("",!0)]),_:1})],4))}}),Ao=$(Mo,[["__scopeId","data-v-c9ba27ad"]]),Co=s=>(B("data-v-070ab83d"),s=s(),H(),s),Bo={class:"container"},Ho=["aria-expanded"],Eo=Co(()=>h("span",{class:"vpi-align-left menu-icon"},null,-1)),Do={class:"menu-text"},Fo=_({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(s){const{theme:t,frontmatter:e}=L(),{hasSidebar:o}=O(),{headers:n}=Fe(),{y:i}=Ae(),l=w(0);j(()=>{l.value=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--vp-nav-height"))}),se(()=>{n.value=ke(e.value.outline??t.value.outline)});const v=g(()=>n.value.length===0),d=g(()=>v.value&&!o.value),m=g(()=>({VPLocalNav:!0,"has-sidebar":o.value,empty:v.value,fixed:d.value}));return(P,k)=>r(e).layout!=="home"&&(!d.value||r(i)>=l.value)?(a(),u("div",{key:0,class:N(m.value)},[h("div",Bo,[r(o)?(a(),u("button",{key:0,class:"menu","aria-expanded":P.open,"aria-controls":"VPSidebarNav",onClick:k[0]||(k[0]=V=>P.$emit("open-menu"))},[Eo,h("span",Do,T(r(t).sidebarMenuLabel||"Menu"),1)],8,Ho)):f("",!0),b(Ao,{headers:r(n),navHeight:l.value},null,8,["headers","navHeight"])])],2)):f("",!0)}}),Oo=$(Fo,[["__scopeId","data-v-070ab83d"]]);function Uo(){const s=w(!1);function t(){s.value=!0,window.addEventListener("resize",n)}function e(){s.value=!1,window.removeEventListener("resize",n)}function o(){s.value?e():t()}function n(){window.outerWidth>=768&&e()}const i=oe();return G(()=>i.path,e),{isScreenOpen:s,openScreen:t,closeScreen:e,toggleScreen:o}}const jo={},Go={class:"VPSwitch",type:"button",role:"switch"},zo={class:"check"},Ko={key:0,class:"icon"};function Ro(s,t){return a(),u("button",Go,[h("span",zo,[s.$slots.default?(a(),u("span",Ko,[c(s.$slots,"default",{},void 0,!0)])):f("",!0)])])}const Wo=$(jo,[["render",Ro],["__scopeId","data-v-4a1c76db"]]),Oe=s=>(B("data-v-b79b56d4"),s=s(),H(),s),qo=Oe(()=>h("span",{class:"vpi-sun sun"},null,-1)),Jo=Oe(()=>h("span",{class:"vpi-moon moon"},null,-1)),Yo=_({__name:"VPSwitchAppearance",setup(s){const{isDark:t,theme:e}=L(),o=J("toggle-appearance",()=>{t.value=!t.value}),n=g(()=>t.value?e.value.lightModeSwitchTitle||"Switch to light theme":e.value.darkModeSwitchTitle||"Switch to dark theme");return(i,l)=>(a(),y(Wo,{title:n.value,class:"VPSwitchAppearance","aria-checked":r(t),onClick:r(o)},{default:p(()=>[qo,Jo]),_:1},8,["title","aria-checked","onClick"]))}}),$e=$(Yo,[["__scopeId","data-v-b79b56d4"]]),Xo={key:0,class:"VPNavBarAppearance"},Qo=_({__name:"VPNavBarAppearance",setup(s){const{site:t}=L();return(e,o)=>r(t).appearance&&r(t).appearance!=="force-dark"?(a(),u("div",Xo,[b($e)])):f("",!0)}}),Zo=$(Qo,[["__scopeId","data-v-ead91a81"]]),ge=w();let Ue=!1,ie=0;function xo(s){const t=w(!1);if(q){!Ue&&en(),ie++;const e=G(ge,o=>{var n,i,l;o===s.el.value||(n=s.el.value)!=null&&n.contains(o)?(t.value=!0,(i=s.onFocus)==null||i.call(s)):(t.value=!1,(l=s.onBlur)==null||l.call(s))});fe(()=>{e(),ie--,ie||tn()})}return st(t)}function en(){document.addEventListener("focusin",je),Ue=!0,ge.value=document.activeElement}function tn(){document.removeEventListener("focusin",je)}function je(){ge.value=document.activeElement}const sn={class:"VPMenuLink"},on=_({__name:"VPMenuLink",props:{item:{}},setup(s){const{page:t}=L();return(e,o)=>(a(),u("div",sn,[b(F,{class:N({active:r(z)(r(t).relativePath,e.item.activeMatch||e.item.link,!!e.item.activeMatch)}),href:e.item.link,target:e.item.target,rel:e.item.rel},{default:p(()=>[D(T(e.item.text),1)]),_:1},8,["class","href","target","rel"])]))}}),ne=$(on,[["__scopeId","data-v-8b74d055"]]),nn={class:"VPMenuGroup"},an={key:0,class:"title"},rn=_({__name:"VPMenuGroup",props:{text:{},items:{}},setup(s){return(t,e)=>(a(),u("div",nn,[t.text?(a(),u("p",an,T(t.text),1)):f("",!0),(a(!0),u(M,null,E(t.items,o=>(a(),u(M,null,["link"in o?(a(),y(ne,{key:0,item:o},null,8,["item"])):f("",!0)],64))),256))]))}}),ln=$(rn,[["__scopeId","data-v-48c802d0"]]),cn={class:"VPMenu"},un={key:0,class:"items"},dn=_({__name:"VPMenu",props:{items:{}},setup(s){return(t,e)=>(a(),u("div",cn,[t.items?(a(),u("div",un,[(a(!0),u(M,null,E(t.items,o=>(a(),u(M,{key:o.text},["link"in o?(a(),y(ne,{key:0,item:o},null,8,["item"])):(a(),y(ln,{key:1,text:o.text,items:o.items},null,8,["text","items"]))],64))),128))])):f("",!0),c(t.$slots,"default",{},void 0,!0)]))}}),vn=$(dn,[["__scopeId","data-v-97491713"]]),pn=s=>(B("data-v-e5380155"),s=s(),H(),s),hn=["aria-expanded","aria-label"],fn={key:0,class:"text"},_n=["innerHTML"],mn=pn(()=>h("span",{class:"vpi-chevron-down text-icon"},null,-1)),bn={key:1,class:"vpi-more-horizontal icon"},kn={class:"menu"},$n=_({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(s){const t=w(!1),e=w();xo({el:e,onBlur:o});function o(){t.value=!1}return(n,i)=>(a(),u("div",{class:"VPFlyout",ref_key:"el",ref:e,onMouseenter:i[1]||(i[1]=l=>t.value=!0),onMouseleave:i[2]||(i[2]=l=>t.value=!1)},[h("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":t.value,"aria-label":n.label,onClick:i[0]||(i[0]=l=>t.value=!t.value)},[n.button||n.icon?(a(),u("span",fn,[n.icon?(a(),u("span",{key:0,class:N([n.icon,"option-icon"])},null,2)):f("",!0),n.button?(a(),u("span",{key:1,innerHTML:n.button},null,8,_n)):f("",!0),mn])):(a(),u("span",bn))],8,hn),h("div",kn,[b(vn,{items:n.items},{default:p(()=>[c(n.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}}),ye=$($n,[["__scopeId","data-v-e5380155"]]),gn=["href","aria-label","innerHTML"],yn=_({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(s){const t=s,e=g(()=>typeof t.icon=="object"?t.icon.svg:``);return(o,n)=>(a(),u("a",{class:"VPSocialLink no-icon",href:o.link,"aria-label":o.ariaLabel??(typeof o.icon=="string"?o.icon:""),target:"_blank",rel:"noopener",innerHTML:e.value},null,8,gn))}}),Pn=$(yn,[["__scopeId","data-v-717b8b75"]]),Sn={class:"VPSocialLinks"},Vn=_({__name:"VPSocialLinks",props:{links:{}},setup(s){return(t,e)=>(a(),u("div",Sn,[(a(!0),u(M,null,E(t.links,({link:o,icon:n,ariaLabel:i})=>(a(),y(Pn,{key:o,icon:n,link:o,ariaLabel:i},null,8,["icon","link","ariaLabel"]))),128))]))}}),Pe=$(Vn,[["__scopeId","data-v-ee7a9424"]]),Ln={key:0,class:"group translations"},Tn={class:"trans-title"},wn={key:1,class:"group"},In={class:"item appearance"},Nn={class:"label"},Mn={class:"appearance-action"},An={key:2,class:"group"},Cn={class:"item social-links"},Bn=_({__name:"VPNavBarExtra",setup(s){const{site:t,theme:e}=L(),{localeLinks:o,currentLang:n}=X({correspondingLink:!0}),i=g(()=>o.value.length&&n.value.label||t.value.appearance||e.value.socialLinks);return(l,v)=>i.value?(a(),y(ye,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:p(()=>[r(o).length&&r(n).label?(a(),u("div",Ln,[h("p",Tn,T(r(n).label),1),(a(!0),u(M,null,E(r(o),d=>(a(),y(ne,{key:d.link,item:d},null,8,["item"]))),128))])):f("",!0),r(t).appearance&&r(t).appearance!=="force-dark"?(a(),u("div",wn,[h("div",In,[h("p",Nn,T(r(e).darkModeSwitchLabel||"Appearance"),1),h("div",Mn,[b($e)])])])):f("",!0),r(e).socialLinks?(a(),u("div",An,[h("div",Cn,[b(Pe,{class:"social-links-list",links:r(e).socialLinks},null,8,["links"])])])):f("",!0)]),_:1})):f("",!0)}}),Hn=$(Bn,[["__scopeId","data-v-9b536d0b"]]),En=s=>(B("data-v-5dea55bf"),s=s(),H(),s),Dn=["aria-expanded"],Fn=En(()=>h("span",{class:"container"},[h("span",{class:"top"}),h("span",{class:"middle"}),h("span",{class:"bottom"})],-1)),On=[Fn],Un=_({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(s){return(t,e)=>(a(),u("button",{type:"button",class:N(["VPNavBarHamburger",{active:t.active}]),"aria-label":"mobile navigation","aria-expanded":t.active,"aria-controls":"VPNavScreen",onClick:e[0]||(e[0]=o=>t.$emit("click"))},On,10,Dn))}}),jn=$(Un,[["__scopeId","data-v-5dea55bf"]]),Gn=["innerHTML"],zn=_({__name:"VPNavBarMenuLink",props:{item:{}},setup(s){const{page:t}=L();return(e,o)=>(a(),y(F,{class:N({VPNavBarMenuLink:!0,active:r(z)(r(t).relativePath,e.item.activeMatch||e.item.link,!!e.item.activeMatch)}),href:e.item.link,target:e.item.target,rel:e.item.rel,tabindex:"0"},{default:p(()=>[h("span",{innerHTML:e.item.text},null,8,Gn)]),_:1},8,["class","href","target","rel"]))}}),Kn=$(zn,[["__scopeId","data-v-2781b5e7"]]),Rn=_({__name:"VPNavBarMenuGroup",props:{item:{}},setup(s){const t=s,{page:e}=L(),o=i=>"link"in i?z(e.value.relativePath,i.link,!!t.item.activeMatch):i.items.some(o),n=g(()=>o(t.item));return(i,l)=>(a(),y(ye,{class:N({VPNavBarMenuGroup:!0,active:r(z)(r(e).relativePath,i.item.activeMatch,!!i.item.activeMatch)||n.value}),button:i.item.text,items:i.item.items},null,8,["class","button","items"]))}}),Wn=s=>(B("data-v-492ea56d"),s=s(),H(),s),qn={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},Jn=Wn(()=>h("span",{id:"main-nav-aria-label",class:"visually-hidden"},"Main Navigation",-1)),Yn=_({__name:"VPNavBarMenu",setup(s){const{theme:t}=L();return(e,o)=>r(t).nav?(a(),u("nav",qn,[Jn,(a(!0),u(M,null,E(r(t).nav,n=>(a(),u(M,{key:n.text},["link"in n?(a(),y(Kn,{key:0,item:n},null,8,["item"])):(a(),y(Rn,{key:1,item:n},null,8,["item"]))],64))),128))])):f("",!0)}}),Xn=$(Yn,[["__scopeId","data-v-492ea56d"]]);function Qn(s){const{localeIndex:t,theme:e}=L();function o(n){var A,C,I;const i=n.split("."),l=(A=e.value.search)==null?void 0:A.options,v=l&&typeof l=="object",d=v&&((I=(C=l.locales)==null?void 0:C[t.value])==null?void 0:I.translations)||null,m=v&&l.translations||null;let P=d,k=m,V=s;const S=i.pop();for(const Q of i){let U=null;const R=V==null?void 0:V[Q];R&&(U=V=R);const ae=k==null?void 0:k[Q];ae&&(U=k=ae);const re=P==null?void 0:P[Q];re&&(U=P=re),R||(V=U),ae||(k=U),re||(P=U)}return(P==null?void 0:P[S])??(k==null?void 0:k[S])??(V==null?void 0:V[S])??""}return o}const Zn=["aria-label"],xn={class:"DocSearch-Button-Container"},ea=h("span",{class:"vp-icon DocSearch-Search-Icon"},null,-1),ta={class:"DocSearch-Button-Placeholder"},sa=h("span",{class:"DocSearch-Button-Keys"},[h("kbd",{class:"DocSearch-Button-Key"}),h("kbd",{class:"DocSearch-Button-Key"},"K")],-1),Se=_({__name:"VPNavBarSearchButton",setup(s){const e=Qn({button:{buttonText:"Search",buttonAriaLabel:"Search"}});return(o,n)=>(a(),u("button",{type:"button",class:"DocSearch DocSearch-Button","aria-label":r(e)("button.buttonAriaLabel")},[h("span",xn,[ea,h("span",ta,T(r(e)("button.buttonText")),1)]),sa],8,Zn))}}),oa={class:"VPNavBarSearch"},na={id:"local-search"},aa={key:1,id:"docsearch"},ra=_({__name:"VPNavBarSearch",setup(s){const t=ot(()=>nt(()=>import("./VPLocalSearchBox.B9WZ723L.js"),__vite__mapDeps([0,1]))),e=()=>null,{theme:o}=L(),n=w(!1),i=w(!1);j(()=>{});function l(){n.value||(n.value=!0,setTimeout(v,16))}function v(){const k=new Event("keydown");k.key="k",k.metaKey=!0,window.dispatchEvent(k),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||v()},16)}function d(k){const V=k.target,S=V.tagName;return V.isContentEditable||S==="INPUT"||S==="SELECT"||S==="TEXTAREA"}const m=w(!1);ce("k",k=>{(k.ctrlKey||k.metaKey)&&(k.preventDefault(),m.value=!0)}),ce("/",k=>{d(k)||(k.preventDefault(),m.value=!0)});const P="local";return(k,V)=>{var S;return a(),u("div",oa,[r(P)==="local"?(a(),u(M,{key:0},[m.value?(a(),y(r(t),{key:0,onClose:V[0]||(V[0]=A=>m.value=!1)})):f("",!0),h("div",na,[b(Se,{onClick:V[1]||(V[1]=A=>m.value=!0)})])],64)):r(P)==="algolia"?(a(),u(M,{key:1},[n.value?(a(),y(r(e),{key:0,algolia:((S=r(o).search)==null?void 0:S.options)??r(o).algolia,onVnodeBeforeMount:V[2]||(V[2]=A=>i.value=!0)},null,8,["algolia"])):f("",!0),i.value?f("",!0):(a(),u("div",aa,[b(Se,{onClick:l})]))],64)):f("",!0)])}}}),ia=_({__name:"VPNavBarSocialLinks",setup(s){const{theme:t}=L();return(e,o)=>r(t).socialLinks?(a(),y(Pe,{key:0,class:"VPNavBarSocialLinks",links:r(t).socialLinks},null,8,["links"])):f("",!0)}}),la=$(ia,[["__scopeId","data-v-164c457f"]]),ca=["href","rel","target"],ua={key:1},da={key:2},va=_({__name:"VPNavBarTitle",setup(s){const{site:t,theme:e}=L(),{hasSidebar:o}=O(),{currentLang:n}=X(),i=g(()=>{var d;return typeof e.value.logoLink=="string"?e.value.logoLink:(d=e.value.logoLink)==null?void 0:d.link}),l=g(()=>{var d;return typeof e.value.logoLink=="string"||(d=e.value.logoLink)==null?void 0:d.rel}),v=g(()=>{var d;return typeof e.value.logoLink=="string"||(d=e.value.logoLink)==null?void 0:d.target});return(d,m)=>(a(),u("div",{class:N(["VPNavBarTitle",{"has-sidebar":r(o)}])},[h("a",{class:"title",href:i.value??r(me)(r(n).link),rel:l.value,target:v.value},[c(d.$slots,"nav-bar-title-before",{},void 0,!0),r(e).logo?(a(),y(ee,{key:0,class:"logo",image:r(e).logo},null,8,["image"])):f("",!0),r(e).siteTitle?(a(),u("span",ua,T(r(e).siteTitle),1)):r(e).siteTitle===void 0?(a(),u("span",da,T(r(t).title),1)):f("",!0),c(d.$slots,"nav-bar-title-after",{},void 0,!0)],8,ca)],2))}}),pa=$(va,[["__scopeId","data-v-28a961f9"]]),ha={class:"items"},fa={class:"title"},_a=_({__name:"VPNavBarTranslations",setup(s){const{theme:t}=L(),{localeLinks:e,currentLang:o}=X({correspondingLink:!0});return(n,i)=>r(e).length&&r(o).label?(a(),y(ye,{key:0,class:"VPNavBarTranslations",icon:"vpi-languages",label:r(t).langMenuLabel||"Change language"},{default:p(()=>[h("div",ha,[h("p",fa,T(r(o).label),1),(a(!0),u(M,null,E(r(e),l=>(a(),y(ne,{key:l.link,item:l},null,8,["item"]))),128))])]),_:1},8,["label"])):f("",!0)}}),ma=$(_a,[["__scopeId","data-v-c80d9ad0"]]),ba=s=>(B("data-v-b9c8b02d"),s=s(),H(),s),ka={class:"wrapper"},$a={class:"container"},ga={class:"title"},ya={class:"content"},Pa={class:"content-body"},Sa=ba(()=>h("div",{class:"divider"},[h("div",{class:"divider-line"})],-1)),Va=_({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(s){const{y:t}=Ae(),{hasSidebar:e}=O(),{hasLocalNav:o}=Fe(),{frontmatter:n}=L(),i=w({});return Te(()=>{i.value={"has-sidebar":e.value,"has-local-nav":o.value,top:n.value.layout==="home"&&t.value===0}}),(l,v)=>(a(),u("div",{class:N(["VPNavBar",i.value])},[h("div",ka,[h("div",$a,[h("div",ga,[b(pa,null,{"nav-bar-title-before":p(()=>[c(l.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":p(()=>[c(l.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),h("div",ya,[h("div",Pa,[c(l.$slots,"nav-bar-content-before",{},void 0,!0),b(ra,{class:"search"}),b(Xn,{class:"menu"}),b(ma,{class:"translations"}),b(Zo,{class:"appearance"}),b(la,{class:"social-links"}),b(Hn,{class:"extra"}),c(l.$slots,"nav-bar-content-after",{},void 0,!0),b(jn,{class:"hamburger",active:l.isScreenOpen,onClick:v[0]||(v[0]=d=>l.$emit("toggle-screen"))},null,8,["active"])])])])]),Sa],2))}}),La=$(Va,[["__scopeId","data-v-b9c8b02d"]]),Ta={key:0,class:"VPNavScreenAppearance"},wa={class:"text"},Ia=_({__name:"VPNavScreenAppearance",setup(s){const{site:t,theme:e}=L();return(o,n)=>r(t).appearance&&r(t).appearance!=="force-dark"?(a(),u("div",Ta,[h("p",wa,T(r(e).darkModeSwitchLabel||"Appearance"),1),b($e)])):f("",!0)}}),Na=$(Ia,[["__scopeId","data-v-2b89f08b"]]),Ma=_({__name:"VPNavScreenMenuLink",props:{item:{}},setup(s){const t=J("close-screen");return(e,o)=>(a(),y(F,{class:"VPNavScreenMenuLink",href:e.item.link,target:e.item.target,rel:e.item.rel,onClick:r(t)},{default:p(()=>[D(T(e.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}}),Aa=$(Ma,[["__scopeId","data-v-d45ba3e8"]]),Ca=_({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(s){const t=J("close-screen");return(e,o)=>(a(),y(F,{class:"VPNavScreenMenuGroupLink",href:e.item.link,target:e.item.target,rel:e.item.rel,onClick:r(t)},{default:p(()=>[D(T(e.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}}),Ge=$(Ca,[["__scopeId","data-v-7179dbb7"]]),Ba={class:"VPNavScreenMenuGroupSection"},Ha={key:0,class:"title"},Ea=_({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(s){return(t,e)=>(a(),u("div",Ba,[t.text?(a(),u("p",Ha,T(t.text),1)):f("",!0),(a(!0),u(M,null,E(t.items,o=>(a(),y(Ge,{key:o.text,item:o},null,8,["item"]))),128))]))}}),Da=$(Ea,[["__scopeId","data-v-4b8941ac"]]),Fa=s=>(B("data-v-c9df2649"),s=s(),H(),s),Oa=["aria-controls","aria-expanded"],Ua=["innerHTML"],ja=Fa(()=>h("span",{class:"vpi-plus button-icon"},null,-1)),Ga=["id"],za={key:1,class:"group"},Ka=_({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(s){const t=s,e=w(!1),o=g(()=>`NavScreenGroup-${t.text.replace(" ","-").toLowerCase()}`);function n(){e.value=!e.value}return(i,l)=>(a(),u("div",{class:N(["VPNavScreenMenuGroup",{open:e.value}])},[h("button",{class:"button","aria-controls":o.value,"aria-expanded":e.value,onClick:n},[h("span",{class:"button-text",innerHTML:i.text},null,8,Ua),ja],8,Oa),h("div",{id:o.value,class:"items"},[(a(!0),u(M,null,E(i.items,v=>(a(),u(M,{key:v.text},["link"in v?(a(),u("div",{key:v.text,class:"item"},[b(Ge,{item:v},null,8,["item"])])):(a(),u("div",za,[b(Da,{text:v.text,items:v.items},null,8,["text","items"])]))],64))),128))],8,Ga)],2))}}),Ra=$(Ka,[["__scopeId","data-v-c9df2649"]]),Wa={key:0,class:"VPNavScreenMenu"},qa=_({__name:"VPNavScreenMenu",setup(s){const{theme:t}=L();return(e,o)=>r(t).nav?(a(),u("nav",Wa,[(a(!0),u(M,null,E(r(t).nav,n=>(a(),u(M,{key:n.text},["link"in n?(a(),y(Aa,{key:0,item:n},null,8,["item"])):(a(),y(Ra,{key:1,text:n.text||"",items:n.items},null,8,["text","items"]))],64))),128))])):f("",!0)}}),Ja=_({__name:"VPNavScreenSocialLinks",setup(s){const{theme:t}=L();return(e,o)=>r(t).socialLinks?(a(),y(Pe,{key:0,class:"VPNavScreenSocialLinks",links:r(t).socialLinks},null,8,["links"])):f("",!0)}}),ze=s=>(B("data-v-362991c2"),s=s(),H(),s),Ya=ze(()=>h("span",{class:"vpi-languages icon lang"},null,-1)),Xa=ze(()=>h("span",{class:"vpi-chevron-down icon chevron"},null,-1)),Qa={class:"list"},Za=_({__name:"VPNavScreenTranslations",setup(s){const{localeLinks:t,currentLang:e}=X({correspondingLink:!0}),o=w(!1);function n(){o.value=!o.value}return(i,l)=>r(t).length&&r(e).label?(a(),u("div",{key:0,class:N(["VPNavScreenTranslations",{open:o.value}])},[h("button",{class:"title",onClick:n},[Ya,D(" "+T(r(e).label)+" ",1),Xa]),h("ul",Qa,[(a(!0),u(M,null,E(r(t),v=>(a(),u("li",{key:v.link,class:"item"},[b(F,{class:"link",href:v.link},{default:p(()=>[D(T(v.text),1)]),_:2},1032,["href"])]))),128))])],2)):f("",!0)}}),xa=$(Za,[["__scopeId","data-v-362991c2"]]),er={class:"container"},tr=_({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(s){const t=w(null),e=Ce(q?document.body:null);return(o,n)=>(a(),y(pe,{name:"fade",onEnter:n[0]||(n[0]=i=>e.value=!0),onAfterLeave:n[1]||(n[1]=i=>e.value=!1)},{default:p(()=>[o.open?(a(),u("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:t,id:"VPNavScreen"},[h("div",er,[c(o.$slots,"nav-screen-content-before",{},void 0,!0),b(qa,{class:"menu"}),b(xa,{class:"translations"}),b(Na,{class:"appearance"}),b(Ja,{class:"social-links"}),c(o.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):f("",!0)]),_:3}))}}),sr=$(tr,[["__scopeId","data-v-382f42e9"]]),or={key:0,class:"VPNav"},nr=_({__name:"VPNav",setup(s){const{isScreenOpen:t,closeScreen:e,toggleScreen:o}=Uo(),{frontmatter:n}=L(),i=g(()=>n.value.navbar!==!1);return _e("close-screen",e),te(()=>{q&&document.documentElement.classList.toggle("hide-nav",!i.value)}),(l,v)=>i.value?(a(),u("header",or,[b(La,{"is-screen-open":r(t),onToggleScreen:r(o)},{"nav-bar-title-before":p(()=>[c(l.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":p(()=>[c(l.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":p(()=>[c(l.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":p(()=>[c(l.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),b(sr,{open:r(t)},{"nav-screen-content-before":p(()=>[c(l.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":p(()=>[c(l.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])])):f("",!0)}}),ar=$(nr,[["__scopeId","data-v-f1e365da"]]),Ke=s=>(B("data-v-f24171a4"),s=s(),H(),s),rr=["role","tabindex"],ir=Ke(()=>h("div",{class:"indicator"},null,-1)),lr=Ke(()=>h("span",{class:"vpi-chevron-right caret-icon"},null,-1)),cr=[lr],ur={key:1,class:"items"},dr=_({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(s){const t=s,{collapsed:e,collapsible:o,isLink:n,isActiveLink:i,hasActiveLink:l,hasChildren:v,toggle:d}=Nt(g(()=>t.item)),m=g(()=>v.value?"section":"div"),P=g(()=>n.value?"a":"div"),k=g(()=>v.value?t.depth+2===7?"p":`h${t.depth+2}`:"p"),V=g(()=>n.value?void 0:"button"),S=g(()=>[[`level-${t.depth}`],{collapsible:o.value},{collapsed:e.value},{"is-link":n.value},{"is-active":i.value},{"has-active":l.value}]);function A(I){"key"in I&&I.key!=="Enter"||!t.item.link&&d()}function C(){t.item.link&&d()}return(I,Q)=>{const U=K("VPSidebarItem",!0);return a(),y(W(m.value),{class:N(["VPSidebarItem",S.value])},{default:p(()=>[I.item.text?(a(),u("div",Z({key:0,class:"item",role:V.value},rt(I.item.items?{click:A,keydown:A}:{},!0),{tabindex:I.item.items&&0}),[ir,I.item.link?(a(),y(F,{key:0,tag:P.value,class:"link",href:I.item.link,rel:I.item.rel,target:I.item.target},{default:p(()=>[(a(),y(W(k.value),{class:"text",innerHTML:I.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href","rel","target"])):(a(),y(W(k.value),{key:1,class:"text",innerHTML:I.item.text},null,8,["innerHTML"])),I.item.collapsed!=null?(a(),u("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:C,onKeydown:at(C,["enter"]),tabindex:"0"},cr,32)):f("",!0)],16,rr)):f("",!0),I.item.items&&I.item.items.length?(a(),u("div",ur,[I.depth<5?(a(!0),u(M,{key:0},E(I.item.items,R=>(a(),y(U,{key:R.text,item:R,depth:I.depth+1},null,8,["item","depth"]))),128)):f("",!0)])):f("",!0)]),_:1},8,["class"])}}}),vr=$(dr,[["__scopeId","data-v-f24171a4"]]),Re=s=>(B("data-v-ec846e01"),s=s(),H(),s),pr=Re(()=>h("div",{class:"curtain"},null,-1)),hr={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},fr=Re(()=>h("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),_r=_({__name:"VPSidebar",props:{open:{type:Boolean}},setup(s){const{sidebarGroups:t,hasSidebar:e}=O(),o=s,n=w(null),i=Ce(q?document.body:null);return G([o,n],()=>{var l;o.open?(i.value=!0,(l=n.value)==null||l.focus()):i.value=!1},{immediate:!0,flush:"post"}),(l,v)=>r(e)?(a(),u("aside",{key:0,class:N(["VPSidebar",{open:l.open}]),ref_key:"navEl",ref:n,onClick:v[0]||(v[0]=it(()=>{},["stop"]))},[pr,h("nav",hr,[fr,c(l.$slots,"sidebar-nav-before",{},void 0,!0),(a(!0),u(M,null,E(r(t),d=>(a(),u("div",{key:d.text,class:"group"},[b(vr,{item:d,depth:0},null,8,["item"])]))),128)),c(l.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):f("",!0)}}),mr=$(_r,[["__scopeId","data-v-ec846e01"]]),br=_({__name:"VPSkipLink",setup(s){const t=oe(),e=w();G(()=>t.path,()=>e.value.focus());function o({target:n}){const i=document.getElementById(decodeURIComponent(n.hash).slice(1));if(i){const l=()=>{i.removeAttribute("tabindex"),i.removeEventListener("blur",l)};i.setAttribute("tabindex","-1"),i.addEventListener("blur",l),i.focus(),window.scrollTo(0,0)}}return(n,i)=>(a(),u(M,null,[h("span",{ref_key:"backToTop",ref:e,tabindex:"-1"},null,512),h("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:o}," Skip to content ")],64))}}),kr=$(br,[["__scopeId","data-v-c3508ec8"]]),$r=_({__name:"Layout",setup(s){const{isOpen:t,open:e,close:o}=O(),n=oe();G(()=>n.path,o),It(t,o);const{frontmatter:i}=L(),l=Be(),v=g(()=>!!l["home-hero-image"]);return _e("hero-image-slot-exists",v),(d,m)=>{const P=K("Content");return r(i).layout!==!1?(a(),u("div",{key:0,class:N(["Layout",r(i).pageClass])},[c(d.$slots,"layout-top",{},void 0,!0),b(kr),b(ht,{class:"backdrop",show:r(t),onClick:r(o)},null,8,["show","onClick"]),b(ar,null,{"nav-bar-title-before":p(()=>[c(d.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":p(()=>[c(d.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":p(()=>[c(d.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":p(()=>[c(d.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":p(()=>[c(d.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":p(()=>[c(d.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),b(Oo,{open:r(t),onOpenMenu:r(e)},null,8,["open","onOpenMenu"]),b(mr,{open:r(t)},{"sidebar-nav-before":p(()=>[c(d.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":p(()=>[c(d.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),b(go,null,{"page-top":p(()=>[c(d.$slots,"page-top",{},void 0,!0)]),"page-bottom":p(()=>[c(d.$slots,"page-bottom",{},void 0,!0)]),"not-found":p(()=>[c(d.$slots,"not-found",{},void 0,!0)]),"home-hero-before":p(()=>[c(d.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":p(()=>[c(d.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":p(()=>[c(d.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":p(()=>[c(d.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":p(()=>[c(d.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":p(()=>[c(d.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":p(()=>[c(d.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":p(()=>[c(d.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":p(()=>[c(d.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":p(()=>[c(d.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":p(()=>[c(d.$slots,"doc-before",{},void 0,!0)]),"doc-after":p(()=>[c(d.$slots,"doc-after",{},void 0,!0)]),"doc-top":p(()=>[c(d.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":p(()=>[c(d.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":p(()=>[c(d.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":p(()=>[c(d.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":p(()=>[c(d.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":p(()=>[c(d.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":p(()=>[c(d.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":p(()=>[c(d.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),b(Lo),c(d.$slots,"layout-bottom",{},void 0,!0)],2)):(a(),y(P,{key:1}))}}}),gr=$($r,[["__scopeId","data-v-a9a9e638"]]),Ve={Layout:gr,enhanceApp:({app:s})=>{s.component("Badge",dt)}},yr=s=>{if(typeof document>"u")return{stabilizeScrollPosition:n=>async(...i)=>n(...i)};const t=document.documentElement;return{stabilizeScrollPosition:o=>async(...n)=>{const i=o(...n),l=s.value;if(!l)return i;const v=l.offsetTop-t.scrollTop;return await Me(),t.scrollTop=l.offsetTop-v,i}}},We="vitepress:tabSharedState",Y=typeof localStorage<"u"?localStorage:null,qe="vitepress:tabsSharedState",Pr=()=>{const s=Y==null?void 0:Y.getItem(qe);if(s)try{return JSON.parse(s)}catch{}return{}},Sr=s=>{Y&&Y.setItem(qe,JSON.stringify(s))},Vr=s=>{const t=lt({});G(()=>t.content,(e,o)=>{e&&o&&Sr(e)},{deep:!0}),s.provide(We,t)},Lr=(s,t)=>{const e=J(We);if(!e)throw new Error("[vitepress-plugin-tabs] TabsSharedState should be injected");j(()=>{e.content||(e.content=Pr())});const o=w(),n=g({get(){var d;const l=t.value,v=s.value;if(l){const m=(d=e.content)==null?void 0:d[l];if(m&&v.includes(m))return m}else{const m=o.value;if(m)return m}return v[0]},set(l){const v=t.value;v?e.content&&(e.content[v]=l):o.value=l}});return{selected:n,select:l=>{n.value=l}}};let Le=0;const Tr=()=>(Le++,""+Le);function wr(){const s=Be();return g(()=>{var o;const e=(o=s.default)==null?void 0:o.call(s);return e?e.filter(n=>typeof n.type=="object"&&"__name"in n.type&&n.type.__name==="PluginTabsTab"&&n.props).map(n=>{var i;return(i=n.props)==null?void 0:i.label}):[]})}const Je="vitepress:tabSingleState",Ir=s=>{_e(Je,s)},Nr=()=>{const s=J(Je);if(!s)throw new Error("[vitepress-plugin-tabs] TabsSingleState should be injected");return s},Mr={class:"plugin-tabs"},Ar=["id","aria-selected","aria-controls","tabindex","onClick"],Cr=_({__name:"PluginTabs",props:{sharedStateKey:{}},setup(s){const t=s,e=wr(),{selected:o,select:n}=Lr(e,ct(t,"sharedStateKey")),i=w(),{stabilizeScrollPosition:l}=yr(i),v=l(n),d=w([]),m=k=>{var A;const V=e.value.indexOf(o.value);let S;k.key==="ArrowLeft"?S=V>=1?V-1:e.value.length-1:k.key==="ArrowRight"&&(S=V(a(),u("div",Mr,[h("div",{ref_key:"tablist",ref:i,class:"plugin-tabs--tab-list",role:"tablist",onKeydown:m},[(a(!0),u(M,null,E(r(e),S=>(a(),u("button",{id:`tab-${S}-${r(P)}`,ref_for:!0,ref_key:"buttonRefs",ref:d,key:S,role:"tab",class:"plugin-tabs--tab","aria-selected":S===r(o),"aria-controls":`panel-${S}-${r(P)}`,tabindex:S===r(o)?0:-1,onClick:()=>r(v)(S)},T(S),9,Ar))),128))],544),c(k.$slots,"default")]))}}),Br=["id","aria-labelledby"],Hr=_({__name:"PluginTabsTab",props:{label:{}},setup(s){const{uid:t,selected:e}=Nr();return(o,n)=>r(e)===o.label?(a(),u("div",{key:0,id:`panel-${o.label}-${r(t)}`,class:"plugin-tabs--content",role:"tabpanel",tabindex:"0","aria-labelledby":`tab-${o.label}-${r(t)}`},[c(o.$slots,"default",{},void 0,!0)],8,Br)):f("",!0)}}),Er=$(Hr,[["__scopeId","data-v-9b0d03d2"]]),Dr=s=>{Vr(s),s.component("PluginTabs",Cr),s.component("PluginTabsTab",Er)},Or={extends:Ve,Layout(){return ut(Ve.Layout,null,{})},enhanceApp({app:s,router:t,siteData:e}){Dr(s)}};export{Or as R,Qn as c,L as u}; diff --git a/dev/assets/constraints_comparison_constraints.md.2Ukc8viw.js b/dev/assets/constraints_comparison_constraints.md.2Ukc8viw.js deleted file mode 100644 index a799fd2..0000000 --- a/dev/assets/constraints_comparison_constraints.md.2Ukc8viw.js +++ /dev/null @@ -1,25 +0,0 @@ -import{_ as s,c as i,o as a,a7 as n}from"./chunks/framework.aA95Gx5L.js";const y=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/comparison_constraints.md","filePath":"constraints/comparison_constraints.md","lastUpdated":null}'),h={name:"constraints/comparison_constraints.md"},t=n(`

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Comparison-based Constraints

# Constraints.xcsp_all_differentFunction.
julia
xcsp_all_different(list::Vector{Int})

Return true if all the values of list are different, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

Variants

  • :all_different: Global constraint ensuring that all the values of x are all different.
julia
concept(:all_different, x; vals)
-concept(:all_different)(x; vals)

Examples

julia
c = concept(:all_different)
-
-c([1, 2, 3, 4])
-c([1, 2, 3, 1])
-c([1, 0, 0, 4]; vals=[0])
-c([1, 0, 0, 1]; vals=[0])

source


# Constraints.xcsp_all_equalFunction.
julia
xcsp_all_equal(list::Vector{Int}, val::Int)

Return true if all the values of list are equal to val, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • val::Int: value to compare to.

Variants

  • :all_equal: Global constraint ensuring that all the values of x are all equal.
julia
concept(:all_equal, x; val=nothing, pair_vars=zeros(x), op=+)
-concept(:all_equal)(x; val=nothing, pair_vars=zeros(x), op=+)

Examples

julia
c = concept(:all_equal)
-
-c([0, 0, 0, 0])
-c([1, 2, 3, 4])
-c([3, 2, 1, 0]; pair_vars=[0, 1, 2, 3])
-c([0, 1, 2, 3]; pair_vars=[0, 1, 2, 3])
-c([1, 2, 3, 4]; op=/, val=1, pair_vars=[1, 2, 3, 4])
-c([1, 2, 3, 4]; op=*, val=1, pair_vars=[1, 2, 3, 4])

source


# Constraints.xcsp_orderedFunction.
julia
xcsp_ordered(list::Vector{Int}, operator, lengths)

Return true if all the values of list are in an increasing order, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • operator: comparison operator to use.

  • lengths: list of lengths to use. Defaults to nothing.

Variants

  • :ordered: Global constraint ensuring that all the values of x are in an increasing order.
julia
concept(:ordered, x; op=≤, pair_vars=nothing)
-concept(:ordered)(x; op=≤, pair_vars=nothing)
  • :increasing: Global constraint ensuring that all the values of x are in an increasing order.
julia
concept(:increasing, x; op=≤, pair_vars=nothing)
-concept(:increasing)(x; op=≤, pair_vars=nothing)
  • :decreasing: Global constraint ensuring that all the values of x are in a decreasing order.
julia
concept(:decreasing, x; op=≥, pair_vars=nothing)
-concept(:decreasing)(x; op=≥, pair_vars=nothing)
  • :strictly_increasing: Global constraint ensuring that all the values of x are in a strictly increasing order.
julia
concept(:strictly_increasing, x; op=<, pair_vars=nothing)
-concept(:strictly_increasing)(x; op=<, pair_vars=nothing)
  • :strictly_decreasing: Global constraint ensuring that all the values of x are in a strictly decreasing order.
julia
concept(:strictly_decreasing, x; op=>, pair_vars=nothing)
-concept(:strictly_decreasing)(x; op=>, pair_vars=nothing)

Examples

julia
c = concept(:ordered)
-
-c([1, 2, 3, 4, 4]; op=≤)
-c([1, 2, 3, 4, 5]; op=<)
-!c([1, 2, 3, 4, 3]; op=≤)
-!c([1, 2, 3, 4, 3]; op=<)

source


`,8),l=[t];function k(p,e,r,E,d,g){return a(),i("div",null,l)}const c=s(h,[["render",k]]);export{y as __pageData,c as default}; diff --git a/dev/assets/constraints_comparison_constraints.md.2Ukc8viw.lean.js b/dev/assets/constraints_comparison_constraints.md.2Ukc8viw.lean.js deleted file mode 100644 index cf7b997..0000000 --- a/dev/assets/constraints_comparison_constraints.md.2Ukc8viw.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as i,o as a,a7 as n}from"./chunks/framework.aA95Gx5L.js";const y=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/comparison_constraints.md","filePath":"constraints/comparison_constraints.md","lastUpdated":null}'),h={name:"constraints/comparison_constraints.md"},t=n("",8),l=[t];function k(p,e,r,E,d,g){return a(),i("div",null,l)}const c=s(h,[["render",k]]);export{y as __pageData,c as default}; diff --git a/dev/assets/constraints_connection_constraints.md.0kSxmxNT.js b/dev/assets/constraints_connection_constraints.md.0kSxmxNT.js deleted file mode 100644 index 8a826a2..0000000 --- a/dev/assets/constraints_connection_constraints.md.0kSxmxNT.js +++ /dev/null @@ -1,24 +0,0 @@ -import{_ as s,c as i,o as a,a7 as n}from"./chunks/framework.aA95Gx5L.js";const c=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/connection_constraints.md","filePath":"constraints/connection_constraints.md","lastUpdated":null}'),t={name:"constraints/connection_constraints.md"},h=n(`

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Connection Constraints

# Constraints.xcsp_maximumFunction.
julia
xcsp_maximum(; list, condition)

Return true if the maximum constraint is satisfied, false otherwise. The maximum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the maximum value in a list of variables.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

  • condition::Tuple: condition to check.

Variants

  • :maximum: The maximum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the maximum value in a list of variables.
julia
concept(:maximum, x; op, val)
-concept(:maximum)(x; op, val)

Examples

julia
c = concept(:maximum)
-
-c([1, 2, 3, 4, 5]; op = ==, val = 5)
-c([1, 2, 3, 4, 5]; op = ==, val = 6)

source


# Constraints.xcsp_minimumFunction.
julia
xcsp_minimum(; list, condition)

Return true if the minimum constraint is satisfied, false otherwise. The minimum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the minimum value in a list of variables.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

  • condition::Tuple: condition to check.

Variants

  • :minimum: The minimum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the minimum value in a list of variables.
julia
concept(:minimum, x; op, val)
-concept(:minimum)(x; op, val)

Examples

julia
c = concept(:minimum)
-
-c([1, 2, 3, 4, 5]; op = ==, val = 1)
-c([1, 2, 3, 4, 5]; op = ==, val = 0)

source


# Constraints.xcsp_elementFunction.
julia
xcsp_element(; list, index, condition)

Return true if the element constraint is satisfied, false otherwise. The element constraint is a global constraint used in constraint programming that specifies that the value of a variable should be equal to the value of another variable indexed by a third variable.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

  • index::Int: index of the value to check.

  • condition::Tuple: condition to check.

Variants

  • :element: The element constraint is a global constraint used in constraint programming that specifies that the value of a variable should be equal to the value of another variable indexed by a third variable.
julia
concept(:element, x; id=nothing, op===, val=nothing)
-concept(:element)(x; id=nothing, op===, val=nothing)

Examples

julia
c = concept(:element)
-
-c([1, 2, 3, 4, 5]; id=1, val=1)
-c([1, 2, 3, 4, 5]; id=1, val=2)
-c([1, 2, 3, 4, 2])
-c([1, 2, 3, 4, 1])

source


# Constraints.xcsp_channelFunction.
julia
xcsp_channel(; list)

Return true if the channel constraint is satisfied, false otherwise. The channel constraint establishes a bijective correspondence between two sets of variables. This means that each value in the first set of variables corresponds to a unique value in the second set, and vice versa.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

Variants

  • :channel: The channel constraint establishes a bijective correspondence between two sets of variables. This means that each value in the first set of variables corresponds to a unique value in the second set, and vice versa.
julia
concept(:channel, x; dim=1, id=nothing)
-concept(:channel)(x; dim=1, id=nothing)

Examples

julia
c = concept(:channel)
-
-c([2, 1, 4, 3])
-c([1, 2, 3, 4])
-c([2, 3, 1, 4])
-c([2, 1, 5, 3, 4, 2, 1, 4, 5, 3]; dim=2)
-c([2, 1, 4, 3, 5, 2, 1, 4, 5, 3]; dim=2)
-c([false, false, true, false]; id=3)
-c([false, false, true, false]; id=1)

source


`,10),l=[h];function k(p,e,r,E,d,o){return a(),i("div",null,l)}const y=s(t,[["render",k]]);export{c as __pageData,y as default}; diff --git a/dev/assets/constraints_connection_constraints.md.0kSxmxNT.lean.js b/dev/assets/constraints_connection_constraints.md.0kSxmxNT.lean.js deleted file mode 100644 index 3774d91..0000000 --- a/dev/assets/constraints_connection_constraints.md.0kSxmxNT.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as i,o as a,a7 as n}from"./chunks/framework.aA95Gx5L.js";const c=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/connection_constraints.md","filePath":"constraints/connection_constraints.md","lastUpdated":null}'),t={name:"constraints/connection_constraints.md"},h=n("",10),l=[h];function k(p,e,r,E,d,o){return a(),i("div",null,l)}const y=s(t,[["render",k]]);export{c as __pageData,y as default}; diff --git a/dev/assets/constraints_constraint_commons.md.PTLdrUW2.js b/dev/assets/constraints_constraint_commons.md.PTLdrUW2.js deleted file mode 100644 index f3c0636..0000000 --- a/dev/assets/constraints_constraint_commons.md.PTLdrUW2.js +++ /dev/null @@ -1,10 +0,0 @@ -import{_ as s,c as a,o as i,a7 as t}from"./chunks/framework.aA95Gx5L.js";const k=JSON.parse('{"title":"ConstraintCommons.jl","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/constraint_commons.md","filePath":"constraints/constraint_commons.md","lastUpdated":null}'),e={name:"constraints/constraint_commons.md"},n=t(`

ConstraintCommons.jl

ConstraintCommons.jl is an essential package within the Julia Constraints ecosystem designed to facilitate the development and interoperability of constraint programming solutions in Julia. It serves as a foundational layer that provides shared structures, abstract types, functions, and generic methods utilized by both basic feature packages and learning-oriented packages.

Key Features and Functionalities

  • Shared Structures and Abstract Types: ConstraintCommons.jl offers a collection of shared data structures and abstract types. This standardization is crucial for ensuring that packages such as ConstraintDomains, Constraints, ConstraintLearning, etc. can seamlessly interact and integrate, fostering a cohesive development environment.

  • Generic Functions and Methods: The package includes a set of generic functions and methods that are common across the JuliaConstraints ecosystem. This approach minimizes duplication and facilitates the extension of functionalities across different packages without requiring redundant code.

  • Interface for Learning and Application Transition: One of the pivotal roles of ConstraintCommons.jl is to provide a shared interface that bridges the gap between learning packages (e.g., CompositionalNetworks, QUBOConstraints, and ConstraintTranslator) and basic functionality packages. This interface ensures that once a learning process is complete, the resulting models or solutions can be directly utilized with the basic packages, eliminating the need for users to manage multiple package dependencies actively.

  • Simplifying the User Experience: By ensuring that learning outcomes are compatible with the fundamental packages for constraint programming, ConstraintCommons.jl simplifies the workflow for end-users. Once the learning aspect of problem modeling is completed, users can proceed with their projects relying solely on the basic packages, streamlining the development process and enhancing usability.

  • Impact on the JuliaConstraints Ecosystem: ConstraintCommons.jl plays a critical role in the JuliaConstraints ecosystem by providing the foundational elements that enable package interoperability and efficient development workflows. Its design emphasizes ease of use and seamless transition between the learning phase of constraint programming and practical application, thereby enhancing productivity and reducing the complexity of developing constraint-based solutions.

Parameters

This section of the package list or extract parameters based on the XCSP3-core specifications. Note that, for the forseeable future, the default constraints specification will follow the XCSP3 format.

# ConstraintCommons.USUAL_CONSTRAINT_PARAMETERSConstant.
julia
const USUAL_CONSTRAINT_PARAMETERS

List of usual constraints parameters (based on XCSP3-core constraints).

julia
const USUAL_CONSTRAINT_PARAMETERS = [
-    :bool,
-    :dim,
-    :id,
-    :language,
-    :op,
-    :pair_vars,
-    :val,
-    :vals,
-]

source


# ConstraintCommons.extract_parametersFunction.
julia
extract_parameters(m::Union{Method, Function}; parameters)

Extracts the intersection between the kargs of m and parameters (defaults to USUAL_CONSTRAINT_PARAMETERS).

source

julia
extract_parameters(s::Symbol, constraints_dict=USUAL_CONSTRAINTS; parameters=ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS)

Return the parameters of the constraint s in constraints_dict.

Arguments

  • s::Symbol: the constraint name.

  • constraints_dict::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

  • parameters::Vector{Symbol}: vector of parameters. Default is ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS.

Example

julia
extract_parameters(:all_different)

source


Performances – TODO

Languages

XCSP3 considers two kinds of structure to recognize languages as core constraints: Automata, Multivalued Decision Diagrams (MMDs).

# ConstraintCommons.AbstractMultivaluedDecisionDiagramType.
julia
AbstractMultivaluedDecisionDiagram

An abstract interface for Multivalued Decision Diagrams (MDD) used in Julia Constraints packages. Requirements:

  • accept(a<:AbstractMultivaluedDecisionDiagram, word): return true if a accepts word.

source


# ConstraintCommons.MDDType.
julia
MDD{S,T} <: AbstractMultivaluedDecisionDiagram

A minimal implementation of a multivalued decision diagram structure.

source


# ConstraintCommons.AbstractAutomatonType.
julia
AbstractAutomaton

An abstract interface for automata used in Julia Constraints packages. Requirements:

  • accept(a<:AbstractAutomaton, word): return true if a accepts word.

source


# ConstraintCommons.AutomatonType.
julia
Automaton{S, T, F <: Union{S, Vector{S}, Set{S}}} <: AbstractAutomaton

A minimal implementation of a deterministic automaton structure.

source


Missing docstring.

Missing docstring for Automaton(a::MDD). Check Documenter's build log for details.

# ConstraintCommons.acceptFunction.
julia
accept(a::Union{Automaton, MDD}, w)

Return true if a accepts the word w and false otherwise.

source

julia
ConstraintCommons.accept(fa::FakeAutomaton, word)

Implement the accept methods for FakeAutomaton.

source


# ConstraintCommons.at_endFunction.
julia
at_end(a::Automaton, s)

Internal method used by accept with Automaton.

source


Performances – TODO

Extensions

We extended some operations for Nothing and Symbol.

Missing docstring.

Missing docstring for Base.:*. Check Documenter's build log for details.

Missing docstring.

Missing docstring for Base.in(::Any, ::Nothing). Check Documenter's build log for details.

Missing docstring.

Missing docstring for Base.isempty(::Nothing). Check Documenter's build log for details.

Performances – TODO

Sampling

During our constraint learning processes, we use sampling to efficiently make partial exploration of search spaces. Follows some sampling utilities.

# ConstraintCommons.oversampleFunction.
julia
oversample(X, f)

Oversample elements of X until the boolean function f has as many true and false configurations.

source


Performances – TODO

Extrema

We need to compute the difference between extrema of various kind of collections in several situations.

# ConstraintCommons.δ_extremaFunction.
julia
δ_extrema(X...)

Compute both the difference between the maximum and the minimum of over all the collections of X.

source


Performances – TODO

Dictionaries

We provide the everuseful incsert! function for dictionaries.

# ConstraintCommons.incsert!Function.
julia
incsert!(d::Union{AbstractDict, AbstractDictionary}, ind, val = 1)

Increase or insert a counter in a dictionary-based collection. The counter insertion defaults to val = 1.

source


Performances – TODO

`,48),o=[n];function r(l,c,p,d,h,m){return i(),a("div",null,o)}const g=s(e,[["render",r]]);export{k as __pageData,g as default}; diff --git a/dev/assets/constraints_constraint_commons.md.PTLdrUW2.lean.js b/dev/assets/constraints_constraint_commons.md.PTLdrUW2.lean.js deleted file mode 100644 index e4e042c..0000000 --- a/dev/assets/constraints_constraint_commons.md.PTLdrUW2.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as a,o as i,a7 as t}from"./chunks/framework.aA95Gx5L.js";const k=JSON.parse('{"title":"ConstraintCommons.jl","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/constraint_commons.md","filePath":"constraints/constraint_commons.md","lastUpdated":null}'),e={name:"constraints/constraint_commons.md"},n=t("",48),o=[n];function r(l,c,p,d,h,m){return i(),a("div",null,o)}const g=s(e,[["render",r]]);export{k as __pageData,g as default}; diff --git a/dev/assets/constraints_constraint_domains.md.Cd0YH57K.js b/dev/assets/constraints_constraint_domains.md.Cd0YH57K.js deleted file mode 100644 index 02a6713..0000000 --- a/dev/assets/constraints_constraint_domains.md.Cd0YH57K.js +++ /dev/null @@ -1,36 +0,0 @@ -import{_ as s,c as i,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/constraint_domains.md","filePath":"constraints/constraint_domains.md","lastUpdated":null}'),n={name:"constraints/constraint_domains.md"},e=t(`

ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints

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.

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.

Commons

# ConstraintDomains.AbstractDomainType.
julia
AbstractDomain

An abstract super type for any domain type. A domain type D <: AbstractDomain must implement the following methods to properly interface AbstractDomain.

  • Base.∈(val, ::D)

  • Base.rand(::D)

  • Base.length(::D) that is the number of elements in a discrete domain, and the distance between bounds or similar for a continuous domain

Additionally, if the domain is used in a dynamic context, it can extend

  • add!(::D, args)

  • delete!(::D, args)

where args depends on D's structure

source


# ConstraintDomains.EmptyDomainType.
julia
EmptyDomain

A struct to handle yet to be defined domains.

source


# ConstraintDomains.domainFunction.
julia
domain()

Construct an EmptyDomain.

source

julia
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
-domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}

Construct a domain of continuous interval(s).

source

julia
domain(values)
-domain(range::R) where {T <: Real, R <: AbstractRange{T}}

Construct either a SetDomain or a \`RangeDomain\`\`.

julia
d1 = domain(1:5)
-d2 = domain([53.69, 89.2, 0.12])
-d3 = domain([2//3, 89//123])
-d4 = domain(4.3)
-d5 = domain(1,42,86.9)

source


# ConstraintDomains.domain_sizeFunction.
julia
domain_size(d <: AbstractDomain)

Fallback method for domain_size(d) that return length(d).

source

julia
domain_size(itv::Intervals)

Return the difference between the highest and lowest values in itv.

source

julia
domain_size(d::D) where D <: DiscreteDomain

Return the maximum distance between two points in d.

source


# ConstraintDomains.get_domainFunction.
julia
get_domain(::AbstractDomain)

Access the internal structure of any domain type.

source


# ConstraintDomains.to_domainsFunction.
julia
to_domains(args...)

Convert various arguments into valid domains format.

source


Extension to Base module

# Base.inFunction.
julia
x::Variable constraint
-value  x::Variable

Check if a variable x is restricted by a constraint::Int, or if a value belongs to the domain of x.

source

julia
var::Int c::Constraint

source

julia
Base.in(value, d <: AbstractDomain)

Fallback method for value ∈ d that returns false.

source

julia
Base.in(x, itv::Intervals)

Return true if x ∈ I for any 'I ∈ itv, false otherwise.x ∈ I\` is equivalent to

  • a < x < b if I = (a, b)

  • a < x ≤ b if I = (a, b]

  • a ≤ x < b if I = [a, b)

  • a ≤ x ≤ b if I = [a, b]

source

julia
Base.in(value, d::D) where D <: DiscreteDomain

Return true if value is a point of d.

source


# Base.randFunction.
julia
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}

Extends Base.rand to (a collection of) domains.

source

julia
Base.rand(itv::Intervals)
-Base.rand(itv::Intervals, i)

Return a random value from itv, specifically from the ith interval if i is specified.

source

julia
Base.rand(d::D) where D <: DiscreteDomain

Draw randomly a point in d.

source

julia
Base.rand(fa::FakeAutomaton)

Extends Base.rand. Currently simply returns fa.

source


# Base.isemptyFunction.
julia
Base.isempty(d <: AbstractDomain)

Fallback method for isempty(d) that return length(d) == 0 which default to 0.

source


# Base.randFunction.
julia
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}

Extends Base.rand to (a collection of) domains.

source

julia
Base.rand(itv::Intervals)
-Base.rand(itv::Intervals, i)

Return a random value from itv, specifically from the ith interval if i is specified.

source

julia
Base.rand(d::D) where D <: DiscreteDomain

Draw randomly a point in d.

source

julia
Base.rand(fa::FakeAutomaton)

Extends Base.rand. Currently simply returns fa.

source


# Base.stringFunction.
julia
Base.string(D::Vector{<:AbstractDomain})
-Base.string(d<:AbstractDomain)

Extends the string method to (a vector of) domains.

source


Performances

Continuous

# ConstraintDomains.ContinuousDomainType.
julia
ContinuousDomain{T <: Real} <: AbstractDomain

An abstract supertype for all continuous domains.

source


# ConstraintDomains.IntervalsType.
julia
Intervals{T <: Real} <: ContinuousDomain{T}

An encapsuler to store a vector of PatternFolds.Interval. Dynamic changes to Intervals are not handled yet.

source


# ConstraintDomains.domainFunction.
julia
domain()

Construct an EmptyDomain.

source

julia
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
-domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}

Construct a domain of continuous interval(s).

source

julia
domain(values)
-domain(range::R) where {T <: Real, R <: AbstractRange{T}}

Construct either a SetDomain or a \`RangeDomain\`\`.

julia
d1 = domain(1:5)
-d2 = domain([53.69, 89.2, 0.12])
-d3 = domain([2//3, 89//123])
-d4 = domain(4.3)
-d5 = domain(1,42,86.9)

source


# ConstraintDomains.domain_sizeFunction.
julia
domain_size(d <: AbstractDomain)

Fallback method for domain_size(d) that return length(d).

source

julia
domain_size(itv::Intervals)

Return the difference between the highest and lowest values in itv.

source

julia
domain_size(d::D) where D <: DiscreteDomain

Return the maximum distance between two points in d.

source


# ConstraintDomains.merge_domainsFunction.
julia
merge_domains(d₁::AbstractDomain, d₂::AbstractDomain)

Merge two domains of same nature (discrete/contiuous).

source


# ConstraintDomains.intersect_domainsFunction.
julia
intersect_domains(d₁, d₂)

Compute the intersections of two domains.

source


# ConstraintDomains.intersect_domains!Function.
julia
intersect_domains!(is, i, new_itvls)

Compute the intersections of a domain with an interval and store the results in new_itvls.

Arguments

  • is::IS: a collection of intervals.

  • i::I: an interval.

  • new_itvls::Vector{I}: a vector to store the results.

source


# ConstraintDomains.sizeFunction.
julia
Base.size(i::I) where {I <: Interval}

Defines the size of an interval as its span.

source


Extension to Base module

# Base.lengthFunction.
julia
length(layer)

Return the number of operations in a layer.

source

julia
Base.length(icn)

Return the total number of operations of an ICN.

source

julia
Base.rand(d <: AbstractDomain)

Fallback method for length(d) that return 0.

source

julia
Base.length(itv::Intervals)

Return the sum of the length of each interval in itv.

source

julia
Base.length(d::D) where D <: DiscreteDomain

Return the number of points in d.

source


# Base.randFunction.
julia
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}

Extends Base.rand to (a collection of) domains.

source

julia
Base.rand(itv::Intervals)
-Base.rand(itv::Intervals, i)

Return a random value from itv, specifically from the ith interval if i is specified.

source

julia
Base.rand(d::D) where D <: DiscreteDomain

Draw randomly a point in d.

source

julia
Base.rand(fa::FakeAutomaton)

Extends Base.rand. Currently simply returns fa.

source


# Base.inFunction.
julia
x::Variable constraint
-value  x::Variable

Check if a variable x is restricted by a constraint::Int, or if a value belongs to the domain of x.

source

julia
var::Int c::Constraint

source

julia
Base.in(value, d <: AbstractDomain)

Fallback method for value ∈ d that returns false.

source

julia
Base.in(x, itv::Intervals)

Return true if x ∈ I for any 'I ∈ itv, false otherwise.x ∈ I\` is equivalent to

  • a < x < b if I = (a, b)

  • a < x ≤ b if I = (a, b]

  • a ≤ x < b if I = [a, b)

  • a ≤ x ≤ b if I = [a, b]

source

julia
Base.in(value, d::D) where D <: DiscreteDomain

Return true if value is a point of d.

source


# Base.stringFunction.
julia
Base.string(D::Vector{<:AbstractDomain})
-Base.string(d<:AbstractDomain)

Extends the string method to (a vector of) domains.

source


Discrete

# ConstraintDomains.DiscreteDomainType.
julia
DiscreteDomain{T <: Number} <: AbstractDomain

An abstract supertype for discrete domains (set, range).

source


# ConstraintDomains.SetDomainType.
julia
SetDomain{T <: Number} <: DiscreteDomain{T}

Domain that stores discrete values as a set of (unordered) points.

source


# ConstraintDomains.RangeDomainType.
julia
RangeDomain

A discrete domain defined by a range <: AbstractRange{Real}. As ranges are immutable in Julia, changes in RangeDomain must use set_domain!.

source


# ConstraintDomains.ArbitraryDomainFunction.
julia
ArbitraryDomain{T} <: DiscreteDomain{T}

A domain type that stores arbitrary values, possibly non numeric, of type T.

source


# ConstraintDomains.domainFunction.
julia
domain()

Construct an EmptyDomain.

source

julia
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
-domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}

Construct a domain of continuous interval(s).

source

julia
domain(values)
-domain(range::R) where {T <: Real, R <: AbstractRange{T}}

Construct either a SetDomain or a \`RangeDomain\`\`.

julia
d1 = domain(1:5)
-d2 = domain([53.69, 89.2, 0.12])
-d3 = domain([2//3, 89//123])
-d4 = domain(4.3)
-d5 = domain(1,42,86.9)

source


# ConstraintDomains.domain_sizeFunction.
julia
domain_size(d <: AbstractDomain)

Fallback method for domain_size(d) that return length(d).

source

julia
domain_size(itv::Intervals)

Return the difference between the highest and lowest values in itv.

source

julia
domain_size(d::D) where D <: DiscreteDomain

Return the maximum distance between two points in d.

source


# ConstraintDomains.add!Function.
julia
add!(d::SetDomain, value)

Add value to the list of points in d.

source


# ConstraintDomains.merge_domainsFunction.
julia
merge_domains(d₁::AbstractDomain, d₂::AbstractDomain)

Merge two domains of same nature (discrete/contiuous).

source


# ConstraintDomains.intersect_domainsFunction.
julia
intersect_domains(d₁, d₂)

Compute the intersections of two domains.

source


# ConstraintDomains.sizeFunction.
julia
Base.size(i::I) where {I <: Interval}

Defines the size of an interval as its span.

source


Extension to Base module

# Base.delete!Function.
julia
Base.delete!(d::SetDomain, value)(d::SetDomain, value)

Delete value from the list of points in d.

source


# Base.lengthFunction.
julia
length(layer)

Return the number of operations in a layer.

source

julia
Base.length(icn)

Return the total number of operations of an ICN.

source

julia
Base.rand(d <: AbstractDomain)

Fallback method for length(d) that return 0.

source

julia
Base.length(itv::Intervals)

Return the sum of the length of each interval in itv.

source

julia
Base.length(d::D) where D <: DiscreteDomain

Return the number of points in d.

source


# Base.randFunction.
julia
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}

Extends Base.rand to (a collection of) domains.

source

julia
Base.rand(itv::Intervals)
-Base.rand(itv::Intervals, i)

Return a random value from itv, specifically from the ith interval if i is specified.

source

julia
Base.rand(d::D) where D <: DiscreteDomain

Draw randomly a point in d.

source

julia
Base.rand(fa::FakeAutomaton)

Extends Base.rand. Currently simply returns fa.

source


# Base.inFunction.
julia
x::Variable constraint
-value  x::Variable

Check if a variable x is restricted by a constraint::Int, or if a value belongs to the domain of x.

source

julia
var::Int c::Constraint

source

julia
Base.in(value, d <: AbstractDomain)

Fallback method for value ∈ d that returns false.

source

julia
Base.in(x, itv::Intervals)

Return true if x ∈ I for any 'I ∈ itv, false otherwise.x ∈ I\` is equivalent to

  • a < x < b if I = (a, b)

  • a < x ≤ b if I = (a, b]

  • a ≤ x < b if I = [a, b)

  • a ≤ x ≤ b if I = [a, b]

source

julia
Base.in(value, d::D) where D <: DiscreteDomain

Return true if value is a point of d.

source


# Base.stringFunction.
julia
Base.string(D::Vector{<:AbstractDomain})
-Base.string(d<:AbstractDomain)

Extends the string method to (a vector of) domains.

source


General

# Base.eltypeFunction.
julia
Base.eltype(::AbstractDomain)

Extend eltype for domains.

source


# Base.convertFunction.
julia
Base.convert(::Type{Union{Intervals, RangeDomain}}, d::Union{Intervals, RangeDomain})

Extends Base.convert for domains.

source


Exploration

# ConstraintDomains.ExploreSettingsType.
julia
ExploreSettings(
-    domains;
-    complete_search_limit = 10^6,
-    max_samplings = sum(domain_size, domains),
-    search = :flexible,
-    solutions_limit = floor(Int, sqrt(max_samplings)),
-)

Settings for the exploration of a search space composed by a collection of domains.

source


# ConstraintDomains._exploreFunction.
julia
_explore(args...)

Internals of the explore function. Behavior is automatically adjusted on the kind of exploration: :flexible, :complete, :partial.

source


# ConstraintDomains.exploreFunction.
julia
explore(domains, concept, param = nothing; search_limit = 1000, solutions_limit = 100)

Search (a part of) a search space and returns a pair of vector of configurations: (solutions, non_solutions). If the search space size is over search_limit, then both solutions and non_solutions are limited to solutions_limit.

Beware that if the density of the solutions in the search space is low, solutions_limit needs to be reduced. This process will be automatic in the future (simple reinforcement learning).

Arguments:

  • domains: a collection of domains

  • concept: the concept of the targeted constraint

  • param: an optional parameter of the constraint

  • sol_number: the required number of solutions (half of the number of configurations), default to 100

source


Parameters

# ConstraintDomains.BoolParameterDomainType.
julia
BoolParameterDomain <: AbstractDomain

A domain to store boolean values. It is used to generate random parameters.

source


# ConstraintDomains.DimParameterDomainType.
julia
DimParameterDomain <: AbstractDomain

A domain to store dimensions. It is used to generate random parameters.

source


# ConstraintDomains.IdParameterDomainType.
julia
IdParameterDomain <: AbstractDomain

A domain to store ids. It is used to generate random parameters.

source


# ConstraintDomains.FakeAutomatonType.
julia
FakeAutomaton{T} <: ConstraintCommons.AbstractAutomaton

A structure to generate pseudo automaton enough for parameter exploration.

source


# ConstraintCommons.acceptFunction.
julia
accept(a::Union{Automaton, MDD}, w)

Return true if a accepts the word w and false otherwise.

source

julia
ConstraintCommons.accept(fa::FakeAutomaton, word)

Implement the accept methods for FakeAutomaton.

source


# ConstraintDomains.fake_automatonFunction.
julia
fake_automaton(d)

Construct a FakeAutomaton.

source


# ConstraintDomains.LanguageParameterDomainType.
julia
LanguageParameterDomain <: AbstractDomain

A domain to store languages. It is used to generate random parameters.

source


# ConstraintDomains.OpParameterDomainType.
julia
OpParameterDomain{T} <: AbstractDomain

A domain to store operators. It is used to generate random parameters.

source


# ConstraintDomains.PairVarsParameterDomainType.
julia
PairVarsParameterDomain{T} <: AbstractDomain

A domain to store values paired with variables. It is used to generate random parameters.

source


# ConstraintDomains.ValParameterDomainType.
julia
ValParameterDomain{T} <: AbstractDomain

A domain to store one value. It is used to generate random parameters.

source


# ConstraintDomains.ValsParameterDomainType.
julia
ValsParameterDomain{T} <: AbstractDomain

A domain to store values. It is used to generate random parameters.

source


# Base.randFunction.
julia
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}

Extends Base.rand to (a collection of) domains.

source

julia
Base.rand(itv::Intervals)
-Base.rand(itv::Intervals, i)

Return a random value from itv, specifically from the ith interval if i is specified.

source

julia
Base.rand(d::D) where D <: DiscreteDomain

Draw randomly a point in d.

source

julia
Base.rand(fa::FakeAutomaton)

Extends Base.rand. Currently simply returns fa.

source


# ConstraintDomains.generate_parametersFunction.
julia
generate_parameters(d<:AbstractDomain, param)

Generates random parameters based on the domain d and the kind of parameters param.

source


`,128),l=[e];function r(h,p,o,d,k,c){return a(),i("div",null,l)}const E=s(n,[["render",r]]);export{u as __pageData,E as default}; diff --git a/dev/assets/constraints_constraint_domains.md.Cd0YH57K.lean.js b/dev/assets/constraints_constraint_domains.md.Cd0YH57K.lean.js deleted file mode 100644 index ea78b82..0000000 --- a/dev/assets/constraints_constraint_domains.md.Cd0YH57K.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as i,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/constraint_domains.md","filePath":"constraints/constraint_domains.md","lastUpdated":null}'),n={name:"constraints/constraint_domains.md"},e=t("",128),l=[e];function r(h,p,o,d,k,c){return a(),i("div",null,l)}const E=s(n,[["render",r]]);export{u as __pageData,E as default}; diff --git a/dev/assets/constraints_constraint_models.md.DjPMcFlD.js b/dev/assets/constraints_constraint_models.md.DjPMcFlD.js deleted file mode 100644 index 8db65b7..0000000 --- a/dev/assets/constraints_constraint_models.md.DjPMcFlD.js +++ /dev/null @@ -1,30 +0,0 @@ -import{_ as n,c as e,m as s,a as i,a7 as a,o as t}from"./chunks/framework.aA95Gx5L.js";const T=JSON.parse('{"title":"ConstraintModels.jl","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/constraint_models.md","filePath":"constraints/constraint_models.md","lastUpdated":null}'),l={name:"constraints/constraint_models.md"},h=a(`

ConstraintModels.jl

Documentation for ConstraintModels.jl.

# ConstraintModels.SudokuInstanceType.
julia
mutable struct SudokuInstance{T <: Integer} <: AbstractMatrix{T}

A struct for SudokuInstances, which is a subtype of AbstractMatrix.

julia
SudokuInstance(A::AbstractMatrix{T})
-SudokuInstance(::Type{T}, n::Int) # fill in blank sudoku of type T
-SudokuInstance(n::Int) # fill in blank sudoku of type Int
-SudokuInstance(::Type{T}) # fill in "standard" 9×9 sudoku of type T
-SudokuInstance() # fill in "standard" 9×9 sudoku of type Int
-SudokuInstance(n::Int, P::Pair{Tuple{Int, Int}, T}...) where {T <: Integer} # construct a sudoku given pairs of coordinates and values
-SudokuInstance(P::Pair{Tuple{Int, Int}, T}...) # again, default to 9×9 sudoku, constructing given pairs

Constructor functions for the SudokuInstance struct.

source


# ConstraintModels.SudokuInstanceMethod.
julia
SudokuInstance(X::Dictionary)

Construct a SudokuInstance with the values X of a solver as input.

source


`,6),p={style:{"border-width":"1px","border-style":"solid","border-color":"black",padding:"1em","border-radius":"25px"}},r=s("a",{id:"Base.Multimedia.display-Tuple{Any, ConstraintModels.SudokuInstance}",href:"#Base.Multimedia.display-Tuple{Any, ConstraintModels.SudokuInstance}"},"#",-1),d=s("b",null,[s("u",null,"Base.Multimedia.display")],-1),o=s("i",null,"Method",-1),k=a(`
julia
display(io::IO, S::SudokuInstance)
-display(S::SudokuInstance) # default to stdout
`,1),c={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},u={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.025ex"},xmlns:"http://www.w3.org/2000/svg",width:"5.481ex",height:"1.136ex",role:"img",focusable:"false",viewBox:"0 -491 2422.4 502","aria-hidden":"true"},g=a('',1),y=[g],C=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"n"),s("mo",null,"×"),s("mi",null,"n")])],-1),b=s("p",null,[s("a",{href:"https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L314-L320",target:"_blank",rel:"noreferrer"},"source")],-1),F=a(`
# Base.Multimedia.displayMethod.
julia
Base.display(X, Val(:sudoku))

Extends Base.display to a sudoku configuration.

source


# Base.Multimedia.displayMethod.
julia
Base.display(S::SudokuInstance)

Extends Base.display to SudokuInstance.

source


# Base.Multimedia.displayMethod.
julia
Base.display(X::Dictionary)

Extends Base.display to a sudoku configuration.

source


# Base.sizeMethod.
julia
Base.size(S::SudokuInstance)

Extends Base.size for SudokuInstance.

source


# ConstraintModels._format_lineMethod.
julia
_format_line(r, M)

Format line of a sudoku grid.

source


# ConstraintModels._format_line_segmentMethod.
julia
_format_line_segment(r, col_pos, M)

Format line segment of a sudoku grid.

source


# ConstraintModels._format_valMethod.
julia
_format_val(a)

Format an integer a into a string for SudokuInstance.

source


# ConstraintModels._get_sep_lineMethod.
julia
_get_sep_line(s, pos_row, M)

Return a line separator.

source


# ConstraintModels.chemical_equilibriumMethod.
julia
chemical_equilibrium(atoms_compounds, elements_weights, standard_free_energy; modeler = :JuMP)

Warning

Even the structure to model problems with continuous domains is available, the default solver is not yet equiped to solve such problems efficiently.

From Wikipedia

In a chemical reaction, chemical equilibrium is the state in which both the reactants and products are present in concentrations which have no further tendency to change with time, so that there is no observable change in the properties of the system. This state results when the forward reaction proceeds at the same rate as the reverse reaction. The reaction rates of the forward and backward reactions are generally not zero, but they are equal. Thus, there are no net changes in the concentrations of the reactants and products. Such a state is known as dynamic equilibrium.

source


# ConstraintModels.golombFunction.
julia
golomb(n, L=n²)

Model the Golomb problem of n marks on the ruler 0:L. The modeler argument accepts :raw, and :JuMP (default), which refer respectively to the solver internal model, the MathOptInterface model, and the JuMP model.

source


# ConstraintModels.magic_squareMethod.
julia
magic_square(n; modeler = :JuMP)

Create a model for the magic square problem of order n. The modeler argument accepts :JuMP (default), which refer to the solver the JuMP model.

source


# ConstraintModels.mincutMethod.
julia
mincut(graph; source, sink, interdiction =0, modeler = :JuMP)

Compute the minimum cut of a graph.

Arguments:

  • graph: Any matrix <: AbstractMatrix that describes the capacities of the graph

  • source: Id of the source node; must be set

  • sink: Id of the sink node; must be set

  • interdiction: indicates the number of forbidden links

  • modeler: Default to :JuMP.

source


# ConstraintModels.n_queensMethod.
julia
n_queens(n; modeler = :JuMP)

Create a model for the n-queens problem with n queens. The modeler argument accepts :JuMP (default), which refer to the JuMP model.

source


# ConstraintModels.qapMethod.
julia
qap(n, weigths, distances; modeler = :JuMP)

Modelize an instance of the Quadractic Assignment Problem with

  • n: number of both facilities and locations

  • weights: Matrix of the weights of each pair of facilities

  • distances: Matrix of distances between locations

  • modeler: Default to :JuMP. No other modeler available for now.

From Wikipedia

There are a set of n facilities and a set of n locations. For each pair of locations, a distance is specified and for each pair of facilities a weight or flow is specified (e.g., the amount of supplies transported between the two facilities). The problem is to assign all facilities to different locations with the goal of minimizing the sum of the distances multiplied by the corresponding flows.

source


# ConstraintModels.schedulingMethod.
julia
scheduling(processing_time, due_date; modeler=:JuMP)

Create a model for the n-queens problem with n queens. The modeler argument accepts :JuMP (default), which refer to the JuMP model.

Warning

The model seems to have a flaw. Needs to be investigated.

source


# ConstraintModels.sudokuMethod.
julia
sudoku(n; start= Dictionary{Int, Int}(), modeler = :JuMP)

Create a model for the sudoku problem of domain 1:n² with optional starting values. The modeler argument accepts :raw, :MOI, and :JuMP (default), which refer respectively to the solver internal model, the MathOptInterface model, and the JuMP model.

julia
# Construct a JuMP model \`m\` and its associated matrix \`grid\` for sudoku 9×9
-m, grid = sudoku(3)
-
-# Same with a starting instance
-instance = [
-    9  3  0  0  0  0  0  4  0
-    0  0  0  0  4  2  0  9  0
-    8  0  0  1  9  6  7  0  0
-    0  0  0  4  7  0  0  0  0
-    0  2  0  0  0  0  0  6  0
-    0  0  0  0  2  3  0  0  0
-    0  0  8  5  3  1  0  0  2
-    0  9  0  2  8  0  0  0  0
-    0  7  0  0  0  0  0  5  3
-]
-m, grid = sudoku(3, start = instance)
-
-# Run the solver
-optimize!(m)
-
-# Retrieve and display the values
-solution = value.(grid)
-display(solution, Val(:sudoku))

source


`,33);function E(m,v,f,B,_,M){return t(),e("div",null,[h,s("div",p,[r,i(" "),d,i(" — "),o,i(". "),k,s("p",null,[i("Displays an "),s("mjx-container",c,[(t(),e("svg",u,y)),C]),i(" SudokuInstance.")]),b]),F])}const j=n(l,[["render",E]]);export{T as __pageData,j as default}; diff --git a/dev/assets/constraints_constraint_models.md.DjPMcFlD.lean.js b/dev/assets/constraints_constraint_models.md.DjPMcFlD.lean.js deleted file mode 100644 index f29765d..0000000 --- a/dev/assets/constraints_constraint_models.md.DjPMcFlD.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as n,c as e,m as s,a as i,a7 as a,o as t}from"./chunks/framework.aA95Gx5L.js";const T=JSON.parse('{"title":"ConstraintModels.jl","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/constraint_models.md","filePath":"constraints/constraint_models.md","lastUpdated":null}'),l={name:"constraints/constraint_models.md"},h=a("",6),p={style:{"border-width":"1px","border-style":"solid","border-color":"black",padding:"1em","border-radius":"25px"}},r=s("a",{id:"Base.Multimedia.display-Tuple{Any, ConstraintModels.SudokuInstance}",href:"#Base.Multimedia.display-Tuple{Any, ConstraintModels.SudokuInstance}"},"#",-1),d=s("b",null,[s("u",null,"Base.Multimedia.display")],-1),o=s("i",null,"Method",-1),k=a("",1),c={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},u={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.025ex"},xmlns:"http://www.w3.org/2000/svg",width:"5.481ex",height:"1.136ex",role:"img",focusable:"false",viewBox:"0 -491 2422.4 502","aria-hidden":"true"},g=a("",1),y=[g],C=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"n"),s("mo",null,"×"),s("mi",null,"n")])],-1),b=s("p",null,[s("a",{href:"https://github.com/JuliaConstraints/ConstraintModels.jl/blob/v0.1.9/src/sudoku.jl#L314-L320",target:"_blank",rel:"noreferrer"},"source")],-1),F=a("",33);function E(m,v,f,B,_,M){return t(),e("div",null,[h,s("div",p,[r,i(" "),d,i(" — "),o,i(". "),k,s("p",null,[i("Displays an "),s("mjx-container",c,[(t(),e("svg",u,y)),C]),i(" SudokuInstance.")]),b]),F])}const j=n(l,[["render",E]]);export{T as __pageData,j as default}; diff --git a/dev/assets/constraints_constraints.md.ijIsQmJK.js b/dev/assets/constraints_constraints.md.ijIsQmJK.js deleted file mode 100644 index 0789f9f..0000000 --- a/dev/assets/constraints_constraints.md.ijIsQmJK.js +++ /dev/null @@ -1,3 +0,0 @@ -import{_ as s,c as i,o as t,a7 as a}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/constraints.md","filePath":"constraints/constraints.md","lastUpdated":null}'),n={name:"constraints/constraints.md"},e=a(`

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Constraints.jl is a pivotal package within the JuliaConstraints ecosystem, designed to facilitate the definition, manipulation, and application of constraints in constraint programming (CP). This package is central to handling both standard and complex constraints, making it an indispensable tool for developers and researchers working in CP.

Key Features and Functionalities

  • Integration of XCSP3-core Constraints: One of the standout features of Constraints.jl is its incorporation of the XCSP3-core constraints as usual constraints within Julia. This integration ensures that users can define and work with a wide range of standard constraints, following the specifications outlined in the XCSP3-core, directly in Julia. The use of USUAL_CONSTRAINTS dictionary allows for straightforward addition and manipulation of these constraints, enhancing the package's utility and flexibility.

  • Learning Package Integration: Constraints.jl goes beyond traditional constraint handling by offering the capability to include results from various learning packages within the JuliaConstraints organization. This feature allows for the enhancement of usual constraints and those from the Global Constraints Catalog with learned parameters and behaviors, significantly improving constraint applicability and performance in complex CP problems.

  • Constraint Definition and Symmetry Handling: The package provides a simple yet powerful syntax for defining new constraints (@usual) and managing their symmetries through the USUAL_SYMMETRIES dictionary. This approach simplifies the creation of new constraints and the optimization of constraint search spaces by avoiding redundant explorations.

  • Advanced Constraint Functionalities: At the core of Constraints.jl is the Constraint type, encapsulating the essential elements of a constraint, including its concept (a Boolean function determining satisfaction) and an error function (providing a preference measure over invalid assignments). These components are crucial for defining how constraints behave and are evaluated within a CP model.

  • Flexible Constraint Application: The package supports a range of methods for interacting with constraints, such as args, concept, error_f, params_length, symmetries, and xcsp_intension. These methods offer users the ability to examine constraint properties, apply constraints to variable assignments, and work with intensional constraints defined by predicates. Such flexibility is vital for tailoring constraint behavior to specific problems and contexts.

Enabling Advanced Modeling in Constraint Programming

Constraints.jl embodies the JuliaConstraints ecosystem's commitment to providing robust, flexible tools for constraint programming. By integrating standard constraints, facilitating the incorporation of learned behaviors, and offering comprehensive tools for constraint definition and application, Constraints.jl significantly enhances the modeling capabilities available to CP practitioners. Whether for educational purposes, research, or solving practical CP problems, Constraints.jl offers a sophisticated, user-friendly platform for working with constraints in Julia.

Basic tools

# Constraints.USUAL_SYMMETRIESConstant.
julia
USUAL_SYMMETRIES

A Dictionary that contains the function to apply for each symmetry to avoid searching a whole space.

source


# Constraints.ConstraintType.
julia
Constraint

Parametric structure with the following fields.

  • concept: a Boolean function that, given an assignment x, outputs true if x satisfies the constraint, and false otherwise.

  • error: a positive function that works as preferences over invalid assignments. Return 0.0 if the constraint is satisfied, and a strictly positive real otherwise.

source


# Constraints.conceptFunction.
julia
concept(c::Constraint)

Return the concept (function) of constraint c. concept(c::Constraint, x...; param = nothing) Apply the concept of c to values x and optionally param.

source

julia
concept(s::Symbol, args...; kargs...)

Return the concept of the constraint s applied to args and kargs. This is a shortcut for concept(USUAL_CONSTRAINTS[s])(args...; kargs...).

Arguments

  • s::Symbol: the constraint name.

  • args...: the arguments to apply the concept to.

  • kargs...: the keyword arguments to apply the concept to.

Example

julia
concept(:all_different, [1, 2, 3])

source


# Constraints.error_fFunction.
julia
error_f(c::Constraint)

Return the error function of constraint c. error_f(c::Constraint, x; param = nothing) Apply the error function of c to values x and optionally param.

source


# Constraints.argsFunction.
julia
args(c::Constraint)

Return the expected length restriction of the arguments in a constraint c. The value nothing indicates that any strictly positive number of value is accepted.

source


# Constraints.params_lengthFunction.
julia
params_length(c::Constraint)

Return the expected length restriction of the arguments in a constraint c. The value nothing indicates that any strictly positive number of parameters is accepted.

source


# Constraints.symmetriesFunction.
julia
symmetries(c::Constraint)

Return the list of symmetries of c.

source


# Constraints.make_errorFunction.
julia
make_error(symb::Symbol)

Create a function that returns an error based on the predicate of the constraint identified by the symbol provided.

Arguments

  • symb::Symbol: The symbol used to determine the error function to be returned. The function first checks if a predicate with the prefix "icn_" exists in the Constraints module. If it does, it returns that function. If it doesn't, it checks for a predicate with the prefix "error_". If that exists, it returns that function. If neither exists, it returns a function that evaluates the predicate with the prefix "concept_" and returns the negation of its result cast to Float64.

Returns

  • Function: A function that takes in a variable x and an arbitrary number of parameters params. The function returns a Float64.

Examples

julia
e = make_error(:all_different)
-e([1, 2, 3]) # Returns 0.0
-e([1, 1, 3]) # Returns 1.0

source


# Constraints.shrink_conceptFunction.
julia
shrink_concept(s)

Simply delete the concept_ part of symbol or string starting with it. TODO: add a check with a warning if s starts with something different.

source


# Constraints.concept_vs_errorFunction.
julia
concept_vs_error(c, e, args...; kargs...)

Compare the results of a concept function and an error function for the same inputs. It is mainly used for testing purposes.

Arguments

  • c: The concept function.

  • e: The error function.

  • args...: Positional arguments to be passed to both the concept and error functions.

  • kargs...: Keyword arguments to be passed to both the concept and error functions.

Returns

  • Boolean: Returns true if the result of the concept function is not equal to whether the result of the error function is greater than 0.0. Otherwise, it returns false.

Examples

julia
concept_vs_error(all_different, make_error(:all_different), [1, 2, 3]) # Returns false

source


Usual constraints (based on and including XCSP3-core categories)

# Constraints.USUAL_CONSTRAINTSConstant.
julia
USUAL_CONSTRAINTS::Dict

Dictionary that contains all the usual constraints defined in Constraint.jl. It is based on XCSP3-core specifications available at https://arxiv.org/abs/2009.00514

Adding a new constraint is as simple as defining a new function with the same name as the constraint and using the @usual macro to define it. The macro will take care of adding the new constraint to the USUAL_CONSTRAINTS dictionary.

Example

julia
@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals)

source


# Constraints.describeFunction.
julia
describe(constraints::Dict{Symbol,Constraint}=USUAL_CONSTRAINTS; width=150)

Return a pretty table with the description of the constraints in constraints.

Arguments

  • constraints::Dict{Symbol,Constraint}: dictionary of constraints to describe. Default is USUAL_CONSTRAINTS.

  • width::Int: width of the table.

Example

julia
describe()

source


# ConstraintCommons.extract_parametersFunction.
julia
extract_parameters(m::Union{Method, Function}; parameters)

Extracts the intersection between the kargs of m and parameters (defaults to USUAL_CONSTRAINT_PARAMETERS).

source

julia
extract_parameters(s::Symbol, constraints_dict=USUAL_CONSTRAINTS; parameters=ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS)

Return the parameters of the constraint s in constraints_dict.

Arguments

  • s::Symbol: the constraint name.

  • constraints_dict::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

  • parameters::Vector{Symbol}: vector of parameters. Default is ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS.

Example

julia
extract_parameters(:all_different)

source


# Constraints.@usualMacro.
julia
usual(ex::Expr)

This macro is used to define a new constraint or update an existing one in the USUAL_CONSTRAINTS dictionary. It takes an expression ex as input, which represents the definition of a constraint.

Here's a step-by-step explanation of what the macro does:

  1. It first extracts the symbol of the concept from the input expression. This symbol is expected to be the first argument of the first argument of the expression. For example, if the expression is @usual all_different(x; y=1), the symbol would be :all_different.

  2. It then calls the shrink_concept function on the symbol to get a simplified version of the concept symbol.

  3. It initializes a dictionary defaults to store whether each keyword argument of the concept has a default value or not.

  4. It checks if the expression has more than two arguments. If it does, it means that there are keyword arguments present. It then loops over these keyword arguments. If a keyword argument is a symbol, it means it doesn't have a default value, so it adds an entry to the defaults dictionary with the keyword argument as the key and false as the value. If a keyword argument is not a symbol, it means it has a default value, so it adds an entry to the defaults dictionary with the keyword argument as the key and true as the value.

  5. It calls the make_error function on the simplified concept symbol to generate an error function for the constraint.

  6. It evaluates the input expression to get the concept function.

  7. It checks if the USUAL_CONSTRAINTS dictionary already contains an entry for the simplified concept symbol. If it does, it adds the defaults dictionary to the parameters of the existing constraint. If it doesn't, it creates a new constraint with the concept function, a description, the error function, and the defaults dictionary as the parameters, and adds it to the USUAL_CONSTRAINTS dictionary.

This macro is used to make it easier to define and update constraints in a consistent and possibly automated way.

Arguments

  • ex::Expr: expression to parse.

Example

julia
@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals)

source


# Constraints.constraints_parametersFunction.
julia
constraints_parameters(C=USUAL_CONSTRAINTS)

Return a pretty table with the parameters of the constraints in C.

Arguments

  • C::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

Example

julia
constraints_parameters()

source


# Constraints.constraints_descriptionsFunction.
julia
constraints_descriptions(C=USUAL_CONSTRAINTS)

Return a pretty table with the descriptions of the constraints in C.

Arguments

  • C::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

Example

julia
constraints_descriptions()

source


# Constraints.conceptFunction.
julia
concept(c::Constraint)

Return the concept (function) of constraint c. concept(c::Constraint, x...; param = nothing) Apply the concept of c to values x and optionally param.

source

julia
concept(s::Symbol, args...; kargs...)

Return the concept of the constraint s applied to args and kargs. This is a shortcut for concept(USUAL_CONSTRAINTS[s])(args...; kargs...).

Arguments

  • s::Symbol: the constraint name.

  • args...: the arguments to apply the concept to.

  • kargs...: the keyword arguments to apply the concept to.

Example

julia
concept(:all_different, [1, 2, 3])

source


`,42),r=[e];function o(l,p,h,c,d,k){return t(),i("div",null,r)}const b=s(n,[["render",o]]);export{u as __pageData,b as default}; diff --git a/dev/assets/constraints_constraints.md.ijIsQmJK.lean.js b/dev/assets/constraints_constraints.md.ijIsQmJK.lean.js deleted file mode 100644 index 61c2f9c..0000000 --- a/dev/assets/constraints_constraints.md.ijIsQmJK.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as i,o as t,a7 as a}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/constraints.md","filePath":"constraints/constraints.md","lastUpdated":null}'),n={name:"constraints/constraints.md"},e=a("",42),r=[e];function o(l,p,h,c,d,k){return t(),i("div",null,r)}const b=s(n,[["render",o]]);export{u as __pageData,b as default}; diff --git a/dev/assets/constraints_counting_summing_constraints.md.BIdrSepq.js b/dev/assets/constraints_counting_summing_constraints.md.BIdrSepq.js deleted file mode 100644 index b9b9241..0000000 --- a/dev/assets/constraints_counting_summing_constraints.md.BIdrSepq.js +++ /dev/null @@ -1,39 +0,0 @@ -import{_ as s,c as i,o as a,a7 as n}from"./chunks/framework.aA95Gx5L.js";const y=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/counting_summing_constraints.md","filePath":"constraints/counting_summing_constraints.md","lastUpdated":null}'),h={name:"constraints/counting_summing_constraints.md"},t=n(`

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Counting and Summing Constraints

# Constraints.xcsp_sumFunction.
julia
xcsp_sum(list, coeffs, condition)

Return true if the sum of the variables in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • coeffs::Vector{Int}: list of coefficients to use.

  • condition: condition to satisfy.

Variants

  • :sum: Global constraint ensuring that the sum of the variables in x satisfies a given condition.
julia
concept(:sum, x; op===, pair_vars=ones(x), val)
-concept(:sum)(x; op===, pair_vars=ones(x), val)

Examples

julia
c = concept(:sum)
-
-c([1, 2, 3, 4, 5]; op===, val=15)
-c([1, 2, 3, 4, 5]; op===, val=2)
-c([1, 2, 3, 4, 3]; op=≤, val=15)
-c([1, 2, 3, 4, 3]; op=≤, val=3)

source


# Constraints.xcsp_countFunction.
julia
xcsp_count(list, values, condition)

Return true if the number of occurrences of the values in values in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • values::Vector{Int}: list of values to check.

  • condition: condition to satisfy.

Variants

  • :count: Constraint ensuring that the number of occurrences of the values in vals in x satisfies the given condition.
julia
concept(:count, x; vals, op, val)
-concept(:count)(x; vals, op, val)
  • :at_least: Constraint ensuring that the number of occurrences of the values in vals in x is at least val.
julia
concept(:at_least, x; vals, val)
-concept(:at_least)(x; vals, val)
  • :at_most: Constraint ensuring that the number of occurrences of the values in vals in x is at most val.
julia
concept(:at_most, x; vals, val)
-concept(:at_most)(x; vals, val)
  • :exactly: Constraint ensuring that the number of occurrences of the values in vals in x is exactly val.
julia
concept(:exactly, x; vals, val)
-concept(:exactly)(x; vals, val)

Examples

julia
c = concept(:count)
-
-c([2, 1, 4, 3]; vals=[1, 2, 3, 4], op=≥, val=2)
-c([1, 2, 3, 4]; vals=[1, 2], op==, val=2)
-c([2, 1, 4, 3]; vals=[1, 2], op=≤, val=1)

source


# Constraints.xcsp_nvaluesFunction.
julia
xcsp_nvalues(list, condition, except)

Return true if the number of distinct values in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • condition: condition to satisfy.

  • except::Union{Nothing, Vector{Int}}: list of values to exclude. Default is nothing.

Variants

  • :nvalues: The nValues constraint specifies that the number of distinct values in the list of variables x is equal to a given value. The constraint is defined by the following expression: nValues(x, op, val) where x is a list of variables, op is a comparison operator, and val is an integer value.
julia
concept(:nvalues, x; op, val)
-concept(:nvalues)(x; op, val)

Examples

julia
c = concept(:nvalues)
-
-c([1, 2, 3, 4, 5]; op = ==, val = 5)
-c([1, 2, 3, 4, 5]; op = ==, val = 2)
-c([1, 2, 3, 4, 3]; op = <=, val = 5)
-c([1, 2, 3, 4, 3]; op = <=, val = 3)

source


# Constraints.xcsp_cardinalityFunction.
julia
xcsp_cardinality(list, values, occurs, closed)

Return true if the number of occurrences of the values in values in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • values::Vector{Int}: list of values to check.

  • occurs::Vector{Int}: list of occurrences to check.

  • closed::Bool: whether the constraint is closed or not.

Variants

  • :cardinality: The cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables.
julia
concept(:cardinality, x; bool=false, vals)
-concept(:cardinality)(x; bool=false, vals)
  • :cardinality_closed: The closed cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. It is closed, meaning that all values in the domain of the variables must be considered.
julia
concept(:cardinality_closed, x; vals)
-concept(:cardinality_closed)(x; vals)
  • :cardinality_open: The open cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. It is open, meaning that only the values in the list of values must be considered.
julia
concept(:cardinality_open, x; vals)
-concept(:cardinality_open)(x; vals)

Examples

julia
c = concept(:cardinality)
-
-c([2, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3])
-c([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=false)
-c([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=true)
-c([2, 5, 10, 10]; vals=[2 1; 5 1; 10 2])
-c([2, 5, 10, 10]; vals=[2 0 1 42; 5 1 3 7; 10 2 3 -4])
-c([2, 5, 5, 10]; vals=[2 0 1; 5 1 3; 10 2 3])
-c([2, 5, 10, 8]; vals=[2 1; 5 1; 10 2])
-c([5, 5, 5, 10]; vals=[2 0 1 42; 5 1 3 7; 10 2 3 -4])
-
-cc = concept(:cardinality_closed)
-cc([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3])
-
-co = concept(:cardinality_open)
-co([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3])

source


`,10),k=[t];function l(p,e,E,r,d,g){return a(),i("div",null,k)}const C=s(h,[["render",l]]);export{y as __pageData,C as default}; diff --git a/dev/assets/constraints_counting_summing_constraints.md.BIdrSepq.lean.js b/dev/assets/constraints_counting_summing_constraints.md.BIdrSepq.lean.js deleted file mode 100644 index f9b7043..0000000 --- a/dev/assets/constraints_counting_summing_constraints.md.BIdrSepq.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as i,o as a,a7 as n}from"./chunks/framework.aA95Gx5L.js";const y=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/counting_summing_constraints.md","filePath":"constraints/counting_summing_constraints.md","lastUpdated":null}'),h={name:"constraints/counting_summing_constraints.md"},t=n("",10),k=[t];function l(p,e,E,r,d,g){return a(),i("div",null,k)}const C=s(h,[["render",l]]);export{y as __pageData,C as default}; diff --git a/dev/assets/constraints_elementary_constraints.md.BbiPuUtE.js b/dev/assets/constraints_elementary_constraints.md.BbiPuUtE.js deleted file mode 100644 index 5912c07..0000000 --- a/dev/assets/constraints_elementary_constraints.md.BbiPuUtE.js +++ /dev/null @@ -1,5 +0,0 @@ -import{_ as i,c as s,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const g=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/elementary_constraints.md","filePath":"constraints/elementary_constraints.md","lastUpdated":null}'),n={name:"constraints/elementary_constraints.md"},e=t(`

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Elementary Constraints

# Constraints.xcsp_instantiationFunction.
julia
xcsp_instantiation(; list, values)

Return true if the instantiation constraint is satisfied, false otherwise. The instantiation constraint is a global constraint used in constraint programming that ensures that a list of variables takes on a specific set of values in a specific order.

Arguments

  • list::AbstractVector: list of values to check.

  • values::AbstractVector: list of values to check against.

Variants

  • :instantiation: The instantiation constraint is a global constraint used in constraint programming that ensures that a list of variables takes on a specific set of values in a specific order.
julia
concept(:instantiation, x; pair_vars)
-concept(:instantiation)(x; pair_vars)

Examples

julia
c = concept(:instantiation)
-
-c([1, 2, 3, 4, 5]; pair_vars=[1, 2, 3, 4, 5])
-c([1, 2, 3, 4, 5]; pair_vars=[1, 2, 3, 4, 6])

source


`,4),l=[e];function h(r,p,k,o,d,E){return a(),s("div",null,l)}const C=i(n,[["render",h]]);export{g as __pageData,C as default}; diff --git a/dev/assets/constraints_elementary_constraints.md.BbiPuUtE.lean.js b/dev/assets/constraints_elementary_constraints.md.BbiPuUtE.lean.js deleted file mode 100644 index 0ae1790..0000000 --- a/dev/assets/constraints_elementary_constraints.md.BbiPuUtE.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as s,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const g=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/elementary_constraints.md","filePath":"constraints/elementary_constraints.md","lastUpdated":null}'),n={name:"constraints/elementary_constraints.md"},e=t("",4),l=[e];function h(r,p,k,o,d,E){return a(),s("div",null,l)}const C=i(n,[["render",h]]);export{g as __pageData,C as default}; diff --git a/dev/assets/constraints_generic_constraints.md.WUfYZUE9.js b/dev/assets/constraints_generic_constraints.md.WUfYZUE9.js deleted file mode 100644 index ec95cc2..0000000 --- a/dev/assets/constraints_generic_constraints.md.WUfYZUE9.js +++ /dev/null @@ -1,39 +0,0 @@ -import{_ as e,c as a,m as s,a as i,a7 as n,o as t}from"./chunks/framework.aA95Gx5L.js";const N=JSON.parse('{"title":"Generic Constraints","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/generic_constraints.md","filePath":"constraints/generic_constraints.md","lastUpdated":null}'),l={name:"constraints/generic_constraints.md"},h=n('

Generic Constraints

In the XCSP³-core standard, generic constraints are categorized into two main types: intention and extension constraints.

Intention Constraints

',3),p={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},k={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.025ex"},xmlns:"http://www.w3.org/2000/svg",width:"1.294ex",height:"1.025ex",role:"img",focusable:"false",viewBox:"0 -442 572 453","aria-hidden":"true"},r=s("g",{stroke:"currentColor",fill:"currentColor","stroke-width":"0",transform:"scale(1,-1)"},[s("g",{"data-mml-node":"math"},[s("g",{"data-mml-node":"mi"},[s("path",{"data-c":"1D465",d:"M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z",style:{"stroke-width":"3"}})])])],-1),d=[r],o=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"x")])],-1),c={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},E={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.464ex"},xmlns:"http://www.w3.org/2000/svg",width:"1.109ex",height:"1.464ex",role:"img",focusable:"false",viewBox:"0 -442 490 647","aria-hidden":"true"},g=s("g",{stroke:"currentColor",fill:"currentColor","stroke-width":"0",transform:"scale(1,-1)"},[s("g",{"data-mml-node":"math"},[s("g",{"data-mml-node":"mi"},[s("path",{"data-c":"1D466",d:"M21 287Q21 301 36 335T84 406T158 442Q199 442 224 419T250 355Q248 336 247 334Q247 331 231 288T198 191T182 105Q182 62 196 45T238 27Q261 27 281 38T312 61T339 94Q339 95 344 114T358 173T377 247Q415 397 419 404Q432 431 462 431Q475 431 483 424T494 412T496 403Q496 390 447 193T391 -23Q363 -106 294 -155T156 -205Q111 -205 77 -183T43 -117Q43 -95 50 -80T69 -58T89 -48T106 -45Q150 -45 150 -87Q150 -107 138 -122T115 -142T102 -147L99 -148Q101 -153 118 -160T152 -167H160Q177 -167 186 -165Q219 -156 247 -127T290 -65T313 -9T321 21L315 17Q309 13 296 6T270 -6Q250 -11 231 -11Q185 -11 150 11T104 82Q103 89 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z",style:{"stroke-width":"3"}})])])],-1),y=[g],C=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"y")])],-1),u={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},m={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.464ex"},xmlns:"http://www.w3.org/2000/svg",width:"5.42ex",height:"1.686ex",role:"img",focusable:"false",viewBox:"0 -540 2395.6 745","aria-hidden":"true"},Q=n('',1),F=[Q],T=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"x"),s("mo",null,"<"),s("mi",null,"y")])],-1),f=n('

Note that the intention constraint is not directly available through the JC-API in Constraints.jl. It is designed as such since defining a constraint through a predicate is the natural way.

We provide a straightforward example through the :dist_different constraint on how to define and add such a constraint in the USUAL_CONSTRAINTS collection.

Higher level modeling language such as JuMP should provide a Intention interface.

Defining an intention constraint in JC-API

',4),b=s("code",null,"dist_different",-1),x=s("em",null,"Constraints.jl",-1),v=s("code",null,"dist_different",-1),_={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},B={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.025ex"},xmlns:"http://www.w3.org/2000/svg",width:"1.294ex",height:"1.025ex",role:"img",focusable:"false",viewBox:"0 -442 572 453","aria-hidden":"true"},w=s("g",{stroke:"currentColor",fill:"currentColor","stroke-width":"0",transform:"scale(1,-1)"},[s("g",{"data-mml-node":"math"},[s("g",{"data-mml-node":"mi"},[s("path",{"data-c":"1D465",d:"M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z",style:{"stroke-width":"3"}})])])],-1),H=[w],A=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"x")])],-1),D={class:"MathJax",jax:"SVG",display:"true",style:{direction:"ltr",display:"block","text-align":"center",margin:"1em 0",position:"relative"}},V={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.566ex"},xmlns:"http://www.w3.org/2000/svg",width:"25.797ex",height:"2.262ex",role:"img",focusable:"false",viewBox:"0 -750 11402.4 1000","aria-hidden":"true"},j=n('',1),M=[j],I=s("mjx-assistive-mml",{unselectable:"on",display:"block",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",overflow:"hidden",width:"100%"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},[s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|"),s("mi",null,"x"),s("mo",{stretchy:"false"},"["),s("mn",null,"1"),s("mo",{stretchy:"false"},"]"),s("mo",null,"−"),s("mi",null,"x"),s("mo",{stretchy:"false"},"["),s("mn",null,"2"),s("mo",{stretchy:"false"},"]"),s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|"),s("mo",null,"≠"),s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|"),s("mi",null,"x"),s("mo",{stretchy:"false"},"["),s("mn",null,"3"),s("mo",{stretchy:"false"},"]"),s("mo",null,"−"),s("mi",null,"x"),s("mo",{stretchy:"false"},"["),s("mn",null,"4"),s("mo",{stretchy:"false"},"]"),s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|")])],-1),P=n(`

The constraint is then added to the usual constraints collection.

julia
const description_dist_different = """
-Ensures that the distances between marks on the ruler are unique.
-"""
-
-# Define the predicate
-predicate_dist_different(x) = abs(x[1] - x[2])  abs(x[3] - x[4])
-
-# Add it to usual constraints
-@usual concept_dist_different(x) = xcsp_intension(
-    list = x,
-    predicate = predicate_dist_different
-)

Please check the section dedicated to the Golomb Ruler problem to see a use for this constraint. <!– TODO: Golomb Ruler –>

APIs

Note that the intension constraint is not directly available through the JC-API in Constraints.jl. It is designed as such since defining a constraint through a predicate is the natural way.

We provide here a usage example for the :dist_different constraint, previously added to the USUAL_CONSTRAINTS collection.

Higher level modeling language such as JuMP should provide an Intension interface.

julia
concept(:dist_different, x)
-concept(:dist_different)(x)
julia
# Defines the DistDifferent constraint
-c = x -> xcsp_intension(
-    list = x,
-    predicate = y -> abs(y[1] - y[2])  abs(y[3] - y[4])
-)
-
-c([1, 2, 3, 3]) # true
-c([1, 2, 3, 4]) # false
julia
# TODO: How to handle intention in JuMP/MOI
julia
# TODO: How to handle intention in JuMP/MOI

Test for DocumenterVitePress Issue

julia
c = concept(:dist_different)
-c([1, 2, 3, 3]) && !c([1, 2, 3, 4])
true
julia
c = concept(:dist_different)
-c([1, 2, 3, 3]) && !c([1, 2, 3, 4])
true

Specific documentation

# Constraints.xcsp_intensionFunction.
julia
xcsp_intension(list, predicate)

An intensional constraint is usually defined from a predicate over list. As such it encompass any generic constraint.

Arguments

  • list::Vector{Int}: A list of variables

  • predicate::Function: A predicate over list

Variants

  • :dist_different: A constraint ensuring that the distances between marks on the ruler are unique. Specifically, it checks that the distance between x[1] and x[2], and the distance between x[3] and x[4], are different. This constraint is fundamental in ensuring the validity of a Golomb ruler, where no two pairs of marks should have the same distance between them.
julia
concept(:dist_different, x)
-concept(:dist_different)(x)

Examples

@example
2 + 2
@example
2 + 2
@example
using Constraints # hide
-c = concept(:dist_different)
-c([1, 2, 3, 3]) && !c([1, 2, 3, 4])
@example
using Constraints # hide
-c = concept(:dist_different)
-c([1, 2, 3, 3]) && !c([1, 2, 3, 4])

source


Extension Constraints

These are constraints that are defined by explicitly listing all the tuples of values that satisfy the constraint. They are called extensional because they are defined by the set of values they allow. For example, a binary constraint that specifies that a variable X must be either 1 or 2 and a variable Y must be either 3 or 4 could be defined extensionally by the set of tuples {(1,3), (1,4), (2,3), (2,4)}.

These two types of constraints provide a flexible way to define complex relationships between variables in constraint programming.

XCSP in Constraints.jl {#XCSP-in-Constraints.jl}

# Constraints.xcsp_extensionFunction.
julia
xcsp_extension(; list, supports=nothing, conflicts=nothing)

Global constraint enforcing that the tuple x matches a configuration within the supports set pair_vars[1] or does not match any configuration within the conflicts set pair_vars[2]. It embodies the logic: x ∈ pair_vars[1] || x ∉ pair_vars[2], providing a comprehensive way to define valid (supported) and invalid (conflicted) tuples for constraint satisfaction problems. This constraint is versatile, allowing for the explicit delineation of both acceptable and unacceptable configurations.

Arguments

  • list::Vector{Int}: A list of variables

  • supports::Vector{Vector{Int}}: A set of supported tuples. Default to nothing.

  • conflicts::Vector{Vector{Int}}: A set of conflicted tuples. Default to nothing.

Variants

  • :extension: Global constraint enforcing that the tuple x matches a configuration within the supports set pair_vars[1] or does not match any configuration within the conflicts set pair_vars[2]. It embodies the logic: x ∈ pair_vars[1] || x ∉ pair_vars[2], providing a comprehensive way to define valid (supported) and invalid (conflicted) tuples for constraint satisfaction problems. This constraint is versatile, allowing for the explicit delineation of both acceptable and unacceptable configurations.
julia
concept(:extension, x; pair_vars)
-concept(:extension)(x; pair_vars)
  • :supports: Global constraint ensuring that the tuple x matches a configuration listed within the support set pair_vars. This constraint is derived from the extension model, specifying that x must be one of the explicitly defined supported configurations: x ∈ pair_vars. It is utilized to directly declare the tuples that are valid and should be included in the solution space.
julia
concept(:supports, x; pair_vars)
-concept(:supports)(x; pair_vars)
  • :conflicts: Global constraint ensuring that the tuple x does not match any configuration listed within the conflict set pair_vars. This constraint, originating from the extension model, stipulates that x must avoid all configurations defined as conflicts: x ∉ pair_vars. It is useful for specifying tuples that are explicitly forbidden and should be excluded from the solution space.
julia
concept(:conflicts, x; pair_vars)
-concept(:conflicts)(x; pair_vars)

Examples

julia
c = concept(:extension)
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 3, 4, 5]])
-c([1, 2, 3, 4, 5]; pair_vars=([[1, 2, 3, 4, 5]], [[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]]))
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]])
-
-c = concept(:supports)
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 3, 4, 5]])
-
-c = concept(:conflicts)
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]])

source


`,22);function L(S,Z,q,J,G,R){return t(),a("div",null,[h,s("p",null,[i("These are constraints that are defined by a logical expression or a function. They are called intentional because they are defined by the property they satisfy. For example, a constraint that specifies that a variable "),s("mjx-container",p,[(t(),a("svg",k,d)),o]),i(" must be less than a variable "),s("mjx-container",c,[(t(),a("svg",E,y)),C]),i(" could be defined intentionally as "),s("mjx-container",u,[(t(),a("svg",m,F)),T]),i(".")]),f,s("p",null,[i("We use the "),b,i(" constraint to illustrate how to define an intention constraint in "),x,i(". The "),v,i(" constraint ensures that the distances between marks "),s("mjx-container",_,[(t(),a("svg",B,H)),A]),i(" on a ruler are unique.")]),s("mjx-container",D,[(t(),a("svg",V,M)),I]),P])}const z=e(l,[["render",L]]);export{N as __pageData,z as default}; diff --git a/dev/assets/constraints_generic_constraints.md.WUfYZUE9.lean.js b/dev/assets/constraints_generic_constraints.md.WUfYZUE9.lean.js deleted file mode 100644 index a54a115..0000000 --- a/dev/assets/constraints_generic_constraints.md.WUfYZUE9.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as a,m as s,a as i,a7 as n,o as t}from"./chunks/framework.aA95Gx5L.js";const N=JSON.parse('{"title":"Generic Constraints","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/generic_constraints.md","filePath":"constraints/generic_constraints.md","lastUpdated":null}'),l={name:"constraints/generic_constraints.md"},h=n("",3),p={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},k={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.025ex"},xmlns:"http://www.w3.org/2000/svg",width:"1.294ex",height:"1.025ex",role:"img",focusable:"false",viewBox:"0 -442 572 453","aria-hidden":"true"},r=s("g",{stroke:"currentColor",fill:"currentColor","stroke-width":"0",transform:"scale(1,-1)"},[s("g",{"data-mml-node":"math"},[s("g",{"data-mml-node":"mi"},[s("path",{"data-c":"1D465",d:"M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z",style:{"stroke-width":"3"}})])])],-1),d=[r],o=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"x")])],-1),c={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},E={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.464ex"},xmlns:"http://www.w3.org/2000/svg",width:"1.109ex",height:"1.464ex",role:"img",focusable:"false",viewBox:"0 -442 490 647","aria-hidden":"true"},g=s("g",{stroke:"currentColor",fill:"currentColor","stroke-width":"0",transform:"scale(1,-1)"},[s("g",{"data-mml-node":"math"},[s("g",{"data-mml-node":"mi"},[s("path",{"data-c":"1D466",d:"M21 287Q21 301 36 335T84 406T158 442Q199 442 224 419T250 355Q248 336 247 334Q247 331 231 288T198 191T182 105Q182 62 196 45T238 27Q261 27 281 38T312 61T339 94Q339 95 344 114T358 173T377 247Q415 397 419 404Q432 431 462 431Q475 431 483 424T494 412T496 403Q496 390 447 193T391 -23Q363 -106 294 -155T156 -205Q111 -205 77 -183T43 -117Q43 -95 50 -80T69 -58T89 -48T106 -45Q150 -45 150 -87Q150 -107 138 -122T115 -142T102 -147L99 -148Q101 -153 118 -160T152 -167H160Q177 -167 186 -165Q219 -156 247 -127T290 -65T313 -9T321 21L315 17Q309 13 296 6T270 -6Q250 -11 231 -11Q185 -11 150 11T104 82Q103 89 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z",style:{"stroke-width":"3"}})])])],-1),y=[g],C=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"y")])],-1),u={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},m={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.464ex"},xmlns:"http://www.w3.org/2000/svg",width:"5.42ex",height:"1.686ex",role:"img",focusable:"false",viewBox:"0 -540 2395.6 745","aria-hidden":"true"},Q=n("",1),F=[Q],T=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"x"),s("mo",null,"<"),s("mi",null,"y")])],-1),f=n("",4),b=s("code",null,"dist_different",-1),x=s("em",null,"Constraints.jl",-1),v=s("code",null,"dist_different",-1),_={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},B={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.025ex"},xmlns:"http://www.w3.org/2000/svg",width:"1.294ex",height:"1.025ex",role:"img",focusable:"false",viewBox:"0 -442 572 453","aria-hidden":"true"},w=s("g",{stroke:"currentColor",fill:"currentColor","stroke-width":"0",transform:"scale(1,-1)"},[s("g",{"data-mml-node":"math"},[s("g",{"data-mml-node":"mi"},[s("path",{"data-c":"1D465",d:"M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z",style:{"stroke-width":"3"}})])])],-1),H=[w],A=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"x")])],-1),D={class:"MathJax",jax:"SVG",display:"true",style:{direction:"ltr",display:"block","text-align":"center",margin:"1em 0",position:"relative"}},V={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.566ex"},xmlns:"http://www.w3.org/2000/svg",width:"25.797ex",height:"2.262ex",role:"img",focusable:"false",viewBox:"0 -750 11402.4 1000","aria-hidden":"true"},j=n("",1),M=[j],I=s("mjx-assistive-mml",{unselectable:"on",display:"block",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",overflow:"hidden",width:"100%"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},[s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|"),s("mi",null,"x"),s("mo",{stretchy:"false"},"["),s("mn",null,"1"),s("mo",{stretchy:"false"},"]"),s("mo",null,"−"),s("mi",null,"x"),s("mo",{stretchy:"false"},"["),s("mn",null,"2"),s("mo",{stretchy:"false"},"]"),s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|"),s("mo",null,"≠"),s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|"),s("mi",null,"x"),s("mo",{stretchy:"false"},"["),s("mn",null,"3"),s("mo",{stretchy:"false"},"]"),s("mo",null,"−"),s("mi",null,"x"),s("mo",{stretchy:"false"},"["),s("mn",null,"4"),s("mo",{stretchy:"false"},"]"),s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|")])],-1),P=n("",22);function L(S,Z,q,J,G,R){return t(),a("div",null,[h,s("p",null,[i("These are constraints that are defined by a logical expression or a function. They are called intentional because they are defined by the property they satisfy. For example, a constraint that specifies that a variable "),s("mjx-container",p,[(t(),a("svg",k,d)),o]),i(" must be less than a variable "),s("mjx-container",c,[(t(),a("svg",E,y)),C]),i(" could be defined intentionally as "),s("mjx-container",u,[(t(),a("svg",m,F)),T]),i(".")]),f,s("p",null,[i("We use the "),b,i(" constraint to illustrate how to define an intention constraint in "),x,i(". The "),v,i(" constraint ensures that the distances between marks "),s("mjx-container",_,[(t(),a("svg",B,H)),A]),i(" on a ruler are unique.")]),s("mjx-container",D,[(t(),a("svg",V,M)),I]),P])}const z=e(l,[["render",L]]);export{N as __pageData,z as default}; diff --git a/dev/assets/constraints_graph_constraints.md.CTf_lkG3.js b/dev/assets/constraints_graph_constraints.md.CTf_lkG3.js deleted file mode 100644 index 3385c3c..0000000 --- a/dev/assets/constraints_graph_constraints.md.CTf_lkG3.js +++ /dev/null @@ -1,7 +0,0 @@ -import{_ as i,c as s,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const g=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/graph_constraints.md","filePath":"constraints/graph_constraints.md","lastUpdated":null}'),n={name:"constraints/graph_constraints.md"},e=t(`

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Constraints on Graphs

# Constraints.xcsp_circuitFunction.
julia
xcsp_circuit(; list, size)

Return true if the circuit constraint is satisfied, false otherwise. The circuit constraint is a global constraint used in constraint programming, often in routing problems. It ensures that the values of a list of variables form a circuit, i.e., a sequence where each value is the index of the next value in the sequence, and the sequence eventually loops back to the start.

Arguments

  • list::AbstractVector: list of values to check.

  • size::Int: size of the circuit.

Variants

  • :circuit: The circuit constraint is a global constraint used in constraint programming, often in routing problems. It ensures that the values of a list of variables form a circuit, i.e., a sequence where each value is the index of the next value in the sequence, and the sequence eventually loops back to the start.
julia
concept(:circuit, x; op, val)
-concept(:circuit)(x; op, val)

Examples

julia
c = concept(:circuit)
-
-c([1, 2, 3, 4])
-c([2, 3, 4, 1])
-c([2, 3, 1, 4]; op = ==, val = 3)
-c([4, 3, 1, 3]; op = >, val = 0)

source


`,4),h=[e];function l(p,r,k,o,c,d){return a(),s("div",null,h)}const C=i(n,[["render",l]]);export{g as __pageData,C as default}; diff --git a/dev/assets/constraints_graph_constraints.md.CTf_lkG3.lean.js b/dev/assets/constraints_graph_constraints.md.CTf_lkG3.lean.js deleted file mode 100644 index 344c8e7..0000000 --- a/dev/assets/constraints_graph_constraints.md.CTf_lkG3.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as s,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const g=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/graph_constraints.md","filePath":"constraints/graph_constraints.md","lastUpdated":null}'),n={name:"constraints/graph_constraints.md"},e=t("",4),h=[e];function l(p,r,k,o,c,d){return a(),s("div",null,h)}const C=i(n,[["render",l]]);export{g as __pageData,C as default}; diff --git a/dev/assets/constraints_intro.md.SiDBJ4N_.js b/dev/assets/constraints_intro.md.SiDBJ4N_.js deleted file mode 100644 index 87a2ef5..0000000 --- a/dev/assets/constraints_intro.md.SiDBJ4N_.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,c as s,o as n,m as t,a}from"./chunks/framework.aA95Gx5L.js";const f=JSON.parse('{"title":"Introduction to basics cosntraints related tools","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/intro.md","filePath":"constraints/intro.md","lastUpdated":null}'),e={name:"constraints/intro.md"},r=t("h1",{id:"Introduction-to-basics-cosntraints-related-tools",tabindex:"-1"},[a("Introduction to basics cosntraints related tools "),t("a",{class:"header-anchor",href:"#Introduction-to-basics-cosntraints-related-tools","aria-label":'Permalink to "Introduction to basics cosntraints related tools {#Introduction-to-basics-cosntraints-related-tools}"'},"​")],-1),c=t("p",null,"About constraints.",-1),i=[r,c];function d(l,_,u,p,h,m){return n(),s("div",null,i)}const I=o(e,[["render",d]]);export{f as __pageData,I as default}; diff --git a/dev/assets/constraints_intro.md.SiDBJ4N_.lean.js b/dev/assets/constraints_intro.md.SiDBJ4N_.lean.js deleted file mode 100644 index 87a2ef5..0000000 --- a/dev/assets/constraints_intro.md.SiDBJ4N_.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,c as s,o as n,m as t,a}from"./chunks/framework.aA95Gx5L.js";const f=JSON.parse('{"title":"Introduction to basics cosntraints related tools","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/intro.md","filePath":"constraints/intro.md","lastUpdated":null}'),e={name:"constraints/intro.md"},r=t("h1",{id:"Introduction-to-basics-cosntraints-related-tools",tabindex:"-1"},[a("Introduction to basics cosntraints related tools "),t("a",{class:"header-anchor",href:"#Introduction-to-basics-cosntraints-related-tools","aria-label":'Permalink to "Introduction to basics cosntraints related tools {#Introduction-to-basics-cosntraints-related-tools}"'},"​")],-1),c=t("p",null,"About constraints.",-1),i=[r,c];function d(l,_,u,p,h,m){return n(),s("div",null,i)}const I=o(e,[["render",d]]);export{f as __pageData,I as default}; diff --git a/dev/assets/constraints_language_constraints.md.CE20vPnP.js b/dev/assets/constraints_language_constraints.md.CE20vPnP.js deleted file mode 100644 index 2a4d3f6..0000000 --- a/dev/assets/constraints_language_constraints.md.CE20vPnP.js +++ /dev/null @@ -1,48 +0,0 @@ -import{_ as s,c as i,o as a,a7 as n}from"./chunks/framework.aA95Gx5L.js";const o=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/language_constraints.md","filePath":"constraints/language_constraints.md","lastUpdated":null}'),t={name:"constraints/language_constraints.md"},h=n(`

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Constraints defined from Languages

# Constraints.xcsp_regularFunction.
julia
xcsp_regular(; list, automaton)
-
-Ensures that a sequence \`x\` (interpreted as a word) is accepted by the regular language represented by a given automaton. This constraint verifies the compliance of \`x\` with the language rules encoded within the \`automaton\` parameter, which must be an instance of \`<:AbstractAutomaton\`.

Arguments

  • list::Vector{Int}: A list of variables

  • automaton<:AbstractAutomaton: An automaton representing the regular language

Variants

  • :regular: Ensures that a sequence x (interpreted as a word) is accepted by the regular language represented by a given automaton. This constraint verifies the compliance of x with the language rules encoded within the automaton parameter, which must be an instance of <:AbstractAutomaton.
julia
concept(:regular, x; language)
-concept(:regular)(x; language)

Examples

julia
c = concept(:regular)
-
-states = Dict(
-    (:a, 0) => :a,
-    (:a, 1) => :b,
-    (:b, 1) => :c,
-    (:c, 0) => :d,
-    (:d, 0) => :d,
-    (:d, 1) => :e,
-    (:e, 0) => :e,
-)
-start = :a
-finish = :e
-
-a = Automaton(states, start, finish)
-
-c([0,0,1,1,0,0,1,0,0]; language = a)
-c([1,1,1,0,1]; language = a)

source


# Constraints.xcsp_mddFunction.
julia
xcsp_mdd(; list, diagram)

Return a function that checks if the list of values list satisfies the MDD diagram.

Arguments

  • list::Vector{Int}: list of values to check.

  • diagram::MDD: MDD to check.

Variants

  • :mdd: Multi-valued Decision Diagram (MDD) constraint. The MDD constraint is a constraint that can be used to model a wide range of problems. It is a directed graph where each node is labeled with a value and each edge is labeled with a value. The constraint is satisfied if there is a path from the first node to the last node such that the sequence of edge labels is a valid sequence of the value labels.
julia
concept(:mdd, x; language)
-concept(:mdd)(x; language)

Examples

julia
c = concept(:mdd)
-
-states = [
-    Dict( # level x1
-        (:r, 0) => :n1,
-        (:r, 1) => :n2,
-        (:r, 2) => :n3,
-    ),
-    Dict( # level x2
-        (:n1, 2) => :n4,
-        (:n2, 2) => :n4,
-        (:n3, 0) => :n5,
-    ),
-    Dict( # level x3
-        (:n4, 0) => :t,
-        (:n5, 0) => :t,
-    ),
-]
-
-a = MDD(states)
-
-c([0,2,0]; language = a)
-c([1,2,0]; language = a)
-c([2,0,0]; language = a)
-c([2,1,2]; language = a)
-c([1,0,2]; language = a)
-c([0,1,2]; language = a)

source


`,6),l=[h];function k(p,e,E,r,d,g){return a(),i("div",null,l)}const F=s(t,[["render",k]]);export{o as __pageData,F as default}; diff --git a/dev/assets/constraints_language_constraints.md.CE20vPnP.lean.js b/dev/assets/constraints_language_constraints.md.CE20vPnP.lean.js deleted file mode 100644 index fdce189..0000000 --- a/dev/assets/constraints_language_constraints.md.CE20vPnP.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as i,o as a,a7 as n}from"./chunks/framework.aA95Gx5L.js";const o=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/language_constraints.md","filePath":"constraints/language_constraints.md","lastUpdated":null}'),t={name:"constraints/language_constraints.md"},h=n("",6),l=[h];function k(p,e,E,r,d,g){return a(),i("div",null,l)}const F=s(t,[["render",k]]);export{o as __pageData,F as default}; diff --git a/dev/assets/constraints_packing_scheduling_constraints.md.CSsKQ9F3.js b/dev/assets/constraints_packing_scheduling_constraints.md.CSsKQ9F3.js deleted file mode 100644 index 4dcbaee..0000000 --- a/dev/assets/constraints_packing_scheduling_constraints.md.CSsKQ9F3.js +++ /dev/null @@ -1,18 +0,0 @@ -import{_ as s,c as i,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const C=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/packing_scheduling_constraints.md","filePath":"constraints/packing_scheduling_constraints.md","lastUpdated":null}'),n={name:"constraints/packing_scheduling_constraints.md"},h=t(`

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Packing and Scheduling Constraints

# Constraints.xcsp_cumulativeFunction.
julia
xcsp_cumulative(; origins, lengths, heights, condition)

Return true if the cumulative constraint is satisfied, false otherwise. The cumulative constraint is a global constraint used in constraint programming that is often used in scheduling problems. It ensures that for any point in time, the sum of the "heights" of tasks that are ongoing at that time does not exceed a certain limit.

Arguments

  • origins::AbstractVector: list of origins of the tasks.

  • lengths::AbstractVector: list of lengths of the tasks.

  • heights::AbstractVector: list of heights of the tasks.

  • condition::Tuple: condition to check.

Variants

  • :cumulative: The cumulative constraint is a global constraint used in constraint programming that is often used in scheduling problems. It ensures that for any point in time, the sum of the "heights" of tasks that are ongoing at that time does not exceed a certain limit.
julia
concept(:cumulative, x; pair_vars, op, val)
-concept(:cumulative)(x; pair_vars, op, val)

Examples

julia
c = concept(:cumulative)
-
-c([1, 2, 3, 4, 5]; val = 1)
-c([1, 2, 2, 4, 5]; val = 1)
-c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op =, val = 5)
-c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5)

source


# Constraints.xcsp_no_overlapFunction.
julia
xcsp_no_overlap(; origins, lengths, zero_ignored)

Return true if the no_overlap constraint is satisfied, false otherwise. The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts.

Arguments

  • origins::AbstractVector: list of origins of the tasks.

  • lengths::AbstractVector: list of lengths of the tasks.

  • zero_ignored::Bool: whether to ignore zero-length tasks.

Variants

  • :no_overlap: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts.
julia
concept(:no_overlap, x; pair_vars, bool)
-concept(:no_overlap)(x; pair_vars, bool)
  • :no_overlap_no_zero: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant ignores zero-length tasks.
julia
concept(:no_overlap_no_zero, x; pair_vars)
-concept(:no_overlap_no_zero)(x; pair_vars)
  • :no_overlap_with_zero: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant includes zero-length tasks.
julia
concept(:no_overlap_with_zero, x; pair_vars)
-concept(:no_overlap_with_zero)(x; pair_vars)

Examples

julia
c = concept(:no_overlap)
-
-c([1, 2, 3, 4, 5])
-c([1, 2, 3, 4, 1])
-c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 1, 1])
-c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 3, 1])
-c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 3, 1, 1])
-c([1, 1, 1, 3, 5, 2, 7, 7, 5, 12, 8, 7]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3)
-c([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3)

source


`,6),k=[h];function l(p,e,r,E,d,g){return a(),i("div",null,k)}const y=s(n,[["render",l]]);export{C as __pageData,y as default}; diff --git a/dev/assets/constraints_packing_scheduling_constraints.md.CSsKQ9F3.lean.js b/dev/assets/constraints_packing_scheduling_constraints.md.CSsKQ9F3.lean.js deleted file mode 100644 index 11f5c85..0000000 --- a/dev/assets/constraints_packing_scheduling_constraints.md.CSsKQ9F3.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as i,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const C=JSON.parse('{"title":"Constraints.jl: Streamlining Constraint Definition and Integration in Julia","description":"","frontmatter":{},"headers":[],"relativePath":"constraints/packing_scheduling_constraints.md","filePath":"constraints/packing_scheduling_constraints.md","lastUpdated":null}'),n={name:"constraints/packing_scheduling_constraints.md"},h=t("",6),k=[h];function l(p,e,r,E,d,g){return a(),i("div",null,k)}const y=s(n,[["render",l]]);export{C as __pageData,y as default}; diff --git a/dev/assets/cp_advanced.md.Dsfkdtcs.js b/dev/assets/cp_advanced.md.Dsfkdtcs.js deleted file mode 100644 index d40d679..0000000 --- a/dev/assets/cp_advanced.md.Dsfkdtcs.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as e,o as t,a7 as n}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"Advanced Constraint Programming Techniques","description":"","frontmatter":{},"headers":[],"relativePath":"cp/advanced.md","filePath":"cp/advanced.md","lastUpdated":null}'),i={name:"cp/advanced.md"},r=n('

Advanced Constraint Programming Techniques

Global Constraints and Their Uses

  • Dive deeper into global constraints and how they simplify complex problems.

Search Strategies and Optimization

  • Discuss various search strategies and their impact on solving CP problems.
',5),s=[r];function o(d,c,l,h,m,_){return t(),e("div",null,s)}const g=a(i,[["render",o]]);export{u as __pageData,g as default}; diff --git a/dev/assets/cp_advanced.md.Dsfkdtcs.lean.js b/dev/assets/cp_advanced.md.Dsfkdtcs.lean.js deleted file mode 100644 index 72766c7..0000000 --- a/dev/assets/cp_advanced.md.Dsfkdtcs.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as e,o as t,a7 as n}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"Advanced Constraint Programming Techniques","description":"","frontmatter":{},"headers":[],"relativePath":"cp/advanced.md","filePath":"cp/advanced.md","lastUpdated":null}'),i={name:"cp/advanced.md"},r=n("",5),s=[r];function o(d,c,l,h,m,_){return t(),e("div",null,s)}const g=a(i,[["render",o]]);export{u as __pageData,g as default}; diff --git a/dev/assets/cp_applications.md.-HdwrgYe.js b/dev/assets/cp_applications.md.-HdwrgYe.js deleted file mode 100644 index f7b8531..0000000 --- a/dev/assets/cp_applications.md.-HdwrgYe.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as e,o as t,a7 as i}from"./chunks/framework.aA95Gx5L.js";const _=JSON.parse('{"title":"Applying Optimization Methods","description":"","frontmatter":{},"headers":[],"relativePath":"cp/applications.md","filePath":"cp/applications.md","lastUpdated":null}'),o={name:"cp/applications.md"},l=i('

Applying Optimization Methods

Case Studies and Real-World Applications

  • Showcase studies where CP and optimization have been successfully applied.

From Theory to Practice

  • Guide readers through the process of formulating and solving an optimization problem from a real-world scenario.
',5),r=[l];function s(n,p,c,d,h,m){return t(),e("div",null,r)}const f=a(o,[["render",s]]);export{_ as __pageData,f as default}; diff --git a/dev/assets/cp_applications.md.-HdwrgYe.lean.js b/dev/assets/cp_applications.md.-HdwrgYe.lean.js deleted file mode 100644 index 2fc20d0..0000000 --- a/dev/assets/cp_applications.md.-HdwrgYe.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as e,o as t,a7 as i}from"./chunks/framework.aA95Gx5L.js";const _=JSON.parse('{"title":"Applying Optimization Methods","description":"","frontmatter":{},"headers":[],"relativePath":"cp/applications.md","filePath":"cp/applications.md","lastUpdated":null}'),o={name:"cp/applications.md"},l=i("",5),r=[l];function s(n,p,c,d,h,m){return t(),e("div",null,r)}const f=a(o,[["render",s]]);export{_ as __pageData,f as default}; diff --git a/dev/assets/cp_contribution.md.CvjPxUVA.js b/dev/assets/cp_contribution.md.CvjPxUVA.js deleted file mode 100644 index b2040a2..0000000 --- a/dev/assets/cp_contribution.md.CvjPxUVA.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as t,c as n,o as i,a7 as o}from"./chunks/framework.aA95Gx5L.js";const C=JSON.parse('{"title":"Community and Contribution","description":"","frontmatter":{},"headers":[],"relativePath":"cp/contribution.md","filePath":"cp/contribution.md","lastUpdated":null}'),a={name:"cp/contribution.md"},e=o('

Community and Contribution

Joining the JuliaConstraint Community

  • Encourage readers to join the community, highlighting how they can contribute and collaborate.

Future Directions

  • Share the vision for JuliaConstraint and upcoming projects or areas of research.
',5),r=[e];function u(c,s,l,m,h,d){return i(),n("div",null,r)}const b=t(a,[["render",u]]);export{C as __pageData,b as default}; diff --git a/dev/assets/cp_contribution.md.CvjPxUVA.lean.js b/dev/assets/cp_contribution.md.CvjPxUVA.lean.js deleted file mode 100644 index e304956..0000000 --- a/dev/assets/cp_contribution.md.CvjPxUVA.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as t,c as n,o as i,a7 as o}from"./chunks/framework.aA95Gx5L.js";const C=JSON.parse('{"title":"Community and Contribution","description":"","frontmatter":{},"headers":[],"relativePath":"cp/contribution.md","filePath":"cp/contribution.md","lastUpdated":null}'),a={name:"cp/contribution.md"},e=o("",5),r=[e];function u(c,s,l,m,h,d){return i(),n("div",null,r)}const b=t(a,[["render",u]]);export{C as __pageData,b as default}; diff --git a/dev/assets/cp_cp101.md.CrtqNaW3.js b/dev/assets/cp_cp101.md.CrtqNaW3.js deleted file mode 100644 index 0d502ae..0000000 --- a/dev/assets/cp_cp101.md.CrtqNaW3.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as i,o as t,a7 as o}from"./chunks/framework.aA95Gx5L.js";const f=JSON.parse('{"title":"Constraint Programming 101","description":"","frontmatter":{},"headers":[],"relativePath":"cp/cp101.md","filePath":"cp/cp101.md","lastUpdated":null}'),n={name:"cp/cp101.md"},r=o('

Constraint Programming 101

What is Constraint Programming?

  • Define CP and its significance in solving combinatorial problems.

Basic Concepts and Terminology

  • Introduce key concepts such as constraints, domains, and variables.

How CP differs from other optimization techniques

  • Contrast with other methods like linear programming and metaheuristics.
',7),e=[r];function s(c,m,l,h,d,g){return t(),i("div",null,e)}const u=a(n,[["render",s]]);export{f as __pageData,u as default}; diff --git a/dev/assets/cp_cp101.md.CrtqNaW3.lean.js b/dev/assets/cp_cp101.md.CrtqNaW3.lean.js deleted file mode 100644 index 68b9a21..0000000 --- a/dev/assets/cp_cp101.md.CrtqNaW3.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as i,o as t,a7 as o}from"./chunks/framework.aA95Gx5L.js";const f=JSON.parse('{"title":"Constraint Programming 101","description":"","frontmatter":{},"headers":[],"relativePath":"cp/cp101.md","filePath":"cp/cp101.md","lastUpdated":null}'),n={name:"cp/cp101.md"},r=o("",7),e=[r];function s(c,m,l,h,d,g){return t(),i("div",null,e)}const u=a(n,[["render",s]]);export{f as __pageData,u as default}; diff --git a/dev/assets/cp_ecosystem.md.BROmdRLS.js b/dev/assets/cp_ecosystem.md.BROmdRLS.js deleted file mode 100644 index 609c9cb..0000000 --- a/dev/assets/cp_ecosystem.md.BROmdRLS.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as t,o as e,a7 as i}from"./chunks/framework.aA95Gx5L.js";const h=JSON.parse('{"title":"Exploring JuliaConstraint Packages","description":"","frontmatter":{},"headers":[],"relativePath":"cp/ecosystem.md","filePath":"cp/ecosystem.md","lastUpdated":null}'),n={name:"cp/ecosystem.md"},s=i('

Exploring JuliaConstraint Packages

Package Overviews

  • Introduce each package within the JuliaConstraint organization, its purpose, and primary features.

Installation and Getting Started Guides

  • Provide step-by-step instructions for installing and getting started with each package.
',5),r=[s];function o(l,c,d,u,g,p){return e(),t("div",null,r)}const P=a(n,[["render",o]]);export{h as __pageData,P as default}; diff --git a/dev/assets/cp_ecosystem.md.BROmdRLS.lean.js b/dev/assets/cp_ecosystem.md.BROmdRLS.lean.js deleted file mode 100644 index 623e6d3..0000000 --- a/dev/assets/cp_ecosystem.md.BROmdRLS.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as t,o as e,a7 as i}from"./chunks/framework.aA95Gx5L.js";const h=JSON.parse('{"title":"Exploring JuliaConstraint Packages","description":"","frontmatter":{},"headers":[],"relativePath":"cp/ecosystem.md","filePath":"cp/ecosystem.md","lastUpdated":null}'),n={name:"cp/ecosystem.md"},s=i("",5),r=[s];function o(l,c,d,u,g,p){return e(),t("div",null,r)}const P=a(n,[["render",o]]);export{h as __pageData,P as default}; diff --git a/dev/assets/cp_getting_started.md.CgxLSopb.js b/dev/assets/cp_getting_started.md.CgxLSopb.js deleted file mode 100644 index dcbf4a2..0000000 --- a/dev/assets/cp_getting_started.md.CgxLSopb.js +++ /dev/null @@ -1,9 +0,0 @@ -import{_ as l,c as t,m as s,a as i,a7 as a,o as e}from"./chunks/framework.aA95Gx5L.js";const L=JSON.parse('{"title":"Getting Started with Julia for CP and Optimization","description":"","frontmatter":{},"headers":[],"relativePath":"cp/getting_started.md","filePath":"cp/getting_started.md","lastUpdated":null}'),n={name:"cp/getting_started.md"},h=a('

Getting Started with Julia for CP and Optimization

Why Julia?

  • Discuss the advantages of Julia for computational science and optimization, highlighting its performance and ease of use.

Setting Up Your Julia Environment

We encourage users to install Julia through juliaup, a version manager for the Julia language. Please look at the official Julia language download page for further information. Once installed, Julia can be used through various editors (Visual Studio Code), notebooks (Pluto.jl), or command-line (REPL).

Although a part of the CP solvers available within the Julia ecosystem have their own interface, we encourage users to use the JuMP modeling language if possible.

Julia Constraints host several solvers(' interfaces). Due to its flexibility in modeling and solving, we will use LocalSearchSolvers.jl through its JuMP interface CBLS.jl as the basic example. Note that depending on the targeted instances, available hardware, and expectations, it is not necessarily the best choice.

All along the documentation, we will try to provide syntax examples for different setup.

julia
using LocalSearchSolvers
julia
using JuMP, CBLS
julia
# TODO: Add other solvers

Your First Julia CP Model

We will start with a classic puzzle game and some of its not that simple variants: the Sudoku.

(From Wikipedia) In classic Sudoku, the objective is to fill a 9 × 9 grid with digits so that each column, each row, and each of the nine 3 × 3 subgrids that compose the grid (also called "boxes", "blocks", or "regions") contains all of the digits from 1 to 9. The puzzle setter provides a partially completed grid, which for a well-posed puzzle has a single solution.

Constraint Programming follows the model-and-solve approach. We first need to model our Sudoku problem.

julia
m = JuMP.Model(CBLS.Optimizer)
julia
# TODO: Add other solvers

But what are the basis of CP models? It is quite simple:

',15),o={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},p={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.439ex"},xmlns:"http://www.w3.org/2000/svg",width:"15.867ex",height:"1.984ex",role:"img",focusable:"false",viewBox:"0 -683 7013.4 877","aria-hidden":"true"},d=a('',1),r=[d],k=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"X"),s("mo",null,"="),s("msub",null,[s("mi",null,"X"),s("mn",null,"1")]),s("mo",null,","),s("mo",null,"⋯"),s("mo",null,","),s("msub",null,[s("mi",null,"X"),s("mi",null,"n")])])],-1),c=a('
julia
@variable(m, 1 X[1:9, 1:9]  9, Int)
julia
# TODO: Add other solvers
',1),Q={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},g={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.439ex"},xmlns:"http://www.w3.org/2000/svg",width:"15.148ex",height:"2.034ex",role:"img",focusable:"false",viewBox:"0 -705 6695.4 899","aria-hidden":"true"},T=a('',1),u=[T],m=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"C"),s("mo",null,"="),s("msub",null,[s("mi",null,"C"),s("mn",null,"1")]),s("mo",null,","),s("mo",null,"⋯"),s("mo",null,","),s("msub",null,[s("mi",null,"C"),s("mi",null,"n")])])],-1),v={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},y={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"0"},xmlns:"http://www.w3.org/2000/svg",width:"1.928ex",height:"1.545ex",role:"img",focusable:"false",viewBox:"0 -683 852 683","aria-hidden":"true"},b=s("g",{stroke:"currentColor",fill:"currentColor","stroke-width":"0",transform:"scale(1,-1)"},[s("g",{"data-mml-node":"math"},[s("g",{"data-mml-node":"mi"},[s("path",{"data-c":"1D44B",d:"M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z",style:{"stroke-width":"3"}})])])],-1),E=[b],C=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"X")])],-1),f=a(`

When modeling problems as CP, one might define and use their own predicates. However, a large collection of already defined constraints exists. One, if not the most, iconic global constraint is called AllDifferent. It ensures that all variables take distinct values.

Sudoku puzzles can be defined using only this one constraint applied to different subsets of variables.

julia
for i in 1:9
-        @constraint(m, X[i,:] in AllDifferent()) # rows
-        @constraint(m, X[:,i] in AllDifferent()) # columns
-end
julia
# TODO: Add other solvers

The last series of AllDifferent constraint is less straight forward. We need to ensure that each 3 × 3 subgrid (block) is filled with distinct values.

julia
for i in 0:2, j in 0:2 # blocks
-    @constraint(
-        m,
-        vec(X[(3i+1):(3(i+1)), (3j+1):(3(j+1))]) in AllDifferent(),
-    )
-end
julia
# TODO: Add other solvers

We can now simply run our solver to look for a feasible solution.

julia
optimize!(m)

Note that this is heuristic solver, we might not get a feasible solution! Let's check it out. The value function print the value of a JuMP variable. We can cast it over a collection with the value. syntax.

julia
value.(X)
`,9);function _(w,F,D,A,x,B){return e(),t("div",null,[h,s("ol",null,[s("li",null,[i("A collection "),s("mjx-container",o,[(e(),t("svg",p,r)),k]),i(" of variables with each an associated domain.")])]),c,s("ol",null,[s("li",null,[i("A collection of predicates (called constraints) "),s("mjx-container",Q,[(e(),t("svg",g,u)),m]),i(" over (subsets of) "),s("mjx-container",v,[(e(),t("svg",y,E)),C]),i(".")])]),f])}const S=l(n,[["render",_]]);export{L as __pageData,S as default}; diff --git a/dev/assets/cp_getting_started.md.CgxLSopb.lean.js b/dev/assets/cp_getting_started.md.CgxLSopb.lean.js deleted file mode 100644 index 7b1f622..0000000 --- a/dev/assets/cp_getting_started.md.CgxLSopb.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as l,c as t,m as s,a as i,a7 as a,o as e}from"./chunks/framework.aA95Gx5L.js";const L=JSON.parse('{"title":"Getting Started with Julia for CP and Optimization","description":"","frontmatter":{},"headers":[],"relativePath":"cp/getting_started.md","filePath":"cp/getting_started.md","lastUpdated":null}'),n={name:"cp/getting_started.md"},h=a("",15),o={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},p={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.439ex"},xmlns:"http://www.w3.org/2000/svg",width:"15.867ex",height:"1.984ex",role:"img",focusable:"false",viewBox:"0 -683 7013.4 877","aria-hidden":"true"},d=a("",1),r=[d],k=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"X"),s("mo",null,"="),s("msub",null,[s("mi",null,"X"),s("mn",null,"1")]),s("mo",null,","),s("mo",null,"⋯"),s("mo",null,","),s("msub",null,[s("mi",null,"X"),s("mi",null,"n")])])],-1),c=a("",1),Q={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},g={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.439ex"},xmlns:"http://www.w3.org/2000/svg",width:"15.148ex",height:"2.034ex",role:"img",focusable:"false",viewBox:"0 -705 6695.4 899","aria-hidden":"true"},T=a("",1),u=[T],m=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"C"),s("mo",null,"="),s("msub",null,[s("mi",null,"C"),s("mn",null,"1")]),s("mo",null,","),s("mo",null,"⋯"),s("mo",null,","),s("msub",null,[s("mi",null,"C"),s("mi",null,"n")])])],-1),v={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},y={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"0"},xmlns:"http://www.w3.org/2000/svg",width:"1.928ex",height:"1.545ex",role:"img",focusable:"false",viewBox:"0 -683 852 683","aria-hidden":"true"},b=s("g",{stroke:"currentColor",fill:"currentColor","stroke-width":"0",transform:"scale(1,-1)"},[s("g",{"data-mml-node":"math"},[s("g",{"data-mml-node":"mi"},[s("path",{"data-c":"1D44B",d:"M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z",style:{"stroke-width":"3"}})])])],-1),E=[b],C=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"X")])],-1),f=a("",9);function _(w,F,D,A,x,B){return e(),t("div",null,[h,s("ol",null,[s("li",null,[i("A collection "),s("mjx-container",o,[(e(),t("svg",p,r)),k]),i(" of variables with each an associated domain.")])]),c,s("ol",null,[s("li",null,[i("A collection of predicates (called constraints) "),s("mjx-container",Q,[(e(),t("svg",g,u)),m]),i(" over (subsets of) "),s("mjx-container",v,[(e(),t("svg",y,E)),C]),i(".")])]),f])}const S=l(n,[["render",_]]);export{L as __pageData,S as default}; diff --git a/dev/assets/cp_intro.md.qCFhsnKE.js b/dev/assets/cp_intro.md.qCFhsnKE.js deleted file mode 100644 index 58971ac..0000000 --- a/dev/assets/cp_intro.md.qCFhsnKE.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as o,o as a,m as t,a as n}from"./chunks/framework.aA95Gx5L.js";const C=JSON.parse('{"title":"Welcome to Julia Constraints","description":"","frontmatter":{},"headers":[],"relativePath":"cp/intro.md","filePath":"cp/intro.md","lastUpdated":null}'),i={name:"cp/intro.md"},r=t("h1",{id:"Welcome-to-Julia-Constraints",tabindex:"-1"},[n("Welcome to Julia Constraints "),t("a",{class:"header-anchor",href:"#Welcome-to-Julia-Constraints","aria-label":'Permalink to "Welcome to Julia Constraints {#Welcome-to-Julia-Constraints}"'},"​")],-1),s=t("p",null,"An introductory post/chapter that provides an overview of the JuliaConstraint organization, its mission, and what readers can expect to learn from the content. Highlight the importance of Constraint Programming (CP) and optimization in solving real-world problems.",-1),c=[r,s];function l(d,m,p,h,_,u){return a(),o("div",null,c)}const J=e(i,[["render",l]]);export{C as __pageData,J as default}; diff --git a/dev/assets/cp_intro.md.qCFhsnKE.lean.js b/dev/assets/cp_intro.md.qCFhsnKE.lean.js deleted file mode 100644 index 58971ac..0000000 --- a/dev/assets/cp_intro.md.qCFhsnKE.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as o,o as a,m as t,a as n}from"./chunks/framework.aA95Gx5L.js";const C=JSON.parse('{"title":"Welcome to Julia Constraints","description":"","frontmatter":{},"headers":[],"relativePath":"cp/intro.md","filePath":"cp/intro.md","lastUpdated":null}'),i={name:"cp/intro.md"},r=t("h1",{id:"Welcome-to-Julia-Constraints",tabindex:"-1"},[n("Welcome to Julia Constraints "),t("a",{class:"header-anchor",href:"#Welcome-to-Julia-Constraints","aria-label":'Permalink to "Welcome to Julia Constraints {#Welcome-to-Julia-Constraints}"'},"​")],-1),s=t("p",null,"An introductory post/chapter that provides an overview of the JuliaConstraint organization, its mission, and what readers can expect to learn from the content. Highlight the importance of Constraint Programming (CP) and optimization in solving real-world problems.",-1),c=[r,s];function l(d,m,p,h,_,u){return a(),o("div",null,c)}const J=e(i,[["render",l]]);export{C as __pageData,J as default}; diff --git a/dev/assets/cp_models.md.DjhzTYet.js b/dev/assets/cp_models.md.DjhzTYet.js deleted file mode 100644 index ddc0dac..0000000 --- a/dev/assets/cp_models.md.DjhzTYet.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as a,o as n,a7 as i}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"Building and Analyzing Models","description":"","frontmatter":{},"headers":[],"relativePath":"cp/models.md","filePath":"cp/models.md","lastUpdated":null}'),o={name:"cp/models.md"},t=i('

Building and Analyzing Models

Modeling Best Practices

  • Share best practices and tips for building efficient CP and optimization models.

Performance Analysis and Improvement

  • Teach how to analyze and improve the performance of models.
',5),l=[t];function s(d,r,c,m,_,h){return n(),a("div",null,l)}const f=e(o,[["render",s]]);export{u as __pageData,f as default}; diff --git a/dev/assets/cp_models.md.DjhzTYet.lean.js b/dev/assets/cp_models.md.DjhzTYet.lean.js deleted file mode 100644 index 0594a23..0000000 --- a/dev/assets/cp_models.md.DjhzTYet.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as a,o as n,a7 as i}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"Building and Analyzing Models","description":"","frontmatter":{},"headers":[],"relativePath":"cp/models.md","filePath":"cp/models.md","lastUpdated":null}'),o={name:"cp/models.md"},t=i("",5),l=[t];function s(d,r,c,m,_,h){return n(),a("div",null,l)}const f=e(o,[["render",s]]);export{u as __pageData,f as default}; diff --git a/dev/assets/cp_opt.md.oWksNiMs.js b/dev/assets/cp_opt.md.oWksNiMs.js deleted file mode 100644 index d97086c..0000000 --- a/dev/assets/cp_opt.md.oWksNiMs.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as a,o as t,a7 as e}from"./chunks/framework.aA95Gx5L.js";const _=JSON.parse('{"title":"Dive into Optimization","description":"","frontmatter":{},"headers":[],"relativePath":"cp/opt.md","filePath":"cp/opt.md","lastUpdated":null}'),n={name:"cp/opt.md"},o=e('

Dive into Optimization

Understanding Optimization

  • Explanation of optimization, types of optimization problems (e.g., linear, nonlinear, integer programming).

Metaheuristics Overview

  • Introduce concepts like Genetic Algorithms, Simulated Annealing, and Tabu Search.

Mathematical Programming Basics

  • Cover the fundamentals of mathematical programming and its role in optimization.
',7),r=[o];function s(l,m,c,d,h,p){return t(),a("div",null,r)}const g=i(n,[["render",s]]);export{_ as __pageData,g as default}; diff --git a/dev/assets/cp_opt.md.oWksNiMs.lean.js b/dev/assets/cp_opt.md.oWksNiMs.lean.js deleted file mode 100644 index 9050a98..0000000 --- a/dev/assets/cp_opt.md.oWksNiMs.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as a,o as t,a7 as e}from"./chunks/framework.aA95Gx5L.js";const _=JSON.parse('{"title":"Dive into Optimization","description":"","frontmatter":{},"headers":[],"relativePath":"cp/opt.md","filePath":"cp/opt.md","lastUpdated":null}'),n={name:"cp/opt.md"},o=e("",7),r=[o];function s(l,m,c,d,h,p){return t(),a("div",null,r)}const g=i(n,[["render",s]]);export{_ as __pageData,g as default}; diff --git a/dev/assets/cp_tuto_xp.md.CLy9H2hK.js b/dev/assets/cp_tuto_xp.md.CLy9H2hK.js deleted file mode 100644 index ab8b4c4..0000000 --- a/dev/assets/cp_tuto_xp.md.CLy9H2hK.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as e,o as t,a7 as s}from"./chunks/framework.aA95Gx5L.js";const x=JSON.parse('{"title":"Tutorials and Experiments","description":"","frontmatter":{},"headers":[],"relativePath":"cp/tuto_xp.md","filePath":"cp/tuto_xp.md","lastUpdated":null}'),n={name:"cp/tuto_xp.md"},i=s('

Tutorials and Experiments

Hands-On Tutorials

  • Provide step-by-step tutorials covering various topics and complexity levels.

Experimental Analysis

  • Discuss the importance of experimental analysis in CP and how to conduct meaningful experiments.
',5),r=[i];function l(o,d,p,u,c,_){return t(),e("div",null,r)}const h=a(n,[["render",l]]);export{x as __pageData,h as default}; diff --git a/dev/assets/cp_tuto_xp.md.CLy9H2hK.lean.js b/dev/assets/cp_tuto_xp.md.CLy9H2hK.lean.js deleted file mode 100644 index 2008e7a..0000000 --- a/dev/assets/cp_tuto_xp.md.CLy9H2hK.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as e,o as t,a7 as s}from"./chunks/framework.aA95Gx5L.js";const x=JSON.parse('{"title":"Tutorials and Experiments","description":"","frontmatter":{},"headers":[],"relativePath":"cp/tuto_xp.md","filePath":"cp/tuto_xp.md","lastUpdated":null}'),n={name:"cp/tuto_xp.md"},i=s("",5),r=[i];function l(o,d,p,u,c,_){return t(),e("div",null,r)}const h=a(n,[["render",l]]);export{x as __pageData,h as default}; diff --git a/dev/assets/full_api.md.BiWge5EP.js b/dev/assets/full_api.md.BiWge5EP.js deleted file mode 100644 index 19ca5cb..0000000 --- a/dev/assets/full_api.md.BiWge5EP.js +++ /dev/null @@ -1,255 +0,0 @@ -import{_ as s,c as i,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const E=JSON.parse('{"title":"Full API","description":"","frontmatter":{},"headers":[],"relativePath":"full_api.md","filePath":"full_api.md","lastUpdated":null}'),e={name:"full_api.md"},n=t(`

Full API

# ConstraintCommons.USUAL_CONSTRAINT_PARAMETERSConstant.
julia
const USUAL_CONSTRAINT_PARAMETERS

List of usual constraints parameters (based on XCSP3-core constraints).

julia
const USUAL_CONSTRAINT_PARAMETERS = [
-    :bool,
-    :dim,
-    :id,
-    :language,
-    :op,
-    :pair_vars,
-    :val,
-    :vals,
-]

source


# ConstraintCommons.AbstractAutomatonType.
julia
AbstractAutomaton

An abstract interface for automata used in Julia Constraints packages. Requirements:

  • accept(a<:AbstractAutomaton, word): return true if a accepts word.

source


# ConstraintCommons.AbstractMultivaluedDecisionDiagramType.
julia
AbstractMultivaluedDecisionDiagram

An abstract interface for Multivalued Decision Diagrams (MDD) used in Julia Constraints packages. Requirements:

  • accept(a<:AbstractMultivaluedDecisionDiagram, word): return true if a accepts word.

source


# ConstraintCommons.AutomatonType.
julia
Automaton{S, T, F <: Union{S, Vector{S}, Set{S}}} <: AbstractAutomaton

A minimal implementation of a deterministic automaton structure.

source


# ConstraintCommons.MDDType.
julia
MDD{S,T} <: AbstractMultivaluedDecisionDiagram

A minimal implementation of a multivalued decision diagram structure.

source


# ConstraintCommons.acceptMethod.
julia
accept(a::Union{Automaton, MDD}, w)

Return true if a accepts the word w and false otherwise.

source


# ConstraintCommons.at_endMethod.
julia
at_end(a::Automaton, s)

Internal method used by accept with Automaton.

source


# ConstraintCommons.extract_parametersMethod.
julia
extract_parameters(m::Union{Method, Function}; parameters)

Extracts the intersection between the kargs of m and parameters (defaults to USUAL_CONSTRAINT_PARAMETERS).

source


# ConstraintCommons.incsert!Function.
julia
incsert!(d::Union{AbstractDict, AbstractDictionary}, ind, val = 1)

Increase or insert a counter in a dictionary-based collection. The counter insertion defaults to val = 1.

source


# ConstraintCommons.oversampleMethod.
julia
oversample(X, f)

Oversample elements of X until the boolean function f has as many true and false configurations.

source


# ConstraintCommons.symconFunction.
julia
Base.:*(s1::Symbol, s2::Symbol, connector::AbstractString="_")

Extends * to Symbols multiplication by connecting the symbols by an _.

source


# ConstraintCommons.δ_extremaMethod.
julia
δ_extrema(X...)

Compute both the difference between the maximum and the minimum of over all the collections of X.

source


# ConstraintDomains.AbstractDomainType.
julia
AbstractDomain

An abstract super type for any domain type. A domain type D <: AbstractDomain must implement the following methods to properly interface AbstractDomain.

  • Base.∈(val, ::D)

  • Base.rand(::D)

  • Base.length(::D) that is the number of elements in a discrete domain, and the distance between bounds or similar for a continuous domain

Additionally, if the domain is used in a dynamic context, it can extend

  • add!(::D, args)

  • delete!(::D, args)

where args depends on D's structure

source


# ConstraintDomains.BoolParameterDomainType.
julia
BoolParameterDomain <: AbstractDomain

A domain to store boolean values. It is used to generate random parameters.

source


# ConstraintDomains.ContinuousDomainType.
julia
ContinuousDomain{T <: Real} <: AbstractDomain

An abstract supertype for all continuous domains.

source


# ConstraintDomains.DimParameterDomainType.
julia
DimParameterDomain <: AbstractDomain

A domain to store dimensions. It is used to generate random parameters.

source


# ConstraintDomains.DiscreteDomainType.
julia
DiscreteDomain{T <: Number} <: AbstractDomain

An abstract supertype for discrete domains (set, range).

source


# ConstraintDomains.EmptyDomainType.
julia
EmptyDomain

A struct to handle yet to be defined domains.

source


# ConstraintDomains.ExploreSettingsMethod.
julia
ExploreSettings(
-    domains;
-    complete_search_limit = 10^6,
-    max_samplings = sum(domain_size, domains),
-    search = :flexible,
-    solutions_limit = floor(Int, sqrt(max_samplings)),
-)

Settings for the exploration of a search space composed by a collection of domains.

source


# ConstraintDomains.FakeAutomatonType.
julia
FakeAutomaton{T} <: ConstraintCommons.AbstractAutomaton

A structure to generate pseudo automaton enough for parameter exploration.

source


# ConstraintDomains.IdParameterDomainType.
julia
IdParameterDomain <: AbstractDomain

A domain to store ids. It is used to generate random parameters.

source


# ConstraintDomains.IntervalsType.
julia
Intervals{T <: Real} <: ContinuousDomain{T}

An encapsuler to store a vector of PatternFolds.Interval. Dynamic changes to Intervals are not handled yet.

source


# ConstraintDomains.LanguageParameterDomainType.
julia
LanguageParameterDomain <: AbstractDomain

A domain to store languages. It is used to generate random parameters.

source


# ConstraintDomains.OpParameterDomainType.
julia
OpParameterDomain{T} <: AbstractDomain

A domain to store operators. It is used to generate random parameters.

source


# ConstraintDomains.PairVarsParameterDomainType.
julia
PairVarsParameterDomain{T} <: AbstractDomain

A domain to store values paired with variables. It is used to generate random parameters.

source


# ConstraintDomains.RangeDomainType.
julia
RangeDomain

A discrete domain defined by a range <: AbstractRange{Real}. As ranges are immutable in Julia, changes in RangeDomain must use set_domain!.

source


# ConstraintDomains.SetDomainType.
julia
SetDomain{T <: Number} <: DiscreteDomain{T}

Domain that stores discrete values as a set of (unordered) points.

source


# ConstraintDomains.ValParameterDomainType.
julia
ValParameterDomain{T} <: AbstractDomain

A domain to store one value. It is used to generate random parameters.

source


# ConstraintDomains.ValsParameterDomainType.
julia
ValsParameterDomain{T} <: AbstractDomain

A domain to store values. It is used to generate random parameters.

source


# Base.convertMethod.
julia
Base.convert(::Type{Union{Intervals, RangeDomain}}, d::Union{Intervals, RangeDomain})

Extends Base.convert for domains.

source


# Base.delete!Method.
julia
Base.delete!(d::SetDomain, value)(d::SetDomain, value)

Delete value from the list of points in d.

source


# Base.eltypeMethod.
julia
Base.eltype(::AbstractDomain)

Extend eltype for domains.

source


# Base.inMethod.
julia
Base.in(x, itv::Intervals)

Return true if x ∈ I for any 'I ∈ itv, false otherwise.x ∈ I\` is equivalent to

  • a < x < b if I = (a, b)

  • a < x ≤ b if I = (a, b]

  • a ≤ x < b if I = [a, b)

  • a ≤ x ≤ b if I = [a, b]

source


# Base.inMethod.
julia
Base.in(value, d <: AbstractDomain)

Fallback method for value ∈ d that returns false.

source


# Base.inMethod.
julia
Base.in(value, d::D) where D <: DiscreteDomain

Return true if value is a point of d.

source


# Base.isemptyMethod.
julia
Base.isempty(d <: AbstractDomain)

Fallback method for isempty(d) that return length(d) == 0 which default to 0.

source


# Base.lengthMethod.
julia
Base.length(itv::Intervals)

Return the sum of the length of each interval in itv.

source


# Base.lengthMethod.
julia
Base.rand(d <: AbstractDomain)

Fallback method for length(d) that return 0.

source


# Base.lengthMethod.
julia
Base.length(d::D) where D <: DiscreteDomain

Return the number of points in d.

source


# Base.randMethod.
julia
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}

Extends Base.rand to (a collection of) domains.

source


# Base.randMethod.
julia
Base.rand(fa::FakeAutomaton)

Extends Base.rand. Currently simply returns fa.

source


# Base.randMethod.
julia
Base.rand(itv::Intervals)
-Base.rand(itv::Intervals, i)

Return a random value from itv, specifically from the ith interval if i is specified.

source


# Base.randMethod.
julia
Base.rand(d::D) where D <: DiscreteDomain

Draw randomly a point in d.

source


# Base.stringMethod.
julia
Base.string(D::Vector{<:AbstractDomain})
-Base.string(d<:AbstractDomain)

Extends the string method to (a vector of) domains.

source


# ConstraintCommons.acceptMethod.
julia
ConstraintCommons.accept(fa::FakeAutomaton, word)

Implement the accept methods for FakeAutomaton.

source


# ConstraintDomains.ArbitraryDomainMethod.
julia
ArbitraryDomain{T} <: DiscreteDomain{T}

A domain type that stores arbitrary values, possibly non numeric, of type T.

source


# ConstraintDomains._exploreMethod.
julia
_explore(args...)

Internals of the explore function. Behavior is automatically adjusted on the kind of exploration: :flexible, :complete, :partial.

source


# ConstraintDomains.add!Method.
julia
add!(d::SetDomain, value)

Add value to the list of points in d.

source


# ConstraintDomains.domainMethod.
julia
domain(values)
-domain(range::R) where {T <: Real, R <: AbstractRange{T}}

Construct either a SetDomain or a \`RangeDomain\`\`.

julia
d1 = domain(1:5)
-d2 = domain([53.69, 89.2, 0.12])
-d3 = domain([2//3, 89//123])
-d4 = domain(4.3)
-d5 = domain(1,42,86.9)

source


# ConstraintDomains.domainMethod.
julia
domain()

Construct an EmptyDomain.

source


# ConstraintDomains.domainMethod.
julia
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
-domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}

Construct a domain of continuous interval(s).

source


# ConstraintDomains.domain_sizeMethod.
julia
domain_size(itv::Intervals)

Return the difference between the highest and lowest values in itv.

source


# ConstraintDomains.domain_sizeMethod.
julia
domain_size(d <: AbstractDomain)

Fallback method for domain_size(d) that return length(d).

source


# ConstraintDomains.domain_sizeMethod.
julia
domain_size(d::D) where D <: DiscreteDomain

Return the maximum distance between two points in d.

source


# ConstraintDomains.exploreMethod.
julia
explore(domains, concept, param = nothing; search_limit = 1000, solutions_limit = 100)

Search (a part of) a search space and returns a pair of vector of configurations: (solutions, non_solutions). If the search space size is over search_limit, then both solutions and non_solutions are limited to solutions_limit.

Beware that if the density of the solutions in the search space is low, solutions_limit needs to be reduced. This process will be automatic in the future (simple reinforcement learning).

Arguments:

  • domains: a collection of domains

  • concept: the concept of the targeted constraint

  • param: an optional parameter of the constraint

  • sol_number: the required number of solutions (half of the number of configurations), default to 100

source


# ConstraintDomains.fake_automatonMethod.
julia
fake_automaton(d)

Construct a FakeAutomaton.

source


# ConstraintDomains.generate_parametersMethod.
julia
generate_parameters(d<:AbstractDomain, param)

Generates random parameters based on the domain d and the kind of parameters param.

source


# ConstraintDomains.get_domainMethod.
julia
get_domain(::AbstractDomain)

Access the internal structure of any domain type.

source


# ConstraintDomains.intersect_domains!Method.
julia
intersect_domains!(is, i, new_itvls)

Compute the intersections of a domain with an interval and store the results in new_itvls.

Arguments

  • is::IS: a collection of intervals.

  • i::I: an interval.

  • new_itvls::Vector{I}: a vector to store the results.

source


# ConstraintDomains.intersect_domainsMethod.
julia
intersect_domains(d₁, d₂)

Compute the intersections of two domains.

source


# ConstraintDomains.merge_domainsMethod.
julia
merge_domains(d₁::AbstractDomain, d₂::AbstractDomain)

Merge two domains of same nature (discrete/contiuous).

source


# ConstraintDomains.sizeMethod.
julia
Base.size(i::I) where {I <: Interval}

Defines the size of an interval as its span.

source


# ConstraintDomains.to_domainsMethod.
julia
to_domains(args...)

Convert various arguments into valid domains format.

source


# Constraints.USUAL_CONSTRAINTSConstant.
julia
USUAL_CONSTRAINTS::Dict

Dictionary that contains all the usual constraints defined in Constraint.jl. It is based on XCSP3-core specifications available at https://arxiv.org/abs/2009.00514

Adding a new constraint is as simple as defining a new function with the same name as the constraint and using the @usual macro to define it. The macro will take care of adding the new constraint to the USUAL_CONSTRAINTS dictionary.

Example

julia
@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals)

source


# Constraints.USUAL_SYMMETRIESConstant.
julia
USUAL_SYMMETRIES

A Dictionary that contains the function to apply for each symmetry to avoid searching a whole space.

source


# Constraints.ConstraintType.
julia
Constraint

Parametric structure with the following fields.

  • concept: a Boolean function that, given an assignment x, outputs true if x satisfies the constraint, and false otherwise.

  • error: a positive function that works as preferences over invalid assignments. Return 0.0 if the constraint is satisfied, and a strictly positive real otherwise.

source


# ConstraintCommons.extract_parametersFunction.
julia
extract_parameters(s::Symbol, constraints_dict=USUAL_CONSTRAINTS; parameters=ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS)

Return the parameters of the constraint s in constraints_dict.

Arguments

  • s::Symbol: the constraint name.

  • constraints_dict::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

  • parameters::Vector{Symbol}: vector of parameters. Default is ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS.

Example

julia
extract_parameters(:all_different)

source


# Constraints.argsMethod.
julia
args(c::Constraint)

Return the expected length restriction of the arguments in a constraint c. The value nothing indicates that any strictly positive number of value is accepted.

source


# Constraints.conceptMethod.
julia
concept(c::Constraint)

Return the concept (function) of constraint c. concept(c::Constraint, x...; param = nothing) Apply the concept of c to values x and optionally param.

source


# Constraints.conceptMethod.
julia
concept(s::Symbol, args...; kargs...)

Return the concept of the constraint s applied to args and kargs. This is a shortcut for concept(USUAL_CONSTRAINTS[s])(args...; kargs...).

Arguments

  • s::Symbol: the constraint name.

  • args...: the arguments to apply the concept to.

  • kargs...: the keyword arguments to apply the concept to.

Example

julia
concept(:all_different, [1, 2, 3])

source


# Constraints.concept_vs_errorMethod.
julia
concept_vs_error(c, e, args...; kargs...)

Compare the results of a concept function and an error function for the same inputs. It is mainly used for testing purposes.

Arguments

  • c: The concept function.

  • e: The error function.

  • args...: Positional arguments to be passed to both the concept and error functions.

  • kargs...: Keyword arguments to be passed to both the concept and error functions.

Returns

  • Boolean: Returns true if the result of the concept function is not equal to whether the result of the error function is greater than 0.0. Otherwise, it returns false.

Examples

julia
concept_vs_error(all_different, make_error(:all_different), [1, 2, 3]) # Returns false

source


# Constraints.constraints_descriptionsFunction.
julia
constraints_descriptions(C=USUAL_CONSTRAINTS)

Return a pretty table with the descriptions of the constraints in C.

Arguments

  • C::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

Example

julia
constraints_descriptions()

source


# Constraints.constraints_parametersFunction.
julia
constraints_parameters(C=USUAL_CONSTRAINTS)

Return a pretty table with the parameters of the constraints in C.

Arguments

  • C::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

Example

julia
constraints_parameters()

source


# Constraints.describeFunction.
julia
describe(constraints::Dict{Symbol,Constraint}=USUAL_CONSTRAINTS; width=150)

Return a pretty table with the description of the constraints in constraints.

Arguments

  • constraints::Dict{Symbol,Constraint}: dictionary of constraints to describe. Default is USUAL_CONSTRAINTS.

  • width::Int: width of the table.

Example

julia
describe()

source


# Constraints.error_fMethod.
julia
error_f(c::Constraint)

Return the error function of constraint c. error_f(c::Constraint, x; param = nothing) Apply the error function of c to values x and optionally param.

source


# Constraints.make_errorMethod.
julia
make_error(symb::Symbol)

Create a function that returns an error based on the predicate of the constraint identified by the symbol provided.

Arguments

  • symb::Symbol: The symbol used to determine the error function to be returned. The function first checks if a predicate with the prefix "icn_" exists in the Constraints module. If it does, it returns that function. If it doesn't, it checks for a predicate with the prefix "error_". If that exists, it returns that function. If neither exists, it returns a function that evaluates the predicate with the prefix "concept_" and returns the negation of its result cast to Float64.

Returns

  • Function: A function that takes in a variable x and an arbitrary number of parameters params. The function returns a Float64.

Examples

julia
e = make_error(:all_different)
-e([1, 2, 3]) # Returns 0.0
-e([1, 1, 3]) # Returns 1.0

source


# Constraints.params_lengthMethod.
julia
params_length(c::Constraint)

Return the expected length restriction of the arguments in a constraint c. The value nothing indicates that any strictly positive number of parameters is accepted.

source


# Constraints.shrink_conceptMethod.
julia
shrink_concept(s)

Simply delete the concept_ part of symbol or string starting with it. TODO: add a check with a warning if s starts with something different.

source


# Constraints.symmetriesMethod.
julia
symmetries(c::Constraint)

Return the list of symmetries of c.

source


# Constraints.xcsp_all_differentMethod.
julia
xcsp_all_different(list::Vector{Int})

Return true if all the values of list are different, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

Variants

  • :all_different: Global constraint ensuring that all the values of x are all different.
julia
concept(:all_different, x; vals)
-concept(:all_different)(x; vals)

Examples

julia
c = concept(:all_different)
-
-c([1, 2, 3, 4])
-c([1, 2, 3, 1])
-c([1, 0, 0, 4]; vals=[0])
-c([1, 0, 0, 1]; vals=[0])

source


# Constraints.xcsp_all_equalMethod.
julia
xcsp_all_equal(list::Vector{Int}, val::Int)

Return true if all the values of list are equal to val, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • val::Int: value to compare to.

Variants

  • :all_equal: Global constraint ensuring that all the values of x are all equal.
julia
concept(:all_equal, x; val=nothing, pair_vars=zeros(x), op=+)
-concept(:all_equal)(x; val=nothing, pair_vars=zeros(x), op=+)

Examples

julia
c = concept(:all_equal)
-
-c([0, 0, 0, 0])
-c([1, 2, 3, 4])
-c([3, 2, 1, 0]; pair_vars=[0, 1, 2, 3])
-c([0, 1, 2, 3]; pair_vars=[0, 1, 2, 3])
-c([1, 2, 3, 4]; op=/, val=1, pair_vars=[1, 2, 3, 4])
-c([1, 2, 3, 4]; op=*, val=1, pair_vars=[1, 2, 3, 4])

source


# Constraints.xcsp_cardinalityMethod.
julia
xcsp_cardinality(list, values, occurs, closed)

Return true if the number of occurrences of the values in values in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • values::Vector{Int}: list of values to check.

  • occurs::Vector{Int}: list of occurrences to check.

  • closed::Bool: whether the constraint is closed or not.

Variants

  • :cardinality: The cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables.
julia
concept(:cardinality, x; bool=false, vals)
-concept(:cardinality)(x; bool=false, vals)
  • :cardinality_closed: The closed cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. It is closed, meaning that all values in the domain of the variables must be considered.
julia
concept(:cardinality_closed, x; vals)
-concept(:cardinality_closed)(x; vals)
  • :cardinality_open: The open cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. It is open, meaning that only the values in the list of values must be considered.
julia
concept(:cardinality_open, x; vals)
-concept(:cardinality_open)(x; vals)

Examples

julia
c = concept(:cardinality)
-
-c([2, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3])
-c([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=false)
-c([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=true)
-c([2, 5, 10, 10]; vals=[2 1; 5 1; 10 2])
-c([2, 5, 10, 10]; vals=[2 0 1 42; 5 1 3 7; 10 2 3 -4])
-c([2, 5, 5, 10]; vals=[2 0 1; 5 1 3; 10 2 3])
-c([2, 5, 10, 8]; vals=[2 1; 5 1; 10 2])
-c([5, 5, 5, 10]; vals=[2 0 1 42; 5 1 3 7; 10 2 3 -4])
-
-cc = concept(:cardinality_closed)
-cc([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3])
-
-co = concept(:cardinality_open)
-co([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3])

source


# Constraints.xcsp_channelMethod.
julia
xcsp_channel(; list)

Return true if the channel constraint is satisfied, false otherwise. The channel constraint establishes a bijective correspondence between two sets of variables. This means that each value in the first set of variables corresponds to a unique value in the second set, and vice versa.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

Variants

  • :channel: The channel constraint establishes a bijective correspondence between two sets of variables. This means that each value in the first set of variables corresponds to a unique value in the second set, and vice versa.
julia
concept(:channel, x; dim=1, id=nothing)
-concept(:channel)(x; dim=1, id=nothing)

Examples

julia
c = concept(:channel)
-
-c([2, 1, 4, 3])
-c([1, 2, 3, 4])
-c([2, 3, 1, 4])
-c([2, 1, 5, 3, 4, 2, 1, 4, 5, 3]; dim=2)
-c([2, 1, 4, 3, 5, 2, 1, 4, 5, 3]; dim=2)
-c([false, false, true, false]; id=3)
-c([false, false, true, false]; id=1)

source


# Constraints.xcsp_circuitMethod.
julia
xcsp_circuit(; list, size)

Return true if the circuit constraint is satisfied, false otherwise. The circuit constraint is a global constraint used in constraint programming, often in routing problems. It ensures that the values of a list of variables form a circuit, i.e., a sequence where each value is the index of the next value in the sequence, and the sequence eventually loops back to the start.

Arguments

  • list::AbstractVector: list of values to check.

  • size::Int: size of the circuit.

Variants

  • :circuit: The circuit constraint is a global constraint used in constraint programming, often in routing problems. It ensures that the values of a list of variables form a circuit, i.e., a sequence where each value is the index of the next value in the sequence, and the sequence eventually loops back to the start.
julia
concept(:circuit, x; op, val)
-concept(:circuit)(x; op, val)

Examples

julia
c = concept(:circuit)
-
-c([1, 2, 3, 4])
-c([2, 3, 4, 1])
-c([2, 3, 1, 4]; op = ==, val = 3)
-c([4, 3, 1, 3]; op = >, val = 0)

source


# Constraints.xcsp_countMethod.
julia
xcsp_count(list, values, condition)

Return true if the number of occurrences of the values in values in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • values::Vector{Int}: list of values to check.

  • condition: condition to satisfy.

Variants

  • :count: Constraint ensuring that the number of occurrences of the values in vals in x satisfies the given condition.
julia
concept(:count, x; vals, op, val)
-concept(:count)(x; vals, op, val)
  • :at_least: Constraint ensuring that the number of occurrences of the values in vals in x is at least val.
julia
concept(:at_least, x; vals, val)
-concept(:at_least)(x; vals, val)
  • :at_most: Constraint ensuring that the number of occurrences of the values in vals in x is at most val.
julia
concept(:at_most, x; vals, val)
-concept(:at_most)(x; vals, val)
  • :exactly: Constraint ensuring that the number of occurrences of the values in vals in x is exactly val.
julia
concept(:exactly, x; vals, val)
-concept(:exactly)(x; vals, val)

Examples

julia
c = concept(:count)
-
-c([2, 1, 4, 3]; vals=[1, 2, 3, 4], op=≥, val=2)
-c([1, 2, 3, 4]; vals=[1, 2], op==, val=2)
-c([2, 1, 4, 3]; vals=[1, 2], op=≤, val=1)

source


# Constraints.xcsp_cumulativeMethod.
julia
xcsp_cumulative(; origins, lengths, heights, condition)

Return true if the cumulative constraint is satisfied, false otherwise. The cumulative constraint is a global constraint used in constraint programming that is often used in scheduling problems. It ensures that for any point in time, the sum of the "heights" of tasks that are ongoing at that time does not exceed a certain limit.

Arguments

  • origins::AbstractVector: list of origins of the tasks.

  • lengths::AbstractVector: list of lengths of the tasks.

  • heights::AbstractVector: list of heights of the tasks.

  • condition::Tuple: condition to check.

Variants

  • :cumulative: The cumulative constraint is a global constraint used in constraint programming that is often used in scheduling problems. It ensures that for any point in time, the sum of the "heights" of tasks that are ongoing at that time does not exceed a certain limit.
julia
concept(:cumulative, x; pair_vars, op, val)
-concept(:cumulative)(x; pair_vars, op, val)

Examples

julia
c = concept(:cumulative)
-
-c([1, 2, 3, 4, 5]; val = 1)
-c([1, 2, 2, 4, 5]; val = 1)
-c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op =, val = 5)
-c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5)

source


# Constraints.xcsp_elementMethod.
julia
xcsp_element(; list, index, condition)

Return true if the element constraint is satisfied, false otherwise. The element constraint is a global constraint used in constraint programming that specifies that the value of a variable should be equal to the value of another variable indexed by a third variable.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

  • index::Int: index of the value to check.

  • condition::Tuple: condition to check.

Variants

  • :element: The element constraint is a global constraint used in constraint programming that specifies that the value of a variable should be equal to the value of another variable indexed by a third variable.
julia
concept(:element, x; id=nothing, op===, val=nothing)
-concept(:element)(x; id=nothing, op===, val=nothing)

Examples

julia
c = concept(:element)
-
-c([1, 2, 3, 4, 5]; id=1, val=1)
-c([1, 2, 3, 4, 5]; id=1, val=2)
-c([1, 2, 3, 4, 2])
-c([1, 2, 3, 4, 1])

source


# Constraints.xcsp_extensionMethod.
julia
xcsp_extension(; list, supports=nothing, conflicts=nothing)

Global constraint enforcing that the tuple x matches a configuration within the supports set pair_vars[1] or does not match any configuration within the conflicts set pair_vars[2]. It embodies the logic: x ∈ pair_vars[1] || x ∉ pair_vars[2], providing a comprehensive way to define valid (supported) and invalid (conflicted) tuples for constraint satisfaction problems. This constraint is versatile, allowing for the explicit delineation of both acceptable and unacceptable configurations.

Arguments

  • list::Vector{Int}: A list of variables

  • supports::Vector{Vector{Int}}: A set of supported tuples. Default to nothing.

  • conflicts::Vector{Vector{Int}}: A set of conflicted tuples. Default to nothing.

Variants

  • :extension: Global constraint enforcing that the tuple x matches a configuration within the supports set pair_vars[1] or does not match any configuration within the conflicts set pair_vars[2]. It embodies the logic: x ∈ pair_vars[1] || x ∉ pair_vars[2], providing a comprehensive way to define valid (supported) and invalid (conflicted) tuples for constraint satisfaction problems. This constraint is versatile, allowing for the explicit delineation of both acceptable and unacceptable configurations.
julia
concept(:extension, x; pair_vars)
-concept(:extension)(x; pair_vars)
  • :supports: Global constraint ensuring that the tuple x matches a configuration listed within the support set pair_vars. This constraint is derived from the extension model, specifying that x must be one of the explicitly defined supported configurations: x ∈ pair_vars. It is utilized to directly declare the tuples that are valid and should be included in the solution space.
julia
concept(:supports, x; pair_vars)
-concept(:supports)(x; pair_vars)
  • :conflicts: Global constraint ensuring that the tuple x does not match any configuration listed within the conflict set pair_vars. This constraint, originating from the extension model, stipulates that x must avoid all configurations defined as conflicts: x ∉ pair_vars. It is useful for specifying tuples that are explicitly forbidden and should be excluded from the solution space.
julia
concept(:conflicts, x; pair_vars)
-concept(:conflicts)(x; pair_vars)

Examples

julia
c = concept(:extension)
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 3, 4, 5]])
-c([1, 2, 3, 4, 5]; pair_vars=([[1, 2, 3, 4, 5]], [[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]]))
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]])
-
-c = concept(:supports)
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 3, 4, 5]])
-
-c = concept(:conflicts)
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]])

source


# Constraints.xcsp_instantiationMethod.
julia
xcsp_instantiation(; list, values)

Return true if the instantiation constraint is satisfied, false otherwise. The instantiation constraint is a global constraint used in constraint programming that ensures that a list of variables takes on a specific set of values in a specific order.

Arguments

  • list::AbstractVector: list of values to check.

  • values::AbstractVector: list of values to check against.

Variants

  • :instantiation: The instantiation constraint is a global constraint used in constraint programming that ensures that a list of variables takes on a specific set of values in a specific order.
julia
concept(:instantiation, x; pair_vars)
-concept(:instantiation)(x; pair_vars)

Examples

julia
c = concept(:instantiation)
-
-c([1, 2, 3, 4, 5]; pair_vars=[1, 2, 3, 4, 5])
-c([1, 2, 3, 4, 5]; pair_vars=[1, 2, 3, 4, 6])

source


# Constraints.xcsp_intensionMethod.
julia
xcsp_intension(list, predicate)

An intensional constraint is usually defined from a predicate over list. As such it encompass any generic constraint.

Arguments

  • list::Vector{Int}: A list of variables

  • predicate::Function: A predicate over list

Variants

  • :dist_different: A constraint ensuring that the distances between marks on the ruler are unique. Specifically, it checks that the distance between x[1] and x[2], and the distance between x[3] and x[4], are different. This constraint is fundamental in ensuring the validity of a Golomb ruler, where no two pairs of marks should have the same distance between them.
julia
concept(:dist_different, x)
-concept(:dist_different)(x)

Examples

@example
2 + 2
@example
2 + 2
@example
using Constraints # hide
-c = concept(:dist_different)
-c([1, 2, 3, 3]) && !c([1, 2, 3, 4])
@example
using Constraints # hide
-c = concept(:dist_different)
-c([1, 2, 3, 3]) && !c([1, 2, 3, 4])

source


# Constraints.xcsp_maximumMethod.
julia
xcsp_maximum(; list, condition)

Return true if the maximum constraint is satisfied, false otherwise. The maximum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the maximum value in a list of variables.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

  • condition::Tuple: condition to check.

Variants

  • :maximum: The maximum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the maximum value in a list of variables.
julia
concept(:maximum, x; op, val)
-concept(:maximum)(x; op, val)

Examples

julia
c = concept(:maximum)
-
-c([1, 2, 3, 4, 5]; op = ==, val = 5)
-c([1, 2, 3, 4, 5]; op = ==, val = 6)

source


# Constraints.xcsp_mddMethod.
julia
xcsp_mdd(; list, diagram)

Return a function that checks if the list of values list satisfies the MDD diagram.

Arguments

  • list::Vector{Int}: list of values to check.

  • diagram::MDD: MDD to check.

Variants

  • :mdd: Multi-valued Decision Diagram (MDD) constraint. The MDD constraint is a constraint that can be used to model a wide range of problems. It is a directed graph where each node is labeled with a value and each edge is labeled with a value. The constraint is satisfied if there is a path from the first node to the last node such that the sequence of edge labels is a valid sequence of the value labels.
julia
concept(:mdd, x; language)
-concept(:mdd)(x; language)

Examples

julia
c = concept(:mdd)
-
-states = [
-    Dict( # level x1
-        (:r, 0) => :n1,
-        (:r, 1) => :n2,
-        (:r, 2) => :n3,
-    ),
-    Dict( # level x2
-        (:n1, 2) => :n4,
-        (:n2, 2) => :n4,
-        (:n3, 0) => :n5,
-    ),
-    Dict( # level x3
-        (:n4, 0) => :t,
-        (:n5, 0) => :t,
-    ),
-]
-
-a = MDD(states)
-
-c([0,2,0]; language = a)
-c([1,2,0]; language = a)
-c([2,0,0]; language = a)
-c([2,1,2]; language = a)
-c([1,0,2]; language = a)
-c([0,1,2]; language = a)

source


# Constraints.xcsp_minimumMethod.
julia
xcsp_minimum(; list, condition)

Return true if the minimum constraint is satisfied, false otherwise. The minimum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the minimum value in a list of variables.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

  • condition::Tuple: condition to check.

Variants

  • :minimum: The minimum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the minimum value in a list of variables.
julia
concept(:minimum, x; op, val)
-concept(:minimum)(x; op, val)

Examples

julia
c = concept(:minimum)
-
-c([1, 2, 3, 4, 5]; op = ==, val = 1)
-c([1, 2, 3, 4, 5]; op = ==, val = 0)

source


# Constraints.xcsp_no_overlapMethod.
julia
xcsp_no_overlap(; origins, lengths, zero_ignored)

Return true if the no_overlap constraint is satisfied, false otherwise. The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts.

Arguments

  • origins::AbstractVector: list of origins of the tasks.

  • lengths::AbstractVector: list of lengths of the tasks.

  • zero_ignored::Bool: whether to ignore zero-length tasks.

Variants

  • :no_overlap: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts.
julia
concept(:no_overlap, x; pair_vars, bool)
-concept(:no_overlap)(x; pair_vars, bool)
  • :no_overlap_no_zero: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant ignores zero-length tasks.
julia
concept(:no_overlap_no_zero, x; pair_vars)
-concept(:no_overlap_no_zero)(x; pair_vars)
  • :no_overlap_with_zero: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant includes zero-length tasks.
julia
concept(:no_overlap_with_zero, x; pair_vars)
-concept(:no_overlap_with_zero)(x; pair_vars)

Examples

julia
c = concept(:no_overlap)
-
-c([1, 2, 3, 4, 5])
-c([1, 2, 3, 4, 1])
-c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 1, 1])
-c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 3, 1])
-c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 3, 1, 1])
-c([1, 1, 1, 3, 5, 2, 7, 7, 5, 12, 8, 7]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3)
-c([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3)

source


# Constraints.xcsp_nvaluesMethod.
julia
xcsp_nvalues(list, condition, except)

Return true if the number of distinct values in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • condition: condition to satisfy.

  • except::Union{Nothing, Vector{Int}}: list of values to exclude. Default is nothing.

Variants

  • :nvalues: The nValues constraint specifies that the number of distinct values in the list of variables x is equal to a given value. The constraint is defined by the following expression: nValues(x, op, val) where x is a list of variables, op is a comparison operator, and val is an integer value.
julia
concept(:nvalues, x; op, val)
-concept(:nvalues)(x; op, val)

Examples

julia
c = concept(:nvalues)
-
-c([1, 2, 3, 4, 5]; op = ==, val = 5)
-c([1, 2, 3, 4, 5]; op = ==, val = 2)
-c([1, 2, 3, 4, 3]; op = <=, val = 5)
-c([1, 2, 3, 4, 3]; op = <=, val = 3)

source


# Constraints.xcsp_orderedMethod.
julia
xcsp_ordered(list::Vector{Int}, operator, lengths)

Return true if all the values of list are in an increasing order, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • operator: comparison operator to use.

  • lengths: list of lengths to use. Defaults to nothing.

Variants

  • :ordered: Global constraint ensuring that all the values of x are in an increasing order.
julia
concept(:ordered, x; op=≤, pair_vars=nothing)
-concept(:ordered)(x; op=≤, pair_vars=nothing)
  • :increasing: Global constraint ensuring that all the values of x are in an increasing order.
julia
concept(:increasing, x; op=≤, pair_vars=nothing)
-concept(:increasing)(x; op=≤, pair_vars=nothing)
  • :decreasing: Global constraint ensuring that all the values of x are in a decreasing order.
julia
concept(:decreasing, x; op=≥, pair_vars=nothing)
-concept(:decreasing)(x; op=≥, pair_vars=nothing)
  • :strictly_increasing: Global constraint ensuring that all the values of x are in a strictly increasing order.
julia
concept(:strictly_increasing, x; op=<, pair_vars=nothing)
-concept(:strictly_increasing)(x; op=<, pair_vars=nothing)
  • :strictly_decreasing: Global constraint ensuring that all the values of x are in a strictly decreasing order.
julia
concept(:strictly_decreasing, x; op=>, pair_vars=nothing)
-concept(:strictly_decreasing)(x; op=>, pair_vars=nothing)

Examples

julia
c = concept(:ordered)
-
-c([1, 2, 3, 4, 4]; op=≤)
-c([1, 2, 3, 4, 5]; op=<)
-!c([1, 2, 3, 4, 3]; op=≤)
-!c([1, 2, 3, 4, 3]; op=<)

source


# Constraints.xcsp_regularMethod.
julia
xcsp_regular(; list, automaton)
-
-Ensures that a sequence \`x\` (interpreted as a word) is accepted by the regular language represented by a given automaton. This constraint verifies the compliance of \`x\` with the language rules encoded within the \`automaton\` parameter, which must be an instance of \`<:AbstractAutomaton\`.

Arguments

  • list::Vector{Int}: A list of variables

  • automaton<:AbstractAutomaton: An automaton representing the regular language

Variants

  • :regular: Ensures that a sequence x (interpreted as a word) is accepted by the regular language represented by a given automaton. This constraint verifies the compliance of x with the language rules encoded within the automaton parameter, which must be an instance of <:AbstractAutomaton.
julia
concept(:regular, x; language)
-concept(:regular)(x; language)

Examples

julia
c = concept(:regular)
-
-states = Dict(
-    (:a, 0) => :a,
-    (:a, 1) => :b,
-    (:b, 1) => :c,
-    (:c, 0) => :d,
-    (:d, 0) => :d,
-    (:d, 1) => :e,
-    (:e, 0) => :e,
-)
-start = :a
-finish = :e
-
-a = Automaton(states, start, finish)
-
-c([0,0,1,1,0,0,1,0,0]; language = a)
-c([1,1,1,0,1]; language = a)

source


# Constraints.xcsp_sumMethod.
julia
xcsp_sum(list, coeffs, condition)

Return true if the sum of the variables in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • coeffs::Vector{Int}: list of coefficients to use.

  • condition: condition to satisfy.

Variants

  • :sum: Global constraint ensuring that the sum of the variables in x satisfies a given condition.
julia
concept(:sum, x; op===, pair_vars=ones(x), val)
-concept(:sum)(x; op===, pair_vars=ones(x), val)

Examples

julia
c = concept(:sum)
-
-c([1, 2, 3, 4, 5]; op===, val=15)
-c([1, 2, 3, 4, 5]; op===, val=2)
-c([1, 2, 3, 4, 3]; op=≤, val=15)
-c([1, 2, 3, 4, 3]; op=≤, val=3)

source


# Constraints.@usualMacro.
julia
usual(ex::Expr)

This macro is used to define a new constraint or update an existing one in the USUAL_CONSTRAINTS dictionary. It takes an expression ex as input, which represents the definition of a constraint.

Here's a step-by-step explanation of what the macro does:

  1. It first extracts the symbol of the concept from the input expression. This symbol is expected to be the first argument of the first argument of the expression. For example, if the expression is @usual all_different(x; y=1), the symbol would be :all_different.

  2. It then calls the shrink_concept function on the symbol to get a simplified version of the concept symbol.

  3. It initializes a dictionary defaults to store whether each keyword argument of the concept has a default value or not.

  4. It checks if the expression has more than two arguments. If it does, it means that there are keyword arguments present. It then loops over these keyword arguments. If a keyword argument is a symbol, it means it doesn't have a default value, so it adds an entry to the defaults dictionary with the keyword argument as the key and false as the value. If a keyword argument is not a symbol, it means it has a default value, so it adds an entry to the defaults dictionary with the keyword argument as the key and true as the value.

  5. It calls the make_error function on the simplified concept symbol to generate an error function for the constraint.

  6. It evaluates the input expression to get the concept function.

  7. It checks if the USUAL_CONSTRAINTS dictionary already contains an entry for the simplified concept symbol. If it does, it adds the defaults dictionary to the parameters of the existing constraint. If it doesn't, it creates a new constraint with the concept function, a description, the error function, and the defaults dictionary as the parameters, and adds it to the USUAL_CONSTRAINTS dictionary.

This macro is used to make it easier to define and update constraints in a consistent and possibly automated way.

Arguments

  • ex::Expr: expression to parse.

Example

julia
@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals)

source


# CompositionalNetworks.CompositionType.
julia
struct Composition{F<:Function}

Store the all the information of a composition learned by an ICN.

source


# CompositionalNetworks.CompositionMethod.
julia
Composition(f::F, symbols) where {F<:Function}

Construct a Composition.

source


# CompositionalNetworks.ICNType.
julia
ICN(; nvars, dom_size, param, transformation, arithmetic, aggregation, comparison)

Construct an Interpretable Compositional Network, with the following arguments:

  • nvars: number of variable in the constraint

  • dom_size: maximum domain size of any variable in the constraint

  • param: optional parameter (default to nothing)

  • transformation: a transformation layer (optional)

  • arithmetic: a arithmetic layer (optional)

  • aggregation: a aggregation layer (optional)

  • comparison: a comparison layer (optional)

source


# CompositionalNetworks.LayerType.
julia
Layer

A structure to store a LittleDict of operations that can be selected during the learning phase of an ICN. If the layer is exclusive, only one operation can be selected at a time.

source


# Base.lengthMethod.
julia
length(layer)

Return the number of operations in a layer.

source


# Base.lengthMethod.
julia
Base.length(icn)

Return the total number of operations of an ICN.

source


# CompositionalNetworks._composeMethod.
julia
_compose(icn)

Internal function called by compose and show_composition.

source


# CompositionalNetworks.ag_count_positiveMethod.
julia
ag_count_positive(x)

Count the number of strictly positive elements of x.

source


# CompositionalNetworks.ag_sumMethod.
julia
ag_sum(x)

Aggregate through + a vector into a single scalar.

source


# CompositionalNetworks.aggregation_layerMethod.
julia
aggregation_layer()

Generate the layer of aggregations of the ICN. The operations are mutually exclusive, that is only one will be selected.

source


# CompositionalNetworks.ar_prodMethod.
julia
ar_prod(x)

Reduce k = length(x) vectors through product to a single vector.

source


# CompositionalNetworks.ar_sumMethod.
julia
ar_sum(x)

Reduce k = length(x) vectors through sum to a single vector.

source


# CompositionalNetworks.arithmetic_layerMethod.
julia
arithmetic_layer()

Generate the layer of arithmetic operations of the ICN. The operations are mutually exclusive, that is only one will be selected.

source


# CompositionalNetworks.as_bitvectorFunction.
julia
as_bitvector(n::Int, max_n::Int = n)

Convert an Int to a BitVector of minimal size (relatively to max_n).

source


# CompositionalNetworks.as_intMethod.
julia
as_int(v::AbstractVector)

Convert a BitVector into an Int.

source


# CompositionalNetworks.co_abs_diff_val_paramMethod.
julia
co_abs_diff_val_param(x; param)

Return the absolute difference between x and param.

source


# CompositionalNetworks.co_abs_diff_val_varsMethod.
julia
co_abs_diff_val_vars(x; nvars)

Return the absolute difference between x and the number of variables nvars.

source


# CompositionalNetworks.co_euclideanMethod.
julia
co_euclidean(x; dom_size)

Compute an euclidean norm with domain size dom_size of a scalar.

source


# CompositionalNetworks.co_euclidean_paramMethod.
julia
co_euclidean_param(x; param, dom_size)

Compute an euclidean norm with domain size dom_size, weighted by param, of a scalar.

source


# CompositionalNetworks.co_identityMethod.
julia
co_identity(x)

Identity function. Already defined in Julia as identity, specialized for scalars in the comparison layer.

source


# CompositionalNetworks.co_param_minus_valMethod.
julia
co_param_minus_val(x; param)

Return the difference param - x if positive, 0.0 otherwise.

source


# CompositionalNetworks.co_val_minus_paramMethod.
julia
co_val_minus_param(x; param)

Return the difference x - param if positive, 0.0 otherwise.

source


# CompositionalNetworks.co_val_minus_varsMethod.
julia
co_val_minus_vars(x; nvars)

Return the difference x - nvars if positive, 0.0 otherwise, where nvars denotes the numbers of variables.

source


# CompositionalNetworks.co_vars_minus_valMethod.
julia
co_vars_minus_val(x; nvars)

Return the difference nvars - x if positive, 0.0 otherwise, where nvars denotes the numbers of variables.

source


# CompositionalNetworks.codeFunction.
julia
code(c::Composition, lang=:maths; name="composition")

Access the code of a composition c in a given language lang. The name of the generated method is optional.

source


# CompositionalNetworks.comparison_layerFunction.
julia
comparison_layer(param = false)

Generate the layer of transformations functions of the ICN. Iff param value is set, also includes all the parametric comparison with that value. The operations are mutually exclusive, that is only one will be selected.

source


# CompositionalNetworks.composeFunction.
julia
compose(icn, weights=nothing)

Return a function composed by some of the operations of a given ICN. Can be applied to any vector of variables. If weights are given, will assign to icn.

source


# CompositionalNetworks.compose_to_file!Method.
julia
compose_to_file!(concept, name, path; domains, param = nothing, language = :Julia, search = :complete, global_iter = 10, local_iter = 100, metric = hamming, popSize = 200)

Explore, learn and compose a function and write it to a file.

Arguments:

  • concept: the concept to learn

  • name: the name to give to the constraint

  • path: path of the output file

Keywords arguments:

  • domains: domains that defines the search space

  • param: an optional parameter of the constraint

  • language: the language to export to, default to :julia

  • search: either :partial or :complete search

  • global_iter: number of learning iteration

  • local_iter: number of generation in the genetic algorithm

  • metric: the metric to measure the distance between a configuration and known solutions

  • popSize: size of the population in the genetic algorithm

source


# CompositionalNetworks.compositionMethod.
julia
composition(c::Composition)

Access the actual method of an ICN composition c.

source


# CompositionalNetworks.composition_to_file!Function.
julia
composition_to_file!(c::Composition, path, name, language=:Julia)

Write the composition code in a given language into a file at path.

source


# CompositionalNetworks.excluMethod.
julia
exclu(layer)

Return true if the layer has mutually exclusive operations.

source


# CompositionalNetworks.explore_learn_composeMethod.
julia
explore_learn_compose(concept; domains, param = nothing, search = :complete, global_iter = 10, local_iter = 100, metric = hamming, popSize = 200, action = :composition)

Explore a search space, learn a composition from an ICN, and compose an error function.

Arguments:

  • concept: the concept of the targeted constraint

  • domains: domains of the variables that define the training space

  • param: an optional parameter of the constraint

  • search: either flexible,:partial or :complete search. Flexible search will use search_limit and solutions_limit to determine if the search space needs to be partially or completely explored

  • global_iter: number of learning iteration

  • local_iter: number of generation in the genetic algorithm

  • metric: the metric to measure the distance between a configuration and known solutions

  • popSize: size of the population in the genetic algorithm

  • action: either :symbols to have a description of the composition or :composition to have the composed function itself

source


# CompositionalNetworks.functionsMethod.
julia
functions(layer)

Access the operations of a layer. The container is ordered.

source


# CompositionalNetworks.generateMethod.
julia
generate(c::Composition, name, lang)

Generates the code of c in a specific language lang.

source


# CompositionalNetworks.generate_exclusive_operationMethod.
julia
generate_exclusive_operation(max_op_number)

Generates the operations (weigths) of a layer with exclusive operations.

source


# CompositionalNetworks.generate_inclusive_operationsMethod.
julia
generate_inclusive_operations(predicate, bits)
-generate_exclusive_operation(max_op_number)

Generates the operations (weights) of a layer with inclusive/exclusive operations.

source


# CompositionalNetworks.generate_weightsMethod.
julia
generate_weights(layers)
-generate_weights(icn)

Generate the weights of a collection of layers or of an ICN.

source


# CompositionalNetworks.hammingMethod.
julia
hamming(x, X)

Compute the hamming distance of x over a collection of solutions X, i.e. the minimal number of variables to switch in xto reach a solution.

source


# CompositionalNetworks.is_viableMethod.
julia
is_viable(layer, w)
-is_viable(icn)
-is_viable(icn, w)

Assert if a pair of layer/icn and weights compose a viable pattern. If no weights are given with an icn, it will check the current internal value.

source


# CompositionalNetworks.layersMethod.
julia
layers(icn)

Return the ordered layers of an ICN.

source


# CompositionalNetworks.lazyMethod.
julia
lazy(funcs::Function...)

Generate methods extended to a vector instead of one of its components. A function f should have the following signature: f(i::Int, x::V).

source


# CompositionalNetworks.lazy_paramMethod.
julia
lazy_param(funcs::Function...)

Generate methods extended to a vector instead of one of its components. A function f should have the following signature: f(i::Int, x::V; param).

source


# CompositionalNetworks.learn_composeMethod.
julia
learn_compose(;
-    nvars, dom_size, param=nothing, icn=ICN(nvars, dom_size, param),
-    X, X_sols, global_iter=100, local_iter=100, metric=hamming, popSize=200
-)

Create an ICN, optimize it, and return its composition.

source


# CompositionalNetworks.make_transformationsMethod.
julia
make_transformations(param::Symbol)

Generates a dictionary of transformation functions based on the specified parameterization. This function facilitates the creation of parametric layers for constraint transformations, allowing for flexible and dynamic constraint manipulation according to the needs of different constraint programming models.

Parameters

  • param::Symbol: Specifies the type of transformations to generate. It can be :none for basic transformations that do not depend on external parameters, or :val for transformations that operate with respect to a specific value parameter.

Returns

  • LittleDict{Symbol, Function}: A dictionary mapping transformation names (Symbol) to their corresponding functions (Function). The functions encapsulate various types of transformations, such as counting, comparison, and contiguous value processing.

Transformation Types

  • When param is :none, the following transformations are available:

    • :identity: No transformation is applied.

    • :count_eq, :count_eq_left, :count_eq_right: Count equalities under different conditions.

    • :count_greater, :count_lesser: Count values greater or lesser than a threshold.

    • :count_g_left, :count_l_left, :count_g_right, :count_l_right: Count values with greater or lesser comparisons from different directions.

    • :contiguous_vals_minus, :contiguous_vals_minus_rev: Process contiguous values with subtraction in normal and reverse order.

  • When param is :val, the transformations relate to operations involving a parameter value:

    • :count_eq_param, :count_l_param, :count_g_param: Count equalities or comparisons against a parameter value.

    • :count_bounding_param: Count values bounding a parameter value.

    • :val_minus_param, :param_minus_val: Subtract a parameter value from values or vice versa.

The function delegates to a version that uses Val(param) for dispatch, ensuring compile-time selection of the appropriate transformation set.

Examples

julia
# Get basic transformations
-basic_transforms = make_transformations(:none)
-
-# Apply an identity transformation
-identity_result = basic_transforms[:identity](data)
-
-# Get value-based transformations
-val_transforms = make_transformations(:val)
-
-# Apply a count equal to parameter transformation
-count_eq_param_result = val_transforms[:count_eq_param](data, param)

source


# CompositionalNetworks.manhattanMethod.
julia
manhattan(x, X)

source


# CompositionalNetworks.map_tr!Method.
julia
map_tr!(f, x, X, param)

Return an anonymous function that applies f to all elements of x and store the result in X, with a parameter param (which is set to nothing for function with no parameter).

source


# CompositionalNetworks.minkowskiMethod.
julia
minkowski(x, X, p)

source


# CompositionalNetworks.nbitsMethod.
julia
nbits(icn)

Return the expected number of bits of a viable weight of an ICN.

source


# CompositionalNetworks.nbits_excluMethod.
julia
nbits_exclu(layer)

Convert the length of an exclusive layer into a number of bits.

source


# CompositionalNetworks.reduce_symbolsFunction.
julia
reduce_symbols(symbols, sep)

Produce a formatted string that separates the symbols by sep. Used internally for show_composition.

source


# CompositionalNetworks.regularizationMethod.
julia
regularization(icn)

Return the regularization value of an ICN weights, which is proportional to the normalized number of operations selected in the icn layers.

source


# CompositionalNetworks.selected_sizeMethod.
julia
selected_size(layer, layer_weights)

Return the number of operations selected by layer_weights in layer.

source


# CompositionalNetworks.show_layerMethod.
julia
show_layer(layer)

Return a string that contains the elements in a layer.

source


# CompositionalNetworks.show_layersMethod.
julia
show_layers(icn)

Return a formatted string with each layers in the icn.

source


# CompositionalNetworks.symbolMethod.
julia
symbol(layer, i)

Return the i-th symbols of the operations in a given layer.

source


# CompositionalNetworks.symbolsMethod.
julia
symbols(c::Composition)

Output the composition as a layered collection of Symbols.

source


# CompositionalNetworks.tr_contiguous_vals_minusMethod.
julia
tr_contiguous_vals_minus(i, x)
-tr_contiguous_vals_minus(x)
-tr_contiguous_vals_minus(x, X::AbstractVector)

Return the difference x[i] - x[i + 1] if positive, 0.0 otherwise. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_contiguous_vals_minus_revMethod.
julia
tr_contiguous_vals_minus_rev(i, x)
-tr_contiguous_vals_minus_rev(x)
-tr_contiguous_vals_minus_rev(x, X::AbstractVector)

Return the difference x[i + 1] - x[i] if positive, 0.0 otherwise. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_bounding_paramMethod.
julia
tr_count_bounding_param(i, x; param)
-tr_count_bounding_param(x; param)
-tr_count_bounding_param(x, X::AbstractVector; param)

Count the number of elements bounded (not strictly) by x[i] and x[i] + param. An extended method to vector with sig (x, param) is generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eqMethod.
julia
tr_count_eq(i, x)
-tr_count_eq(x)
-tr_count_eq(x, X::AbstractVector)

Count the number of elements equal to x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eq_leftMethod.
julia
tr_count_eq_left(i, x)
-tr_count_eq_left(x)
-tr_count_eq_left(x, X::AbstractVector)

Count the number of elements to the left of and equal to x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eq_paramMethod.
julia
tr_count_eq_param(i, x; param)
-tr_count_eq_param(x; param)
-tr_count_eq_param(x, X::AbstractVector; param)

Count the number of elements equal to x[i] + param. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eq_rightMethod.
julia
tr_count_eq_right(i, x)
-tr_count_eq_right(x)
-tr_count_eq_right(x, X::AbstractVector)

Count the number of elements to the right of and equal to x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_g_leftMethod.
julia
tr_count_g_left(i, x)
-tr_count_g_left(x)
-tr_count_g_left(x, X::AbstractVector)

Count the number of elements to the left of and greater than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_g_paramMethod.
julia
tr_count_g_param(i, x; param)
-tr_count_g_param(x; param)
-tr_count_g_param(x, X::AbstractVector; param)

Count the number of elements greater than x[i] + param. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_g_rightMethod.
julia
tr_count_g_right(i, x)
-tr_count_g_right(x)
-tr_count_g_right(x, X::AbstractVector)

Count the number of elements to the right of and greater than x[i]. Extended method to vector with sig (x) are generated.

source


# CompositionalNetworks.tr_count_greaterMethod.
julia
tr_count_greater(i, x)
-tr_count_greater(x)
-tr_count_greater(x, X::AbstractVector)

Count the number of elements greater than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_l_leftMethod.
julia
tr_count_l_left(i, x)
-tr_count_l_left(x)
-tr_count_l_left(x, X::AbstractVector)

Count the number of elements to the left of and lesser than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_l_paramMethod.
julia
tr_count_l_param(i, x; param)
-tr_count_l_param(x; param)
-tr_count_l_param(x, X::AbstractVector; param)

Count the number of elements lesser than x[i] + param. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_l_rightMethod.
julia
tr_count_l_right(i, x)
-tr_count_l_right(x)
-tr_count_l_right(x, X::AbstractVector)

Count the number of elements to the right of and lesser than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_lesserMethod.
julia
tr_count_lesser(i, x)
-tr_count_lesser(x)
-tr_count_lesser(x, X::AbstractVector)

Count the number of elements lesser than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_identityMethod.
julia
tr_identity(i, x)
-tr_identity(x)
-tr_identity(x, X::AbstractVector)

Identity function. Already defined in Julia as identity, specialized for vectors. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_in_unrolled_expansion_##225Method.
julia
tr_in(tr, X, x, param)

Application of an operation from the transformation layer. Used to generate more efficient code for all compositions.

source


# CompositionalNetworks.tr_param_minus_valMethod.
julia
tr_param_minus_val(i, x; param)
-tr_param_minus_val(x; param)
-tr_param_minus_val(x, X::AbstractVector; param)

Return the difference param - x[i] if positive, 0.0 otherwise. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_val_minus_paramMethod.
julia
tr_val_minus_param(i, x; param)
-tr_val_minus_param(x; param)
-tr_val_minus_param(x, X::AbstractVector; param)

Return the difference x[i] - param if positive, 0.0 otherwise. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.transformation_layerFunction.
julia
transformation_layer(param = false)

Generate the layer of transformations functions of the ICN. Iff param value is true, also includes all the parametric transformations.

source


# CompositionalNetworks.weights!Method.
julia
weights!(icn, weights)

Set the weights of an ICN with a BitVector.

source


# CompositionalNetworks.weightsMethod.
julia
weights(icn)

Access the current set of weights of an ICN.

source


# CompositionalNetworks.weights_biasMethod.
julia
weights_bias(x)

A metric that bias x towards operations with a lower bit. Do not affect the main metric.

source


# QUBOConstraints.AbstractOptimizerType.
julia
AbstractOptimizer

An abstract type (interface) used to learn QUBO matrices from constraints. Only a train method is required.

source


# QUBOConstraints.QUBO_baseFunction.
julia
QUBO_base(n, weight = 1)

A basic QUBO matrix to ensure that binarized variables keep a valid encoding.

source


# QUBOConstraints.QUBO_linear_sumMethod.
julia
QUBO_linear_sum(n, σ)

One valid QUBO matrix given n variables and parameter σ for the linear sum constraint.

source


# QUBOConstraints.binarizeMethod.
julia
binarize(x[, domain]; binarization = :one_hot)

Binarize x following the binarization encoding. If x is a vector (instead of a number per say), domain is optional.

source


# QUBOConstraints.debinarizeMethod.
julia
debinarize(x[, domain]; binarization = :one_hot)

Transform a binary vector into a number or a set of number. If domain is not given, it will compute a default value based on binarization and x.

source


# QUBOConstraints.is_validFunction.
julia
is_valid(x, encoding::Symbol = :none)

Check if x has a valid format for encoding.

For instance, if encoding == :one_hot, at most one bit of x can be set to 1.

source


# QUBOConstraints.trainMethod.
julia
train(args...)

Default train method for any AbstractOptimizer.

source


`,371),l=[n];function h(p,r,k,o,d,c){return a(),i("div",null,l)}const y=s(e,[["render",h]]);export{E as __pageData,y as default}; diff --git a/dev/assets/full_api.md.BiWge5EP.lean.js b/dev/assets/full_api.md.BiWge5EP.lean.js deleted file mode 100644 index f024fbc..0000000 --- a/dev/assets/full_api.md.BiWge5EP.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as i,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const E=JSON.parse('{"title":"Full API","description":"","frontmatter":{},"headers":[],"relativePath":"full_api.md","filePath":"full_api.md","lastUpdated":null}'),e={name:"full_api.md"},n=t("",371),l=[n];function h(p,r,k,o,d,c){return a(),i("div",null,l)}const y=s(e,[["render",h]]);export{E as __pageData,y as default}; diff --git a/dev/assets/index-old.md.BzPVACYs.js b/dev/assets/index-old.md.BzPVACYs.js deleted file mode 100644 index a0fdd39..0000000 --- a/dev/assets/index-old.md.BzPVACYs.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as t,o as e,a7 as s}from"./chunks/framework.aA95Gx5L.js";const g=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"index-old.md","filePath":"index-old.md","lastUpdated":null}'),r={name:"index-old.md"},i=s('

JuliaConstraints

JuliaConstraints is a collection of packages that help you solve constraint programming problems in Julia. Constraint programming involves modeling problems with constraints, such as "x > 5" or "x + y = 10", and finding solutions that satisfy all of the constraints. It is a part of the JuMP ecosystem that focuses on constraint programming in Julia.

The goal of packages in JuliaConstraints are two-fold: some of them provide a generic interface, others are solvers for CP models (either purely in Julia or wrapping). They make it easy to solve constraint-satisfaction problems (CSPs) and constraint-optimisation problems (COPs) in Julia using industry-standard solvers and mixed-integer solvers.

Other packages for CP in Julia include:

Operational Research vs Constraint Programming

Operational research (OR) is a problem-solving approach that uses mathematical models, statistical analysis, and optimization techniques to help organizations make better decisions. OR is concerned with understanding and optimizing complex systems, such as supply chains, transportation networks, and manufacturing processes, to improve efficiency and reduce costs.

On the other hand, constraint programming (CP) is a programming paradigm that focuses on solving problems with constraints. Constraints are conditions that must be satisfied for a solution to be valid. CP is often used to solve combinatorial problems, such as scheduling, routing, and allocation, where the search space of possible solutions is very large.

So, while both OR and CP are concerned with solving complex problems, they approach the problem-solving process from different angles. OR typically uses mathematical models and optimization techniques to analyze and optimize existing systems, while CP focuses on finding valid solutions that satisfy a set of constraints.

Constraint-based local search (CBLS) is a type of constraint programming solver that uses a heuristic search algorithm to find solutions to problems. It starts with an initial solution and tries to improve it by making small changes that satisfy the constraints. CBLS is especially useful for large and complex problems where finding an exact solution may take too much time or be impossible.

In contrast, other constraint programming solvers use a variety of algorithms and techniques to find exact solutions to problems. These solvers try to find a solution that satisfies all of the constraints in the problem. They can be useful for smaller problems where finding an exact solution is feasible, or for problems that have a clear mathematical structure.

In summary, CBLS is a type of constraint programming solver that uses a heuristic search algorithm to find good solutions, while other constraint programming solvers use various techniques to find exact solutions to problems.

',14),o=[i];function n(l,h,p,c,m,u){return e(),t("div",null,o)}const f=a(r,[["render",n]]);export{g as __pageData,f as default}; diff --git a/dev/assets/index-old.md.BzPVACYs.lean.js b/dev/assets/index-old.md.BzPVACYs.lean.js deleted file mode 100644 index 37fcb53..0000000 --- a/dev/assets/index-old.md.BzPVACYs.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as t,o as e,a7 as s}from"./chunks/framework.aA95Gx5L.js";const g=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"index-old.md","filePath":"index-old.md","lastUpdated":null}'),r={name:"index-old.md"},i=s("",14),o=[i];function n(l,h,p,c,m,u){return e(),t("div",null,o)}const f=a(r,[["render",n]]);export{g as __pageData,f as default}; diff --git a/dev/assets/index.md.BcgCFTkL.js b/dev/assets/index.md.BcgCFTkL.js deleted file mode 100644 index d854058..0000000 --- a/dev/assets/index.md.BcgCFTkL.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as t,c as e,o,a7 as i}from"./chunks/framework.aA95Gx5L.js";const d=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"Julia Constraints","text":"Model Smoothly Decide Wisely","tagline":"A Toolkit for Constraint Programming","image":{"src":"/logo.png","alt":"JuliaConstraints"},"actions":[{"theme":"brand","text":"Constraint Programming ?!","link":"/cp/intro"},{"theme":"alt","text":"View on Github","link":"https://github.com/JuliaConstraints/JuliaConstraints.github.io"}]},"features":[{"icon":"\\"JuMP.jl\\"/","title":"JuMP.jl","details":"Model optimization problems via JuMP.jl!","link":"https://jump.dev/"},{"icon":"\\"ToQUBO.jl\\"/","title":"ToQUBO.jl","details":"Convert and send optimization models to QUBO solvers!","link":"https://github.com/psrenergy/ToQUBO.jl"},{"icon":"\\"Pluto.jl\\"/","title":"Pluto.jl","details":"Simple, reactive programming environment via Julia notebooks","link":"https://plutojl.org/"}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":null}'),a={name:"index.md"},n=i("

<p style="margin-bottom:2cm"></p>

<div class="vp-doc" style="width:80%; margin:auto">

<h1>What is Julia Constraints? (chatGPTed atm)</h1>

<p>The Julia Constraints organization is dedicated to advancing Constraint Programming within the Julia ecosystem, serving as a hub for resources that facilitate the creation, understanding, and solution of constraint programming problems. Our goal is to make Constraint Programming accessible and efficient for users at all levels of expertise, by providing a comprehensive suite of tools that integrate seamlessly with JuMP.jl, a popular Julia package for mathematical optimization.</p>

<h2>Our offerings include:</h2>

<h3>Core Packages:</h3> <p>A foundation of common packages (ConstraintCommons, ConstraintDomains, Constraints, ConstraintModels) that supply essential features for constraint programming, ensuring users have the basic tools necessary for their projects.</p>

<h3>Learning and Translation Tools:</h3> <p>Advanced packages like CompositionalNetworks, QUBOConstraints, and ConstraintsTranslator bridge the gap between ease of modeling and computational efficiency. These tools learn from constraints and convert natural language problems into constraint programming solutions, requiring minimal input from the user beyond the model itself.</p>

<h3>Solvers:</h3> <p>We provide a range of solvers, from native Julia solvers (LocalSearchSolvers) to interfaces with JuMP for external CP solvers, catering to various problem-solving needs.</p>

<h3>MetaStrategist (Emerging Technology):</h3> <p>In its formative stages, MetaStrategist embodies our pioneering spirit. As a burgeoning meta-solving package, it aims to harness the strengths of CP and JuMP. Its vision is to formulate tailored strategies that consider the unique hardware and software resources at hand, offering a new horizon in problem-solving efficiency and adaptability.</p>

<h3>Performance Checker (Community Resource):</h3> <p>PerfChecker.jl transcends its role within Julia Constraints, offering its capabilities to the broader Julia package ecosystem. This indispensable tool for cross-version performance checking not only safeguards the high efficiency and reliability of our packages but also serves the wider community. By facilitating clear and simple performance evaluations, PerfChecker.jl enhances both development and maintenance, contributing to the overall health and progress of Julia's growing library of resources.</p>

<p>At Julia Constraints, our mission is to democratize Constraint Programming by providing robust, user-friendly tools that simplify the modeling process, enhance efficiency, and empower users to solve complex problems with ease.</p>

</div>

",12),s=[n];function r(l,g,p,c,m,h){return o(),e("div",null,s)}const f=t(a,[["render",r]]);export{d as __pageData,f as default}; diff --git a/dev/assets/index.md.BcgCFTkL.lean.js b/dev/assets/index.md.BcgCFTkL.lean.js deleted file mode 100644 index b64f3ad..0000000 --- a/dev/assets/index.md.BcgCFTkL.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as t,c as e,o,a7 as i}from"./chunks/framework.aA95Gx5L.js";const d=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"Julia Constraints","text":"Model Smoothly Decide Wisely","tagline":"A Toolkit for Constraint Programming","image":{"src":"/logo.png","alt":"JuliaConstraints"},"actions":[{"theme":"brand","text":"Constraint Programming ?!","link":"/cp/intro"},{"theme":"alt","text":"View on Github","link":"https://github.com/JuliaConstraints/JuliaConstraints.github.io"}]},"features":[{"icon":"\\"JuMP.jl\\"/","title":"JuMP.jl","details":"Model optimization problems via JuMP.jl!","link":"https://jump.dev/"},{"icon":"\\"ToQUBO.jl\\"/","title":"ToQUBO.jl","details":"Convert and send optimization models to QUBO solvers!","link":"https://github.com/psrenergy/ToQUBO.jl"},{"icon":"\\"Pluto.jl\\"/","title":"Pluto.jl","details":"Simple, reactive programming environment via Julia notebooks","link":"https://plutojl.org/"}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":null}'),a={name:"index.md"},n=i("",12),s=[n];function r(l,g,p,c,m,h){return o(),e("div",null,s)}const f=t(a,[["render",r]]);export{d as __pageData,f as default}; diff --git a/dev/assets/inter-italic-cyrillic-ext.5XJwZIOp.woff2 b/dev/assets/inter-italic-cyrillic-ext.5XJwZIOp.woff2 deleted file mode 100644 index 2a687296748f6b8bc8076cd11bde49cd27e4442b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28332 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 HNCp4^t1hY; diff --git a/dev/assets/inter-italic-cyrillic.D6csxwjC.woff2 b/dev/assets/inter-italic-cyrillic.D6csxwjC.woff2 deleted file mode 100644 index f64035158d7e4c01654e3f23dcd6e8299928a28c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17824 zcmV(|K+(TGZYzoV0yihRy3;{L*Bm;yv3xXa1 z1Rw>42nQe=C3zL>7I?PUshK)MG!ta^L3b^d$O{#w!;WOi#caU z9epdi^~z}FXC1zMc;nw||B-~iJKZ7-`H(Kn3lKjZ5N5RqaHof~Lr#JsXW1jml58&> zQGi~|0cnL4zB|P8}0t5&U@c|JdMvNGlmzMw!d_sgsBSwh~ z<3uKERMdzOA;C{wc9u@*KWk~1ZrQFoOIvrA?XoRxnU;2`Lr2EaDbuDiOouv|*;F%- z#gKPJ>8fl=HUf*mFq&P*op#SRB5uMwrI5O=D|BV|t7*jYszMn6_y=vT5wbG)8zDBN(kmfH1b)al)=7_XtiK52#|ESncdAW0QK2HvRY`_;WiO>pz_-Xk zH!T)&YR`MAJa7J@pNA;Ve=XlUuY2Z4Y1bh`Bcza^p&9I}QLUiMj74g|4NyqjXq$hi zG1}j&v`P|}Bqr@5l@eV;qy>fq`v}SgHrfA#@*v!mV~$a+B6D&Jh-sRueXL+`%jr?vt30*Vq&Bs(79VL�!Z1%E;0yxE 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 diff --git a/dev/assets/inter-italic-latin-ext.BGcWXLrn.woff2 b/dev/assets/inter-italic-latin-ext.BGcWXLrn.woff2 deleted file mode 100644 index 9c1b9440ed419d4a71ba46b0db3951164f9e10df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63552 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 diff --git a/dev/assets/inter-italic-latin.DbsTr1gm.woff2 b/dev/assets/inter-italic-latin.DbsTr1gm.woff2 deleted file mode 100644 index 01fcf20724f915f68a974ef2fb85f86f3039b1d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46048 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 diff --git a/dev/assets/inter-italic-vietnamese.DHNAd7Wr.woff2 b/dev/assets/inter-italic-vietnamese.DHNAd7Wr.woff2 deleted file mode 100644 index e4f788ee02bb687bc1d5045483ff0d381e7654e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8784 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 G0002QVTgqQ diff --git a/dev/assets/inter-roman-cyrillic-ext.DxP3Awbn.woff2 b/dev/assets/inter-roman-cyrillic-ext.DxP3Awbn.woff2 deleted file mode 100644 index 28593ccb8a4d849a746f2b970678fe426cb136e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26600 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 diff --git a/dev/assets/inter-roman-cyrillic.CMhn1ESj.woff2 b/dev/assets/inter-roman-cyrillic.CMhn1ESj.woff2 deleted file mode 100644 index a20adc161f433a7c4e3d92306301b9228bcf9fb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16780 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

KZ;k8ywA} z5k-SpDU(i8*gg^cv8>58r3@ub4OcK9&& znNhG_@GxqjVK3B&J%{D^HbH;deaX7Mp9Z32&^3D3f90mP=tF!fe9&>s;W0m~7?~A3 zux4`Z+_2B&&IRlyCT>ODZ`DXBg;?l>VcO7-v}Qn30>_G#L1tGZ60ycSW|dPuxCY~C z?DBUN4%cm!9{5w@zZ1rtvV6t&#meNl)pp}^FESGHmRz)CQKWID{e* zKl&Jl=Nczd7`2WWH@A)KYebMQNnqpHcr{eH5E61_)_fc#_p$9HX1N4TnjTJg-%wWH zoq3G1+6~rHwRoT!c1E-&qYs_3xi#$fI(6%GlvNp~MUmFlAu`Q+Aa;zrmahphCCG}z z0y;PaNCP>ruFkBkB;~qvNr}(}C+wTEUKCkk+*V_on5fG3DN%xiKzSk#3FGD1ut~Lt z^w~RQ$7Jwk)6g@$ICnR$+9l9SPld{*PkotiKI(+q(R~t;(U^h;-`ly|GZwjNukIR3 zZZy16I<`IW={p?5Hpoa7@rR}ZL~6p8EN_CWl6QP)wre$ha9MQ@W$csCm3+r!rzVG zx!T-w3Y0SrGE^(c^j=TXYZ)WoQ$z68k4d}y*m)BwN`KQ+4lR)8mFnO_%}^BGtC#DqKj zsiy#o)h5GqQwNXI^!m$bKqyP4dq^G;Stj9AG=8NZ;#|?4Tyy-|5bOl!Q)paeVE>yJ zuixF^`PGr0)8kVsCQkBj&{;$w2JFcfKBqLLz{vs59pkEXIBMN>!gZuKW`^>ZM5d!Z zdtW`z?~$Vc&(G7&wYjulSCXV=0YkS3u?AB8{)D=lld)i{-6PoSA09a9! zBKcMT7hg+|U}vzwa3?iA9NwU8YOxVlCk_EUe9%nIY1jhY6h-u&sQ zo~O3G8DUww5+pR$DZi4{K;GtL2NFf*uT7L}E3w=)T^1||9ej$q)%lDowBv7+?!~e_6 zcszLNdUHpKLJ3`bQG#^v^-~e2b!6fIi88l~FM9Lm6MHiTpLhCg92#G4-riia;MU$E zJu;x$YiIqmr)3SK38&$5IvWV2QiYy+r>tk?4QH!#k0}%H{}!~+`zY4HQ^z+>pj}d`krItpcjKIlWE>kp1b;D;pG(3ut>NJ1P>G>z#yH|x3;marSq~R zL;vRLF6aEH6Yn@{7TcvY7MpzJ-Io7Gux(NgfmvRle{GAcfM{0#20Dza>wY68gnB_y zkAgJ@M*v4GqN>XI4X)`m2=nD26)6BZiV(G@Ty$u}XRUVqTO3f; zl$&n1Z!3uto*%&!O~d~BSd8#e99SaHL-anSvoo>S@%fTGiR>b&6=bY_H6g4D_D(vTPN@jVlle&rLPv#80IFF* z6(&zPi4Ef`is03;Yl)>-TdbQu6{fX&xTKk{8((IxfidA)eHGUfHqattu}56Nj_t6&cOl)314;z(c99T~X^aD*%S* zT}i8&MW3qMgsm3k?@ylWz0=(o(r$nJHfzmqsBl=3E5FC z4}slCp-}ONBuqFbDJWZViA5Txy)XdJRI&3dZ^zI>%gR7!H{Ch#B|kKv1tW9IuOwfs za6?s=(L0Xzb!rQD!p#nX%lhLF!L)JY#CacD>5el$(S+Xh`_FjM8;{o%bTGXUAm?5J zp=8Oi>8P}3JtGAmtvOl#z7l{p#t{Vx!xCo=l~F=4&;)3r8iG@tBMd3+UAJpZQu%)g zArhsZ?&Q7|@WO#@wtt6>Y($LbGLGyvsHZ}`p>N4UqMH`F=tsCcmF5N|dR?DOePv{0 z`KYo(KCHjecqmmacJ0HU#`YWH{!v#xm%m* zFprO$_g|ZOr9KygX5Y?g$38Rr<;qK5O=6C-sIRVM-)RGSZONPRxml-iza!0QdpnTT zfM2X|3^FW`B2osEqRjcbQQCbzsWgdfpBD;g?$j1%Qo-e+orc`*Tj|W>Z*$k4d%T8Q zANqsEqL7)n4akzOv3qZ}ByFgsF|M@rKIf6Rg<2J(s)a@}+)k~ z+GLuI@rxP^LZx9umelc-Y?2q%{VJKCjkJP9M*PYb*gb(ZE0)QY7nPNA6s$4Q(GlPm zb%F-gFA3j(?}y-6HqwtT=0EIJ`2P0ZZLOW*cf^z#wpkY8hof$rK6igIs<<>eJ28?9 z-qO?9TZ@D}ATEX9#CmGYa7QRRJj1KW+!n9e8x_oiVdA+A%NDU}PPz5l+NLp%C`w0O zDvko#g-WKTBGbFwlg;I=drj1A41O;T@_=MnRML{GJHkn)Yr~}8-b;RT!(;QQ@QYkje2^bGk(Z{@u;X*SZSw6el@?CiO*z^T?N$*%{NIT z;UEinEsSGJOHMS9!>o^q%zL;qN@UB>YDmoQc*S8YQa zH`RVqR?x;E{-aRFmT2FiD?l0Wa>Des;w^AS)B;vBne6ug3N(qCu@!P2Xx|<2{ zUM#$xs*~qq7D3YW984#)(xQsV-wz&dkfb#npZXC|F!(&LySwe!``5&*_V54lR-Uk^ zZT-!MY_=$0J~jH`ArVf=TbRX69;!W(qZ5m95OYM#r)1uQ$9v8>eHk4No~1i|B5T4kL+W zv13|^R1ldoZGyFDfEvmz;Lh67dh zv-2Q;pa~9>tmyBok@aBWN4~2w`s~JM#;~;(8D#8j5PceKenmq>5?AsmT~^$Kv!5{36@B5>{_4lhVOmfC!f0 zHj*Pw29#JKbWF?v)I7{>xR902Ec%Latk!WInzIminxD);6Ob8@$OcDSC4;R(8-EIB z4RuI1z?7UKaYg+d5yKT+Er!pHND@NMNv=?YOAG!n`K@mg%XTn&`WixU#GqEKNlqPVPm1mtwo+zK@V zl)!WOhtx8RU-u&a!<`ad>{`3Z)*CivaJhQpKro@r#7Z_J%{d4=%t9<6n#1~B{b3n| zdV!&TI&CCmWfK~pSvQTR1B4=EH+OeMnES32!GCeJ%Gs~~oVtoZwb%o4-8sPv1QK}z z{AY^xOoE;BbHi8NjArzmxc{?dPcH(Piz#ARY;qViqR#Khd=Q}3nE`osNC3t7kz zj^#df!|oK!8e}*jZR(1_-3D7exio%B7NgSApN9W-eCcnyRHWvkNm#V^jTfR-*@$W& z+ei<-6Gqz*5w4&mCaIJbGq-zn6pEv%dvo67jcbvnJntZOkC9#BGmB8|IAXI6E|q$3 z+rWA*zZMX3;#308!i7C(_IleiulGTc%GOg;!%^xNze*KVl}ujh{_)pS#MR9zU9ei` zM2Oq2Af2;;7KdZIP>^cm?l&vpWxt3^(m5vy+(0vg^D4?VZ9~mAdCC<(HDoYLmzQLE zpEoOrPYT@KW2K)yVE%HxWb#&RuI)0f_xS+0>RETjKV01vwwMsB{ z&iv&IFI)Igd;Uc~29O~wn0;byhT(3e6qe$75`i;tS@O_}I!`d;!aFU0?}fo655vvH zu`jwkPLD0#`~JbKvJV#*dK@UBDZA%k+BM(5MjjvOWcvDo!9OD~>NCme_7$S~R@8S) z_k$)B8tKWkj*TykBG2eM9kJ-Ry{u+EZ8w*uHv9VHSSOs zK~9X{a{WUAsw;VKgKN*m?=cCoYP=6aa8}{)bWjur+x+Q7@WiAg>|XL|NwP~st>E@R z$|TlpYx?V~5cw+Tv+UJ`A91^fy(@4{_Ds?$XEGRcW;16-D>%Xe9SGKJN@8>~TfXhV z;+qp^wX7oXzqULse6t*Ml_8pXrn>7)GWoNs-^nx8x#_k$IgE$jr?M{rl}90+e!Y>6 zrj~tID_WI_6(nle5QztkplzgYRsH*zgihBs2#sbTYP>}l8gJ7TrgY+NCGQa9tjJh6 zX4K8|?%91X*ahz6jH}?f5PC* z70GZe#Jm#m#emauwCJ@3pHaxB^2Wxum|u-NYgW@zLnON*bzV;~)b~_V(Z+aag@egv zcpmN2_)zI|3Z1HS z7c(%Ww&mxHie+d{D-v1iQKHPsiTt&S0LP5?>nS&{<woNkCT~l)8Zv+lb zfB*#kGH^)+uN*`(ByF4|gv9QmgDBl$_UmZ^$q*v)9jbsiZnr#n=uf7K;nhnfZYh(` zwOSXZA7p6pU|P0T73E#=wO_%BFocO)TWvr@z#(lKC4?d~O8ukO38cx|aL+ z5YY_MP>*s!*^o4#en?VhW9}b+65N=o+z@AFH-)UENjn~AmjO#`=K1tMsvU#Omc6uf%G}Ks zSMpGQ4_z@blevfN1NEH<@1!k2reiTl3Lth`*}36rOF`92_pi4;x)r>Ant(7;+qS3# z;t-ao6r($~NucV}px&{}K%hPg4R>v=sL5A_OqYdhCnEzTdOuu49V$D(LT70&SOiy> zG%kUw=ODa9*NsaEuT3L{eq;tdo3cPm+FhL^WtssSAIY7a2v4nv7U@DqdanRcmZ7Er zWC5H0ZFF%v)WRDQO0-K*sx_mb)S;oJYRJR~;qI~I??v>Hd3dK30u&PaTsIj-=2+*1 zi_~kd0iUc?n**xP!tdH*)Rz<#s|1LppO)A(NHiykMA0n7f%S9sdB}*K<9|_Gkax3O zm^{CoZ+g45?L502drX3P@s$kV2Yy8EQ|1AYtjgY0i8o{rRtq33DRmR*5Oz}-aKg=C zm&jRVfi*tBInDl`i|gOt1}@+Eczrh=7(mTOD_53k@vWVy%7E z7M$Jj5)lC-AtH=nibx0}AOuFhNHA*Ry?^}3y@pc>JU>E`S@`eEeb$W#DWxwH;I6x8 zRAhSy&K>}lnf}$l14LB$4v4wkvxhyvws*sc6DKK6OlFj*Q&AcF85$ZYD%w(1R8&-) zm`h0+%()gBPRgZZOV`{Cm2xR56&WfmGFodbqog^N3Jnz%H{^+McfTZ{G|o#R5?|xi`GS-yUNeCYZql_zi;k+yUEO!rscdM#n{GH zMONwCymLS7e!{}>HEKQ(JM&e{nI)G%8FA|2>;C8e%bd>*A|2xRV^f>|ifN3uA!5v- zl#cz4Ffz!s%w2~<9{&C3L*N(z;Thv0Ody3IGYi7YUWPD-3c?~45SB4OsPqQPOpKF=PVxM=-@$r?2I2K_ECUChmCkZT708}K#zcor}O`hBR%i{4q#+%$yt-vbW!Km z`t^RpWzAJpNEuRxDmoS2CNaNFd|UBt&G#i?;>XgThK<<3jbwq#mKV{O4*T`o_%@z$R#mF||L#w?h=hxpT} zK0>@CgGMQ^No`6}OS`m&k~#y@KwJjnkVZqv?exh+n775jCJrb8r~t!185M&4IVfmc0iK zyj?#FXR=tnwsf6h-pcn%&pwh_s)e9)hOu=s4)oGyUK_@q*=k+m!Z{x%XGJX!8V+u< zy{oNVwZ`D6GuCK#*W@*;^_|TIgMOF29?))_*`Wg6!E^}VYsIGcF1|A7Py?W#qqzL7 zzx$lC0DK)r{NdG06%4QTR={2aKmr3`Hx>v87zn_6bb#$BPkf-xh~xmUR-xxiBs14i zYg9r2u+?b6-@Y{j`qrATZ=Kou)?1=)gRA>Cy0>pr@VuL&rWhO`sO${7-!{}y08ZjT z$==nCST$mU)YhA0u_a#hnm6rrT06gA{NaCzT~)#^BkG9NLK#O++4RO(&a95xS(kPD z)BRoll&-A*ox|S?{G@q3eTg1)AN=^Orw=TretelZo?^fMep~=#z~@CnL0ABG5@3&! zM&Wx_k{{@r<~^YnF%JEq{L)XOeLZ8gP^^=gFby`kig_Ty(T5XLT`s{bp zVYhtlwhB>x|MtY+*ipxfB~)yj=ZU=FMO}W??KeGscg-Jk z)>&@@y^S{6tj=2)Fkz8JzW>DBao7KveWJy2tqP4W#&gDtyD#C4c3*hptaGNBZU(8x zo)~b+Wmi1)rSk&5H_vzc4=bbwN^4Qw`P8~5;jv`LNKW1H;+!O|thmjiHT&>RQS3xE}m z0Mgf4cDtrDrw54lj;&R0BxZ@rNm(KH+X4%4VxMj7vUd3=Q_%3x?nV?$82s0x(;)TTZ(KfE_K^Ka&kf z&5B2W$fPXPLbJ3udqgc>**q@BNj$tAt-c*iPN=hsQ73Tl&b@LM_g)*qs~B}@md(HF z=UP}SI}|7vNypzR)zF^n;XOi}pUwE{HI6rR&$bHv#rJf-+bjq=2N%WW1Rs5Gnukc(BvbI?gQTaf?ZRm0irtPNOd0f_O5%w9A6u<{@rf zz&1f&&7EU{YZzl ztR?W>U`l{3w){G6*ZH3U1^PS&u)a^xqM2TtSLWn|IdIAEfA)7V_TdXW?$k2}elk>9 zFKsW~uwdEb{i}2he;t@tVEevR)s8ij6vMBS4lgdAPK@6^V%3|@HP6o~EF1Gu;n-ps zVHIlTF8FN0)a_-B&u%N%LJ|zRz8`LPhMk^R_}^X0ClmIcp{ElL7_k*FKyBE$2*huG zJ4n*fK@!V}`TYOO819Y23+KkN(5*g~nO>pRK1_zt}z8nq+NQb@~(2 zb=g~=b2c?y*)wh2o*i3z<(3(t(>-OCdO`KHeFwhBHk>|9TX*DgZhexo_QLMNN4~1r zplRNE+ymS)r!xjL==(E!g7J@ir=0)nss=waJO(sqfA0^U7~Ct?T!1VZ#1{32sWS>^ zX5EbRtjLwWbN;ix;K~(1RZ@uo2G&3yvZ?71go)k5se@2lPW6iT!I!%fT=R?&vpS>KgWllpmBoKLKRTKC zrdmga)@@&GcCj{mx^8=jtbWja;mMEwbXFGsKHhcLKa5(m`}QcFw(lHuQ;PucX$ZVJ z0OJD?e(CieeP8|c7+>h=TF2=c6t*NfsD+&oE z%L{YH(``40%CD=O{LbcW^Tw8U5c?&~xy%nvU96tGxagG^R7Ddf&sEPjljA&fuDX0l zQTYpViY8BhWB$Ub=x9+>Wfo~;%2EtOXvV-cO*!z}&=Gtxv5*Whp8Y)I9o8TQK#N&z5H~F2M#5b5v&C zz@*gaNyl%@o4Z)Ducszt>|>6K4~5#yeV$rT|86Vp%eiEK!O{`lYb9Gs8aX_9o(w`<+CTN^x6BXd?2L? zL<7AhrGWPDPe=&TgPsh*7at<#W{zgAlZPOeuRNd7055y$SH(bI2na_*Ov`uu#mQQ! zTtui%FcP*3?ma*8S&n2R7ku==br+?|`ky^wkqSWqVwa2~o_U;w21v~)(TW$51f*&- z`EAjTKKQ*jtpES!{+Wk&JT0M^D#eQkA_TL(n2}WBxzPxD;*0y57n-<$4<`>F@M0w= z@L~xs@IpN|@Zr|U59C%q&~1??J(bw%LWA0~M$#j3xK%=BIa!A+ChG94mgH3I4g#oW zn;a)`5?D>C80xUmvuJ?ZVr#!&N@I0)Lqa9%&n6>ms?>d`Y!@V1vnVZYdD+*Vc^DV z4+?dGLXf~Dm8?SjmJ5R0M`Gh8~t zHuiP#AAc_VuSc%gV?meOb{D# zOm*Q5YT{_X#ChNGpyHo{#5TKk>!cva;z1&UTppw&$ml>)56@dBFQH4t7aIznuehGt z!fi@vn~_0nvl`SktBu-b5^I~)q_&x~+Gdh!o000=Ho%PpiEXY{r)!AT=kMy{|Id43 zrs>HSAi;QHud@}$xdxBXq00hFw4V^TkmwTP+X2I^*MJDXQS=VN^MBXsG)=TVe^~N3UK9EfR zJ|fy6!At8^yVK-uJ=Qnh8W{Lyn-h8cM`WpP)&;%$V+slYTmm`)R&=I6?Z-&bMj+Wz z&lH_#@-7$v8AA?rNiBn#{Lr4wWiH#P4^TdIigkcke%Qc$1nV>+AL z1ia?oJ*USU5Qw0UfrJiT#=@{ehGq<(dr2>(L=bb3t)V^)NP`+2&}|aZb)W=XH(VGwbZTD-PCuehpD%zk7y%l zFVYCwBH9|->$Do0gZ4=#BXelx=*$V3<(aBXZDwWW07l1#U`5z3ST7dGNcu|p2zoJH zLRZk2($~}9px4nG=_lyt7%wtP8Lu#2V{BxY7&gWsMl0hi<1*t{Mjzu5lg8vQM>8if z38sp(q?VVs>yO> zHD`IUzRwD0#j*ynv$Kb17iUYd71{4(f0%tT`>X6=b~yXL?13C+&aj-ZIg@i{8@Z42Sa}6`#d*{6lzG~`gLxP7zR&wD?^fO;HpHk3*&BG6X%_e*7x$-*F&x?DX&f<$z686IUFO@Sm`7p)ml z0}8FQVj@V;OdvI7_0==Ng&T&Il7xt9c3=S=5TFB)En#U}HsKY=kvbSWA}(|Up_G!Q z+5n*$nn_6ZyD?jIWB0rZ5oonAXH5$4_KOmQT`rD{l%#aU(5ldl__(E-g*RDR_qf7n z7?z7+gjkZ>g%uH48~h%vF@-`s(P)p$^=YfWJ#gCXZj%eN6mFrXAoBHIAP#0lYCPzs z0pO>Vk{a(pza~BX714jMJ5nqTha-`{ z{!6o18F8+CnVaD#&FX7D+?rueA14sHm%wqBC%1ri?~O?HoxhGEP_mw$NLh&ySrOUD zB{@u&mI0}g8%0xD_|}GEP{t$%!;JeA#qMje8={z81B?_)q~bJ&5zBK0EQ#?t_(zi2 z21LuF*927S=85bl25#O1EQE6stf{;b{oSB=n>8{(9^&lkXb5FFk0$p#`TbA+c+YT+ zahh8(lGXz9>q0-ZKN;YR;KNIAc9@cTzOnAS8;MdVg}mzV9Sk|%~#9* z6vJ?T`1(jBgR52L31s6+VxkYD6l%;vKY}CI)J^G*+Y@M1XW!$st{wwmN=)?Z32%-i zgU4l|PU3+kpEzngIv6b0J?K2=~} z-wk|lGZ+fC&`Ftra1=sc6jA|HOeIDjrX`XGeie2!KTi##!^`;6hl?3 zV$OnL6(J-+K-D%Tv}`;fKe);@VNz*9O5<^yN@6-Ow0-u}8b4LwYk&q=+FAT^$2CpN zUkYXt<|OfRJ#g^oxvNzt5INT|ttmN=gG)*%3jQgjAWRD(VNMjzch)unC`7l0p(IW> zDq%nkJdC02Y)JHH?*T5*FF%V1(Aw>nEk%G@`ip$ETM-w^&{$Zt<%ME_2 zrI{#Z;8rQ43P~tJNttq!HU8lhWzrL|h}y-9T#V3BIyw%ne}o-kn0#F5>AMDs5xhK) z1hTMu6epKF42GwmN<`)6g?&OeOHHrPca*lZb2C=c=*p<$>WE>eW(mtanfdEA>4YFOzOe*UZ1rTTmEvr zR8;t&%P-=CLXlK21Dm9hh8;xrA|PZu6hbI8BCzMKMn+Sz-MwdN9>gJcl_eu57f#J< znou;E=BHr(JbXtg)A#RU{xsmhSP-5Z!czlF&l3m7bvQ7n^B*9M62@%s)F;2ZDkbii*i7-r)=Cmu9$Bs+&rkl-q zlxg)R(Wa(9-<*iml72g3e=_beU70slG-M|-EI5k>i;c~8$J?%yfh}vE zDxMd!*}=C6DJ01TE9~u1DZVq#ASu>(^84H0nbX#NK9S_i4eM#&KlkD&FJE;rj(sIi z3r%tmo`s@PHjkvjeQy2%k*wfOXR~3*Dk&BURZB5fEvG~;SP9svQ^Z6FpM{h}0;I-y zK{1&el_;0dy~k0$Qe$3E`c@4Njwc+e&ypamoIF@kNUJ8tQ6k>^$P}0z{`%cPKRkR4#4G5L$6-*p``~=1P%ZUDY;)H*)KtrFnAaXOXWTV3VUQ?P#uAXc^)@3FmK-!EstS9$WIm z$8+%JJYo^?dP_+|O7{-0n*4?dq-*7{2M4@fBFJ%)z_7?$GE&hXYX24J2nZUQHHRyW zK`sYnF_%GKcCO#YMlnCjf@TgDh&PtO_m`b>ks%xeg)f{)c?ois0C}_An<8erFJUOc zsp;2(Y#u~EO(XzuTnt|WoWn?e&!%csyWtpBgT z*(3J4y1g=TVU4Hbth%~zIK`h-GI_+Ez)^zSq9symu{QX7?d_%HL{0SCmKJHcgW1y3 z^7mb#dfBpNaJKdHbIzk=l9E(wF<(gWC-cQgD>EK%ZVtq)8BI{P!w04QvRz6dZWA~xTp4kY{_aj_ZnV$h%(;#E8kNdQCJ*~2v^ zuHF|X!3ZDD9wPRENgVqIQ9oRLK2}PL3NuDShtclZ42`mIAD{XnaCQ~GRf*vQyV_z` zZH8K2xQ=`?=D_+G95iw6CJaF_oDX3q(U-e2Io?2}V~as^o&Yc)Ygs+ZVoyJzK ztbNdwvh-k@IP6q5GMgh9IfAE4TR4m}-Bf{NeoZOZFt-&Gxt!<`+3NlO9=^e`I(f562tVFbPU_n&7DeM} zzFZ0+LS8{ftog}DksvSTUw5M4{t?7Xy7oYz>z=S;S23|w)6R%+UTDKV!}gn})=@CntBn#wXJp9Oc7T64LcCfo@q zt2&F1@@YT}8R5yD;=?Eu#JvdT66dNDiuur6sv$8o9KmeCHc`lKaYhTGUZdRdMwF}R zggW@(4XBKkmdl=ZWC_=D7{iWVYqyq? zn^f66S9t&0DH*v#ReHT?yW9fZ1uH0+ZKoF_J;!CFu4vi*fTC0?#gaolj1CeC3UKyA zY5g=ln`%MngK%6c0|#c?<-)|*D6m4}B2N4QYB|gmek91%W~~tMI%Uwz=X^L+y{4V^ z@RI*hEH7UQ&LQy(@7}k*Z|_gnRm$KPK3t9S97#N>9InyBHBO?%nZZ;rp!U<>9wpu? zgC?|Y=O>f@{hP4lq@JQhq7fL5v!y;oa2&Is1NWlQFJ)u}W?M%ORf5&5y@3A&bfd;7 zCf{`EuG*|8IvnI6EOd%=f4Neq!&D-d)cw2yU_xfv{cc&Nab<_RyC-RaNie4c$7U-j zaX9MgjyW0}DnDCjz9!l8;UhLe1@u$z)*~(cB)g;C)~J) zUwK5FBqTyMLG`PIB{!CWk2v?mEBL3BVDMiH<-aIe4Ndb}CboLnRO%CedBR8T@i3U4 z&$!akGv2N(nAtn#8p(p9oLF@v(mf zVDo~|>ta?g>VgnEw>-fVhkQfC($By-ewfnr5iwv&IS$dl@Gan0m;M(s>}Yt{^^ho^ z$XR0+5exZDV4)}_xJ2kScfNYD&jgswdeRsvN2oA873~Jfadl2}X|9_gVGoBv*%1sV zfobWGI#jqIgY??HZLO6d)t~(EL+J=o8B4iP>{6Z7C;QKn!eR*vk?f5!C4L9vAUKi> z*GU>39vC11-{Ux~LEMjn)X)!$XyrS6>R$UCSK`q7t56i3sItBk1a4{!Lex<4i3T7f zBP1{?O7bSkb&b|cDYWy-%09{B4ajI#v5Z&bqAV0=Q8;2HYa%3|gFPl+L&+QW|M~gL6KDDD zZ(UuNLP?AL>~GOtR@pLZt9O#;@MF!z2R> zd#PF3+11slo4ups20C<72{5XwDeIAAZ zvZ{raOu=6Fu||iE(b&XsH0G#kyo6vYM z-I@MBok~AUC(;kdsag~7`ZQBc62*L_*2$FKJ?28`v1{{5w&()H_N9dqsZ15pp`*sG z0m;=&txSzydOYs0Kw4eZ)##Mj&lUVAd$i|@q;nCQO~hkb&`dfE%Bx261_3?OLSyno zx#`Hc1{bGw+%9--_7rO+oVR_*r^sofDL<+L$%bwkJ5Ae4jTA$Q8+^uo9K63b8W$c! zK1bS-b1+wrb6kkix9T+a$+sX=5FD=3dafUEBugps>S~me)lbvOVtJ?SDk;q`uJ6)| zEa>g--hXJ-DD9u#?%NiMNWV+J+e&toHT=;z+`L5V&*E5n&;ZG)t{_rFk&6Qpa`jYK z6}uGC9pS+&EmuK|JnFe|L_w5x?cGjDmSM++D0oC24T^)0dA5&14^UqMz>-+(33G>& zH&51{18~=B6pGxf0UG%oswM0>LE076$})XjmGkJt)C>%gSIc_M(j} z1zRy^N`zuY5DFzVj2eW@&5jT4J3uPV<8K`Kxfh6i=|LK2rV5^Fpx4Bi4~Onm?mqy= z^i=M68t1x?isXDM-GX`Y5fk0q@S6)@4yx~;)FP)t?)43KR?{@!uB6rX%BR654 z%~+;rH2REW@ncVo`^6G|6vL)hY?px>CvLV^Ovg&f!D;Q68`nmqR=cqj%$S!6mPM0h zsnxSeUTc$mK2CBFAmhJ!1HZ&}&w>#N79;NgxgS5JxFB6%}pdx*ZD& zcm-x%`XRl|hrSGkI)D19^WxX-_fvh{fBw}S?D)Osk-)irkF7ht&5!m_dFBM+SAXrk>c9ANsEkyt^4{!fu15R#-h*owUj;$}YE)a>tJW@6FEbc894@zD^c1;# zhEUC|&v5wh`&ok&8>#z4WO7uC!2~Eym)BqlkX%VlRx6CbC?n^uThY{93^71jyQ_0L zH`ZP>Fe$>iawTFb-Q#)li(mZa#l@WGw0l&3Eu{BaD^f`c1y7|cL<%jERYXAVS6D!7 z30)=qDIm7QC#x!>PzZANkEfEUIUk@v)mcM^-|uz3{{2sW@=Z70_)>d8ovOUy-ELSV zFhLqUDVcjeubs2^QQM)fYlaXPuRBU}^H^IB-tD;(u``w+XQ4G3HGD-mK}aOi#)u8O z5&DC#e=bs;5lN3CoUkf$K`$on(RwkjSEi`k~L$-s;q`!bVM zw?d;)tCy53VOu;&U=F)0jvAKVk3=XcDI&uIpL-zAPLotxp`X+u zV=0)iZjq*pktnr>zEmnfXO}?u?T9jHAz)#V_4k)){pveZwZjs+*`GK}Rl1wmR-w>o zbY+`;k&SmvapXi<%Z`@{ch~iyE%j;~Fr(gr-7t7PAP7RCtc}x=)p?bXOXaB1`fpsv zu&^RcK}SFmx8yilJKKL;&W6? z$F|t^Tf2ghIunbx<|go4z8E-`S&6BVO%I}EAQs}mUJScFkMo^$eX4sMp<1K$_3PSS zkIYlXiBnbX!FvHPd`tZD7yfB7^*ym(Pd{XilmGmPLGcz0>;3 z#5g!=sfod$)2&;+M5Ej~B6P#G0s|n>KMy}~|9tr>$wO=y69D-BUoULeM@5H-CDv`v_uK^}!< zV^Erk$<#;?0T(IM)`aSU9wmD+O-+ogoroIKKx>~Q;}bP#m+|&P20IxTgh>UJiLuSz z1?H53WUq#rP6_fp35ucF1}!TA`C#nol=tgN2`DC9&?h_CGs9K=1gQG}8JGw_GQ`cS z0~k@WI_ZK4A}W%Zoqy?$1$Olew5fl|WPqM5=rIU^57|}HVb+}i2frBscp(9;U;rJc z2Xsjefu(Yf`oBmAf=wKnm9UTb!<_J$#Y)08lVWQKDgFj*&`1MP7=>io;W4rXb{tYL zp=Y*6%*;k4ok=mF3jTXOl6`&%V@gSLUMpbNQH4Q!r?*W>kH??px@4O!w_b}GBiAx+~DDSFdG>j0z1!L z84e7aPMOUN-cV_swRDVl+SdLTi84H@46M$~vMKPcR#~W2X|wgCwW@KZ)V6&_XET>? zZDh{hnrri4sJB98o||HknT$IyUpQ_OSz$s(Wa5w!Ss7ZZEoIi(To>|;H;#z8$);MH z`EW+X252$&f>94$XOnVO-byRR6~cnw=A73}ZJpa@qXlQ!_?A2}o9StPatorKc~!K^ O1{o}0SRMEP0000Yp_Hru diff --git a/dev/assets/inter-roman-greek.JvnBZ4YD.woff2 b/dev/assets/inter-roman-greek.JvnBZ4YD.woff2 deleted file mode 100644 index f790e047daa346583880da2be470431e35aa6054..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21776 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 De!(H( diff --git a/dev/assets/inter-roman-latin-ext.ZlYT4o7i.woff2 b/dev/assets/inter-roman-latin-ext.ZlYT4o7i.woff2 deleted file mode 100644 index 715bd903b9b14d22a056f10e6d13b8d7e0acce57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59608 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

Aggregation Layer

Some text to describe the aggragation layer within usual ICNs.

List of aggregations

# CompositionalNetworks.ag_sumFunction.
julia
ag_sum(x)

Aggregate through + a vector into a single scalar.

source


# CompositionalNetworks.ag_count_positiveFunction.
julia
ag_count_positive(x)

Count the number of strictly positive elements of x.

source


Layer generation

# CompositionalNetworks.aggregation_layerFunction.
julia
aggregation_layer()

Generate the layer of aggregations of the ICN. The operations are mutually exclusive, that is only one will be selected.

source


',10),s=[r];function n(g,l,p,d,c,h){return i(),e("div",null,s)}const k=a(o,[["render",n]]);export{b as __pageData,k as default}; diff --git a/dev/assets/learning_aggregation.md.5RLMQ4Bd.lean.js b/dev/assets/learning_aggregation.md.5RLMQ4Bd.lean.js deleted file mode 100644 index d0fcbcd..0000000 --- a/dev/assets/learning_aggregation.md.5RLMQ4Bd.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as e,o as i,a7 as t}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"Aggregation Layer","description":"","frontmatter":{},"headers":[],"relativePath":"learning/aggregation.md","filePath":"learning/aggregation.md","lastUpdated":null}'),o={name:"learning/aggregation.md"},r=t("",10),s=[r];function n(g,l,p,d,c,h){return i(),e("div",null,s)}const k=a(o,[["render",n]]);export{b as __pageData,k as default}; diff --git a/dev/assets/learning_arithmetic.md.DW5u7RMW.js b/dev/assets/learning_arithmetic.md.DW5u7RMW.js deleted file mode 100644 index 3b42d9e..0000000 --- a/dev/assets/learning_arithmetic.md.DW5u7RMW.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as i,o as t,a7 as a}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"Arithmetic Layer","description":"","frontmatter":{},"headers":[],"relativePath":"learning/arithmetic.md","filePath":"learning/arithmetic.md","lastUpdated":null}'),r={name:"learning/arithmetic.md"},o=a('

Arithmetic Layer

Some text to describe the arithmetic layer within usual ICNs.

List of arithmetic operations

# CompositionalNetworks.ar_sumFunction.
julia
ar_sum(x)

Reduce k = length(x) vectors through sum to a single vector.

source


# CompositionalNetworks.ar_prodFunction.
julia
ar_prod(x)

Reduce k = length(x) vectors through product to a single vector.

source


Layer generation

# CompositionalNetworks.arithmetic_layerFunction.
julia
arithmetic_layer()

Generate the layer of arithmetic operations of the ICN. The operations are mutually exclusive, that is only one will be selected.

source


',10),s=[o];function l(n,h,c,p,d,m){return t(),i("div",null,s)}const g=e(r,[["render",l]]);export{b as __pageData,g as default}; diff --git a/dev/assets/learning_arithmetic.md.DW5u7RMW.lean.js b/dev/assets/learning_arithmetic.md.DW5u7RMW.lean.js deleted file mode 100644 index 5f32649..0000000 --- a/dev/assets/learning_arithmetic.md.DW5u7RMW.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as i,o as t,a7 as a}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"Arithmetic Layer","description":"","frontmatter":{},"headers":[],"relativePath":"learning/arithmetic.md","filePath":"learning/arithmetic.md","lastUpdated":null}'),r={name:"learning/arithmetic.md"},o=a("",10),s=[o];function l(n,h,c,p,d,m){return t(),i("div",null,s)}const g=e(r,[["render",l]]);export{b as __pageData,g as default}; diff --git a/dev/assets/learning_comparison.md.BsnqPWC-.js b/dev/assets/learning_comparison.md.BsnqPWC-.js deleted file mode 100644 index 6dcfb65..0000000 --- a/dev/assets/learning_comparison.md.BsnqPWC-.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as i,o as s,a7 as o}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"Comparison Layer","description":"","frontmatter":{},"headers":[],"relativePath":"learning/comparison.md","filePath":"learning/comparison.md","lastUpdated":null}'),e={name:"learning/comparison.md"},r=o('

Comparison Layer

Some text to describe the comparison layer within usual ICNs.

List of comparisons

List the possible parameters and how it affects the comparison.

Non-parametric

# CompositionalNetworks.co_identityFunction.
julia
co_identity(x)

Identity function. Already defined in Julia as identity, specialized for scalars in the comparison layer.

source


Missing docstring.

Missing docstring for co_euclidian. Check Documenter's build log for details.

# CompositionalNetworks.co_abs_diff_val_varsFunction.
julia
co_abs_diff_val_vars(x; nvars)

Return the absolute difference between x and the number of variables nvars.

source


# CompositionalNetworks.co_val_minus_varsFunction.
julia
co_val_minus_vars(x; nvars)

Return the difference x - nvars if positive, 0.0 otherwise, where nvars denotes the numbers of variables.

source


# CompositionalNetworks.co_vars_minus_valFunction.
julia
co_vars_minus_val(x; nvars)

Return the difference nvars - x if positive, 0.0 otherwise, where nvars denotes the numbers of variables.

source


Param: :val

# CompositionalNetworks.co_abs_diff_val_paramFunction.
julia
co_abs_diff_val_param(x; param)

Return the absolute difference between x and param.

source


# CompositionalNetworks.co_val_minus_paramFunction.
julia
co_val_minus_param(x; param)

Return the difference x - param if positive, 0.0 otherwise.

source


# CompositionalNetworks.co_param_minus_valFunction.
julia
co_param_minus_val(x; param)

Return the difference param - x if positive, 0.0 otherwise.

source


Missing docstring.

Missing docstring for co_euclidian_param. Check Documenter's build log for details.

Layer generation

Missing docstring.

Missing docstring for make_comparisons. Check Documenter's build log for details.

# CompositionalNetworks.comparison_layerFunction.
julia
comparison_layer(param = false)

Generate the layer of transformations functions of the ICN. Iff param value is set, also includes all the parametric comparison with that value. The operations are mutually exclusive, that is only one will be selected.

source


',26),t=[r];function n(l,p,c,d,h,m){return s(),i("div",null,t)}const k=a(e,[["render",n]]);export{b as __pageData,k as default}; diff --git a/dev/assets/learning_comparison.md.BsnqPWC-.lean.js b/dev/assets/learning_comparison.md.BsnqPWC-.lean.js deleted file mode 100644 index 22d78db..0000000 --- a/dev/assets/learning_comparison.md.BsnqPWC-.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as i,o as s,a7 as o}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"Comparison Layer","description":"","frontmatter":{},"headers":[],"relativePath":"learning/comparison.md","filePath":"learning/comparison.md","lastUpdated":null}'),e={name:"learning/comparison.md"},r=o("",26),t=[r];function n(l,p,c,d,h,m){return s(),i("div",null,t)}const k=a(e,[["render",n]]);export{b as __pageData,k as default}; diff --git a/dev/assets/learning_compositional_networks.md.BZgNyUW3.js b/dev/assets/learning_compositional_networks.md.BZgNyUW3.js deleted file mode 100644 index f1e447e..0000000 --- a/dev/assets/learning_compositional_networks.md.BZgNyUW3.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as s,o,a7 as a}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"CompositionalNetworks.jl","description":"","frontmatter":{},"headers":[],"relativePath":"learning/compositional_networks.md","filePath":"learning/compositional_networks.md","lastUpdated":null}'),t={name:"learning/compositional_networks.md"},e=a('

CompositionalNetworks.jl

Documentation for CompositionalNetworks.jl.

Utilities

# CompositionalNetworks.map_tr!Function.
julia
map_tr!(f, x, X, param)

Return an anonymous function that applies f to all elements of x and store the result in X, with a parameter param (which is set to nothing for function with no parameter).

source


# CompositionalNetworks.lazyFunction.
julia
lazy(funcs::Function...)

Generate methods extended to a vector instead of one of its components. A function f should have the following signature: f(i::Int, x::V).

source


# CompositionalNetworks.lazy_paramFunction.
julia
lazy_param(funcs::Function...)

Generate methods extended to a vector instead of one of its components. A function f should have the following signature: f(i::Int, x::V; param).

source


# CompositionalNetworks.as_bitvectorFunction.
julia
as_bitvector(n::Int, max_n::Int = n)

Convert an Int to a BitVector of minimal size (relatively to max_n).

source


# CompositionalNetworks.as_intFunction.
julia
as_int(v::AbstractVector)

Convert a BitVector into an Int.

source


# CompositionalNetworks.reduce_symbolsFunction.
julia
reduce_symbols(symbols, sep)

Produce a formatted string that separates the symbols by sep. Used internally for show_composition.

source


Missing docstring.

Missing docstring for CompositionalNeworks.tr_in. Check Documenter's build log for details.

Metrics

# CompositionalNetworks.hammingFunction.
julia
hamming(x, X)

Compute the hamming distance of x over a collection of solutions X, i.e. the minimal number of variables to switch in xto reach a solution.

source


# CompositionalNetworks.minkowskiFunction.
julia
minkowski(x, X, p)

source


# CompositionalNetworks.manhattanFunction.
julia
manhattan(x, X)

source


Missing docstring.

Missing docstring for weigths_bias. Check Documenter's build log for details.

',24),n=[e];function l(r,p,d,c,h,k){return o(),s("div",null,n)}const b=i(t,[["render",l]]);export{u as __pageData,b as default}; diff --git a/dev/assets/learning_compositional_networks.md.BZgNyUW3.lean.js b/dev/assets/learning_compositional_networks.md.BZgNyUW3.lean.js deleted file mode 100644 index 526d1fd..0000000 --- a/dev/assets/learning_compositional_networks.md.BZgNyUW3.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as s,o,a7 as a}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"CompositionalNetworks.jl","description":"","frontmatter":{},"headers":[],"relativePath":"learning/compositional_networks.md","filePath":"learning/compositional_networks.md","lastUpdated":null}'),t={name:"learning/compositional_networks.md"},e=a("",24),n=[e];function l(r,p,d,c,h,k){return o(),s("div",null,n)}const b=i(t,[["render",l]]);export{u as __pageData,b as default}; diff --git a/dev/assets/learning_constraint_learning.md.DAfFojnp.js b/dev/assets/learning_constraint_learning.md.DAfFojnp.js deleted file mode 100644 index ac50929..0000000 --- a/dev/assets/learning_constraint_learning.md.DAfFojnp.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as s,o as a,a7 as e}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"ConstraintLearning.jl","description":"","frontmatter":{},"headers":[],"relativePath":"learning/constraint_learning.md","filePath":"learning/constraint_learning.md","lastUpdated":null}'),t={name:"learning/constraint_learning.md"},n=e('

ConstraintLearning.jl

Documentation for ConstraintLearning.jl.

# ConstraintLearning.ICNConfigType.
julia
struct ICNConfig{O <: ICNOptimizer}

A structure to hold the metric and optimizer configurations used in learning the weights of an ICN.

source


# ConstraintLearning.ICNConfigMethod.
julia
ICNConfig(; metric = :hamming, optimizer = ICNGeneticOptimizer())

Constructor for ICNConfig. Defaults to hamming metric using a genetic algorithm.

source


# ConstraintLearning.ICNGeneticOptimizerMethod.
julia
ICNGeneticOptimizer(; kargs...)

Default constructor to learn an ICN through a Genetic Algorithm. Default kargs TBW.

source


# ConstraintLearning.ICNLocalSearchOptimizerType.
julia
ICNLocalSearchOptimizer(options = LocalSearchSolvers.Options())

Default constructor to learn an ICN through a CBLS solver.

source


# ConstraintLearning.ICNOptimizerType.
julia
const ICNOptimizer = CompositionalNetworks.AbstractOptimizer

An abstract type for optmizers defined to learn ICNs.

source


# ConstraintLearning.QUBOGradientOptimizerMethod.
julia
QUBOGradientOptimizer(; kargs...)

A QUBO optimizer based on gradient descent. Defaults TBW

source


# ConstraintLearning.QUBOOptimizerType.
julia
const QUBOOptimizer = QUBOConstraints.AbstractOptimizer

An abstract type for optimizers used to learn QUBO matrices from constraints.

source


# CompositionalNetworks.optimize!Method.
julia
CompositionalNetworks.optimize!(icn, solutions, non_sltns, dom_size, metric, optimizer::ICNGeneticOptimizer; parameters...)

Extends the optimize! method to ICNGeneticOptimizer.

source


# CompositionalNetworks.optimize!Method.
julia
CompositionalNetworks.optimize!(icn, solutions, non_sltns, dom_size, metric, optimizer::ICNLocalSearchOptimizer; parameters...)

Extends the optimize! method to ICNLocalSearchOptimizer.

source


# ConstraintLearning._optimize!Method.
julia
_optimize!(icn, X, X_sols; metric = hamming, pop_size = 200)

Optimize and set the weights of an ICN with a given set of configuration X and solutions X_sols.

source


# ConstraintLearning.domain_sizeMethod.
julia
domain_size(ds::Number)

Extends the domain_size function when ds is number (for dispatch purposes).

source


# ConstraintLearning.generate_populationMethod.
julia
generate_population(icn, pop_size

Generate a pôpulation of weights (individuals) for the genetic algorithm weighting icn.

source


# ConstraintLearning.icnMethod.
julia
icn(X,X̅; kargs..., parameters...)

TBW

source


# ConstraintLearning.lossMethod.
julia
loss(x, y, Q)

Loss of the prediction given by Q, a training set y, and a given configuration x.

source


# ConstraintLearning.make_dfMethod.
julia
make_df(X, Q, penalty, binarization, domains)

DataFrame arrangement to output some basic evaluation of a matrix Q.

source


# ConstraintLearning.make_set_penaltyMethod.
julia
make_set_penalty(X, X̅, args...; kargs)

Return a penalty function when the training set is already split into a pair of solutions X and non solutions .

source


# ConstraintLearning.make_training_setsMethod.
julia
make_training_sets(X, penalty, args...)

Return a pair of solutions and non solutions sets based on X and penalty.

source


# ConstraintLearning.mutually_exclusiveMethod.
julia
mutually_exclusive(layer, w)

Constraint ensuring that w encode exclusive operations in layer.

source


# ConstraintLearning.no_empty_layerMethod.
julia
no_empty_layer(x; X = nothing)

Constraint ensuring that at least one operation is selected.

source


# ConstraintLearning.optimize!Method.
julia
optimize!(icn, X, X_sols, global_iter, local_iter; metric=hamming, popSize=100)

Optimize and set the weights of an ICN with a given set of configuration X and solutions X_sols. The best weights among global_iter will be set.

source


# ConstraintLearning.parameter_specific_operationsMethod.
julia
parameter_specific_operations(x; X = nothing)

Constraint ensuring that at least one operation related to parameters is selected if the error function to be learned is parametric.

source


# ConstraintLearning.predictMethod.
julia
predict(x, Q)

Return the predictions given by Q for a given configuration x.

source


# ConstraintLearning.preliminariesMethod.
julia
preliminaries(args)

Preliminaries to the training process in a QUBOGradientOptimizer run.

source


# ConstraintLearning.quboFunction.
julia
qubo(X,X̅; kargs..., parameters...)

TBW

source


# ConstraintLearning.sub_eltypeMethod.
julia
sub_eltype(X)

Return the element type of of the first element of a collection.

source


# ConstraintLearning.train!Method.
julia
train!(Q, X, penalty, η, precision, X_test, oversampling, binarization, domains)

Training inner method.

source


# ConstraintLearning.trainMethod.
julia
train(X, penalty[, d]; optimizer = QUBOGradientOptimizer(), X_test = X)

Learn a QUBO matrix on training set X for a constraint defined by penalty with optional domain information d. By default, it uses a QUBOGradientOptimizer and X as a testing set.

source


# ConstraintLearning.δMethod.
julia
δ(X[, Y]; discrete = true)

Compute the extrema over a collection X``or a pair of collection(X, Y)`.

source


',58),r=[n];function l(o,p,d,h,c,g){return a(),s("div",null,r)}const b=i(t,[["render",l]]);export{u as __pageData,b as default}; diff --git a/dev/assets/learning_constraint_learning.md.DAfFojnp.lean.js b/dev/assets/learning_constraint_learning.md.DAfFojnp.lean.js deleted file mode 100644 index 8495349..0000000 --- a/dev/assets/learning_constraint_learning.md.DAfFojnp.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as s,o as a,a7 as e}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"ConstraintLearning.jl","description":"","frontmatter":{},"headers":[],"relativePath":"learning/constraint_learning.md","filePath":"learning/constraint_learning.md","lastUpdated":null}'),t={name:"learning/constraint_learning.md"},n=e("",58),r=[n];function l(o,p,d,h,c,g){return a(),s("div",null,r)}const b=i(t,[["render",l]]);export{u as __pageData,b as default}; diff --git a/dev/assets/learning_intro.md.497AVcuz.js b/dev/assets/learning_intro.md.497AVcuz.js deleted file mode 100644 index 3405aca..0000000 --- a/dev/assets/learning_intro.md.497AVcuz.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as n,o as e,m as t,a as r}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"Learning about Constraints","description":"","frontmatter":{},"headers":[],"relativePath":"learning/intro.md","filePath":"learning/intro.md","lastUpdated":null}'),o={name:"learning/intro.md"},s=t("h1",{id:"Learning-about-Constraints",tabindex:"-1"},[r("Learning about Constraints "),t("a",{class:"header-anchor",href:"#Learning-about-Constraints","aria-label":'Permalink to "Learning about Constraints {#Learning-about-Constraints}"'},"​")],-1),i=t("p",null,"About learning constraints related matters.",-1),c=[s,i];function l(d,_,u,p,m,g){return e(),n("div",null,c)}const f=a(o,[["render",l]]);export{b as __pageData,f as default}; diff --git a/dev/assets/learning_intro.md.497AVcuz.lean.js b/dev/assets/learning_intro.md.497AVcuz.lean.js deleted file mode 100644 index 3405aca..0000000 --- a/dev/assets/learning_intro.md.497AVcuz.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as n,o as e,m as t,a as r}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"Learning about Constraints","description":"","frontmatter":{},"headers":[],"relativePath":"learning/intro.md","filePath":"learning/intro.md","lastUpdated":null}'),o={name:"learning/intro.md"},s=t("h1",{id:"Learning-about-Constraints",tabindex:"-1"},[r("Learning about Constraints "),t("a",{class:"header-anchor",href:"#Learning-about-Constraints","aria-label":'Permalink to "Learning about Constraints {#Learning-about-Constraints}"'},"​")],-1),i=t("p",null,"About learning constraints related matters.",-1),c=[s,i];function l(d,_,u,p,m,g){return e(),n("div",null,c)}const f=a(o,[["render",l]]);export{b as __pageData,f as default}; diff --git a/dev/assets/learning_layers.md.DuFC9ol_.js b/dev/assets/learning_layers.md.DuFC9ol_.js deleted file mode 100644 index d49aa3b..0000000 --- a/dev/assets/learning_layers.md.DuFC9ol_.js +++ /dev/null @@ -1,4 +0,0 @@ -import{_ as e,c as i,o as s,a7 as a}from"./chunks/framework.aA95Gx5L.js";const g=JSON.parse('{"title":"A layer structure for any ICN","description":"","frontmatter":{},"headers":[],"relativePath":"learning/layers.md","filePath":"learning/layers.md","lastUpdated":null}'),t={name:"learning/layers.md"},r=a(`

A layer structure for any ICN

The layer.jl file defines a Layer structure and several associated functions for manipulating and interacting with this structure in the context of an Interpretable Compositional Network (ICN).

The Layer structure is used to store a LittleDict of operations that can be selected during the learning phase of an ICN. Each layer can be exclusive, meaning only one operation can be selected at a time. This is particularly useful in the context of ICNs, which are used to learn alternative expressions for highly combinatorial functions, such as those found in Constraint-based Local Search solvers.

# CompositionalNetworks.LayerType.
julia
Layer

A structure to store a LittleDict of operations that can be selected during the learning phase of an ICN. If the layer is exclusive, only one operation can be selected at a time.

source


# CompositionalNetworks.functionsFunction.
julia
functions(layer)

Access the operations of a layer. The container is ordered.

source


# Base.lengthMethod.
julia
length(layer)

Return the number of operations in a layer.

source


# CompositionalNetworks.excluFunction.
julia
exclu(layer)

Return true if the layer has mutually exclusive operations.

source


# CompositionalNetworks.symbolFunction.
julia
symbol(layer, i)

Return the i-th symbols of the operations in a given layer.

source


# CompositionalNetworks.nbits_excluFunction.
julia
nbits_exclu(layer)

Convert the length of an exclusive layer into a number of bits.

source


# CompositionalNetworks.show_layerFunction.
julia
show_layer(layer)

Return a string that contains the elements in a layer.

source


# CompositionalNetworks.selected_sizeFunction.
julia
selected_size(layer, layer_weights)

Return the number of operations selected by layer_weights in layer.

source


# CompositionalNetworks.is_viableFunction.
julia
is_viable(layer, w)
-is_viable(icn)
-is_viable(icn, w)

Assert if a pair of layer/icn and weights compose a viable pattern. If no weights are given with an icn, it will check the current internal value.

source


# CompositionalNetworks.generate_inclusive_operationsFunction.
julia
generate_inclusive_operations(predicate, bits)
-generate_exclusive_operation(max_op_number)

Generates the operations (weights) of a layer with inclusive/exclusive operations.

source


# CompositionalNetworks.generate_exclusive_operationFunction.
julia
generate_exclusive_operation(max_op_number)

Generates the operations (weigths) of a layer with exclusive operations.

source


Missing docstring.

Missing docstring for generate_weigths. Check Documenter's build log for details.

`,26),o=[r];function l(n,p,d,c,h,u){return s(),i("div",null,o)}const k=e(t,[["render",l]]);export{g as __pageData,k as default}; diff --git a/dev/assets/learning_layers.md.DuFC9ol_.lean.js b/dev/assets/learning_layers.md.DuFC9ol_.lean.js deleted file mode 100644 index e8a296a..0000000 --- a/dev/assets/learning_layers.md.DuFC9ol_.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as i,o as s,a7 as a}from"./chunks/framework.aA95Gx5L.js";const g=JSON.parse('{"title":"A layer structure for any ICN","description":"","frontmatter":{},"headers":[],"relativePath":"learning/layers.md","filePath":"learning/layers.md","lastUpdated":null}'),t={name:"learning/layers.md"},r=a("",26),o=[r];function l(n,p,d,c,h,u){return s(),i("div",null,o)}const k=e(t,[["render",l]]);export{g as __pageData,k as default}; diff --git a/dev/assets/learning_qubo_constraints.md.DpCFckdQ.js b/dev/assets/learning_qubo_constraints.md.DpCFckdQ.js deleted file mode 100644 index e2bcb23..0000000 --- a/dev/assets/learning_qubo_constraints.md.DpCFckdQ.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as s,o as t,a7 as i}from"./chunks/framework.aA95Gx5L.js";const _=JSON.parse('{"title":"Introduction to QUBOConstraints.jl","description":"","frontmatter":{},"headers":[],"relativePath":"learning/qubo_constraints.md","filePath":"learning/qubo_constraints.md","lastUpdated":null}'),n={name:"learning/qubo_constraints.md"},e=i('

Introduction to QUBOConstraints.jl

Introduction to QUBOConstraints.jl.

Basic features

# QUBOConstraints.QUBO_baseFunction.
julia
QUBO_base(n, weight = 1)

A basic QUBO matrix to ensure that binarized variables keep a valid encoding.

source


# QUBOConstraints.QUBO_linear_sumFunction.
julia
QUBO_linear_sum(n, σ)

One valid QUBO matrix given n variables and parameter σ for the linear sum constraint.

source


',7),r=[e];function o(l,d,c,p,h,u){return t(),s("div",null,r)}const g=a(n,[["render",o]]);export{_ as __pageData,g as default}; diff --git a/dev/assets/learning_qubo_constraints.md.DpCFckdQ.lean.js b/dev/assets/learning_qubo_constraints.md.DpCFckdQ.lean.js deleted file mode 100644 index b897c33..0000000 --- a/dev/assets/learning_qubo_constraints.md.DpCFckdQ.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as s,o as t,a7 as i}from"./chunks/framework.aA95Gx5L.js";const _=JSON.parse('{"title":"Introduction to QUBOConstraints.jl","description":"","frontmatter":{},"headers":[],"relativePath":"learning/qubo_constraints.md","filePath":"learning/qubo_constraints.md","lastUpdated":null}'),n={name:"learning/qubo_constraints.md"},e=i("",7),r=[e];function o(l,d,c,p,h,u){return t(),s("div",null,r)}const g=a(n,[["render",o]]);export{_ as __pageData,g as default}; diff --git a/dev/assets/learning_qubo_encoding.md.CDyoKOWI.js b/dev/assets/learning_qubo_encoding.md.CDyoKOWI.js deleted file mode 100644 index 4331453..0000000 --- a/dev/assets/learning_qubo_encoding.md.CDyoKOWI.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as a,o as n,a7 as s}from"./chunks/framework.aA95Gx5L.js";const k=JSON.parse('{"title":"Encoding for QUBO programs","description":"","frontmatter":{},"headers":[],"relativePath":"learning/qubo_encoding.md","filePath":"learning/qubo_encoding.md","lastUpdated":null}'),e={name:"learning/qubo_encoding.md"},o=s('

Encoding for QUBO programs

# QUBOConstraints.is_validFunction.
julia
is_valid(x, encoding::Symbol = :none)

Check if x has a valid format for encoding.

For instance, if encoding == :one_hot, at most one bit of x can be set to 1.

source


# QUBOConstraints.binarizeFunction.
julia
binarize(x[, domain]; binarization = :one_hot)

Binarize x following the binarization encoding. If x is a vector (instead of a number per say), domain is optional.

source


# QUBOConstraints.debinarizeFunction.
julia
debinarize(x[, domain]; binarization = :one_hot)

Transform a binary vector into a number or a set of number. If domain is not given, it will compute a default value based on binarization and x.

source


',7),t=[o];function r(d,l,c,p,h,g){return n(),a("div",null,t)}const u=i(e,[["render",r]]);export{k as __pageData,u as default}; diff --git a/dev/assets/learning_qubo_encoding.md.CDyoKOWI.lean.js b/dev/assets/learning_qubo_encoding.md.CDyoKOWI.lean.js deleted file mode 100644 index 797be23..0000000 --- a/dev/assets/learning_qubo_encoding.md.CDyoKOWI.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as a,o as n,a7 as s}from"./chunks/framework.aA95Gx5L.js";const k=JSON.parse('{"title":"Encoding for QUBO programs","description":"","frontmatter":{},"headers":[],"relativePath":"learning/qubo_encoding.md","filePath":"learning/qubo_encoding.md","lastUpdated":null}'),e={name:"learning/qubo_encoding.md"},o=s("",7),t=[o];function r(d,l,c,p,h,g){return n(),a("div",null,t)}const u=i(e,[["render",r]]);export{k as __pageData,u as default}; diff --git a/dev/assets/learning_qubo_learning.md.CLlNBMzd.js b/dev/assets/learning_qubo_learning.md.CLlNBMzd.js deleted file mode 100644 index 719aa95..0000000 --- a/dev/assets/learning_qubo_learning.md.CLlNBMzd.js +++ /dev/null @@ -1,119 +0,0 @@ -import{_ as s,c as i,o as a,a7 as n}from"./chunks/framework.aA95Gx5L.js";const F=JSON.parse('{"title":"Learning QUBO matrices","description":"","frontmatter":{},"headers":[],"relativePath":"learning/qubo_learning.md","filePath":"learning/qubo_learning.md","lastUpdated":null}'),h={name:"learning/qubo_learning.md"},k=n(`

Learning QUBO matrices

Interface

# QUBOConstraints.AbstractOptimizerType.
julia
AbstractOptimizer

An abstract type (interface) used to learn QUBO matrices from constraints. Only a train method is required.

source


# QUBOConstraints.trainFunction.
julia
train(args...)

Default train method for any AbstractOptimizer.

source


Examples with various optimizers

Gradient Descent

julia
struct GradientDescentOptimizer <: QUBOConstraints.AbstractOptimizer
-    binarization::Symbol
-    η::Float64
-    precision::Int
-    oversampling::Bool
-end
-
-function GradientDescentOptimizer(;
-    binarization = :one_hot,
-    η = .001,
-    precision = 5,
-    oversampling = false,
-)
-    return GradientDescentOptimizer(binarization, η, precision, oversampling)
-end
-
-
-predict(x, Q) = transpose(x) * Q * x
-
-loss(x, y, Q) = (predict(x, Q) .-y).^2
-
-function make_df(X, Q, penalty, binarization, domains)
-    df = DataFrame()
-    for (i,x) in enumerate(X)
-        if i == 1
-            df = DataFrame(transpose(x), :auto)
-        else
-            push!(df, transpose(x))
-        end
-    end
-
-    dim = length(df[1,:])
-
-    if binarization == :none
-        df[!,:penalty] = map(r -> penalty(Vector(r)), eachrow(df))
-        df[!,:predict] = map(r -> predict(Vector(r), Q), eachrow(df[:, 1:dim]))
-    else
-        df[!,:penalty] = map(
-            r -> penalty(binarize(Vector(r), domains; binarization)),
-            eachrow(df)
-        )
-        df[!,:predict] = map(
-            r -> predict(binarize(Vector(r), domains; binarization), Q),
-            eachrow(df[:, 1:dim])
-        )
-    end
-
-    min_false = minimum(
-        filter(:penalty => >(minimum(df[:,:penalty])), df)[:,:predict];
-        init = typemax(Int)
-    )
-    df[!,:shifted] = df[:,:predict] .- min_false
-    df[!,:accurate] = df[:, :penalty] .* df[:,:shifted] .≥ 0.
-
-    return df
-end
-
-function preliminaries(X, domains, binarization)
-    if binarization==:none
-        n = length(first(X))
-        return X, zeros(n,n)
-    else
-        Y = map(x -> collect(binarize(x, domains; binarization)), X)
-        n = length(first(Y))
-        return Y, zeros(n,n)
-    end
-end
-
-function preliminaries(X, _)
-    n = length(first(X))
-    return X, zeros(n,n)
-end
-
-function train!(Q, X, penalty, η, precision, X_test, oversampling, binarization, domains)
-    θ = params(Q)
-    try
-        penalty(first(X))
-    catch e
-        if isa(e, UndefKeywordError)
-            penalty = (x; dom_size = δ_extrema(Iterators.flatten(X)))-> penalty(x; dom_size)
-        else
-            throw(e)
-        end
-    end
-    for x in (oversampling ? oversample(X, penalty) : X)
-        grads = gradient(() -> loss(x, penalty(x), Q), θ)
-        Q .-= η * grads[Q]
-    end
-
-    Q[:,:] = round.(precision*Q)
-
-    df = make_df(X_test, Q, penalty, binarization, domains)
-    return pretty_table(describe(df[!, [:penalty, :predict, :shifted, :accurate]]))
-end
-
-function train(
-    X,
-    penalty,
-    domains::Vector{D};
-    optimizer = GradientDescentOptimizer(),
-    X_test = X,
-) where {D <: DiscreteDomain}
-    Y, Q = preliminaries(X, domains, optimizer.binarization)
-    train!(
-        Q, Y, penalty, optimizer.η, optimizer.precision, X_test,
-        optimizer.oversampling, optimizer.binarization, domains
-    )
-    return Q
-end
-
-function train(
-    X,
-    penalty,
-    dom_stuff = nothing;
-    optimizer = GradientDescentOptimizer(),
-    X_test = X,
-)
-    return train(X, penalty, to_domains(X, dom_stuff); optimizer, X_test)
-end
`,10),l=[k];function p(t,e,E,r,d,g){return a(),i("div",null,l)}const c=s(h,[["render",p]]);export{F as __pageData,c as default}; diff --git a/dev/assets/learning_qubo_learning.md.CLlNBMzd.lean.js b/dev/assets/learning_qubo_learning.md.CLlNBMzd.lean.js deleted file mode 100644 index b7ec16b..0000000 --- a/dev/assets/learning_qubo_learning.md.CLlNBMzd.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as i,o as a,a7 as n}from"./chunks/framework.aA95Gx5L.js";const F=JSON.parse('{"title":"Learning QUBO matrices","description":"","frontmatter":{},"headers":[],"relativePath":"learning/qubo_learning.md","filePath":"learning/qubo_learning.md","lastUpdated":null}'),h={name:"learning/qubo_learning.md"},k=n("",10),l=[k];function p(t,e,E,r,d,g){return a(),i("div",null,l)}const c=s(h,[["render",p]]);export{F as __pageData,c as default}; diff --git a/dev/assets/learning_transformation.md.BtKPMNbs.js b/dev/assets/learning_transformation.md.BtKPMNbs.js deleted file mode 100644 index 456713f..0000000 --- a/dev/assets/learning_transformation.md.BtKPMNbs.js +++ /dev/null @@ -1,45 +0,0 @@ -import{_ as s,c as i,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const g=JSON.parse('{"title":"Transformations Layer","description":"","frontmatter":{},"headers":[],"relativePath":"learning/transformation.md","filePath":"learning/transformation.md","lastUpdated":null}'),e={name:"learning/transformation.md"},n=t(`

Transformations Layer

Some text to describe the transformation layer within usual ICNs.

The implementation of the transformation relies heavily on the use of the lazy function (make a ref, open an issue to make @lazy macro in front of each transformation).

List of transformations

List the possible parameters and how it affects the transformations.

Non-parametric

# CompositionalNetworks.tr_identityFunction.
julia
tr_identity(i, x)
-tr_identity(x)
-tr_identity(x, X::AbstractVector)

Identity function. Already defined in Julia as identity, specialized for vectors. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eqFunction.
julia
tr_count_eq(i, x)
-tr_count_eq(x)
-tr_count_eq(x, X::AbstractVector)

Count the number of elements equal to x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eq_rightFunction.
julia
tr_count_eq_right(i, x)
-tr_count_eq_right(x)
-tr_count_eq_right(x, X::AbstractVector)

Count the number of elements to the right of and equal to x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eq_leftFunction.
julia
tr_count_eq_left(i, x)
-tr_count_eq_left(x)
-tr_count_eq_left(x, X::AbstractVector)

Count the number of elements to the left of and equal to x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_greaterFunction.
julia
tr_count_greater(i, x)
-tr_count_greater(x)
-tr_count_greater(x, X::AbstractVector)

Count the number of elements greater than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_lesserFunction.
julia
tr_count_lesser(i, x)
-tr_count_lesser(x)
-tr_count_lesser(x, X::AbstractVector)

Count the number of elements lesser than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_g_leftFunction.
julia
tr_count_g_left(i, x)
-tr_count_g_left(x)
-tr_count_g_left(x, X::AbstractVector)

Count the number of elements to the left of and greater than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_g_rightFunction.
julia
tr_count_g_right(i, x)
-tr_count_g_right(x)
-tr_count_g_right(x, X::AbstractVector)

Count the number of elements to the right of and greater than x[i]. Extended method to vector with sig (x) are generated.

source


# CompositionalNetworks.tr_count_l_rightFunction.
julia
tr_count_l_right(i, x)
-tr_count_l_right(x)
-tr_count_l_right(x, X::AbstractVector)

Count the number of elements to the right of and lesser than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_contiguous_vals_minusFunction.
julia
tr_contiguous_vals_minus(i, x)
-tr_contiguous_vals_minus(x)
-tr_contiguous_vals_minus(x, X::AbstractVector)

Return the difference x[i] - x[i + 1] if positive, 0.0 otherwise. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_contiguous_vals_minus_revFunction.
julia
tr_contiguous_vals_minus_rev(i, x)
-tr_contiguous_vals_minus_rev(x)
-tr_contiguous_vals_minus_rev(x, X::AbstractVector)

Return the difference x[i + 1] - x[i] if positive, 0.0 otherwise. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


Param: :val

# CompositionalNetworks.tr_count_eq_paramFunction.
julia
tr_count_eq_param(i, x; param)
-tr_count_eq_param(x; param)
-tr_count_eq_param(x, X::AbstractVector; param)

Count the number of elements equal to x[i] + param. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_l_paramFunction.
julia
tr_count_l_param(i, x; param)
-tr_count_l_param(x; param)
-tr_count_l_param(x, X::AbstractVector; param)

Count the number of elements lesser than x[i] + param. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_g_paramFunction.
julia
tr_count_g_param(i, x; param)
-tr_count_g_param(x; param)
-tr_count_g_param(x, X::AbstractVector; param)

Count the number of elements greater than x[i] + param. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_bounding_paramFunction.
julia
tr_count_bounding_param(i, x; param)
-tr_count_bounding_param(x; param)
-tr_count_bounding_param(x, X::AbstractVector; param)

Count the number of elements bounded (not strictly) by x[i] and x[i] + param. An extended method to vector with sig (x, param) is generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_val_minus_paramFunction.
julia
tr_val_minus_param(i, x; param)
-tr_val_minus_param(x; param)
-tr_val_minus_param(x, X::AbstractVector; param)

Return the difference x[i] - param if positive, 0.0 otherwise. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_param_minus_valFunction.
julia
tr_param_minus_val(i, x; param)
-tr_param_minus_val(x; param)
-tr_param_minus_val(x, X::AbstractVector; param)

Return the difference param - x[i] if positive, 0.0 otherwise. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


Layer generation

# CompositionalNetworks.make_transformationsFunction.
julia
make_transformations(param::Symbol)

Generates a dictionary of transformation functions based on the specified parameterization. This function facilitates the creation of parametric layers for constraint transformations, allowing for flexible and dynamic constraint manipulation according to the needs of different constraint programming models.

Parameters

  • param::Symbol: Specifies the type of transformations to generate. It can be :none for basic transformations that do not depend on external parameters, or :val for transformations that operate with respect to a specific value parameter.

Returns

  • LittleDict{Symbol, Function}: A dictionary mapping transformation names (Symbol) to their corresponding functions (Function). The functions encapsulate various types of transformations, such as counting, comparison, and contiguous value processing.

Transformation Types

  • When param is :none, the following transformations are available:

    • :identity: No transformation is applied.

    • :count_eq, :count_eq_left, :count_eq_right: Count equalities under different conditions.

    • :count_greater, :count_lesser: Count values greater or lesser than a threshold.

    • :count_g_left, :count_l_left, :count_g_right, :count_l_right: Count values with greater or lesser comparisons from different directions.

    • :contiguous_vals_minus, :contiguous_vals_minus_rev: Process contiguous values with subtraction in normal and reverse order.

  • When param is :val, the transformations relate to operations involving a parameter value:

    • :count_eq_param, :count_l_param, :count_g_param: Count equalities or comparisons against a parameter value.

    • :count_bounding_param: Count values bounding a parameter value.

    • :val_minus_param, :param_minus_val: Subtract a parameter value from values or vice versa.

The function delegates to a version that uses Val(param) for dispatch, ensuring compile-time selection of the appropriate transformation set.

Examples

julia
# Get basic transformations
-basic_transforms = make_transformations(:none)
-
-# Apply an identity transformation
-identity_result = basic_transforms[:identity](data)
-
-# Get value-based transformations
-val_transforms = make_transformations(:val)
-
-# Apply a count equal to parameter transformation
-count_eq_param_result = val_transforms[:count_eq_param](data, param)

source


# CompositionalNetworks.transformation_layerFunction.
julia
transformation_layer(param = false)

Generate the layer of transformations functions of the ICN. Iff param value is true, also includes all the parametric transformations.

source


`,46),r=[n];function o(l,p,h,d,c,k){return a(),i("div",null,r)}const m=s(e,[["render",o]]);export{g as __pageData,m as default}; diff --git a/dev/assets/learning_transformation.md.BtKPMNbs.lean.js b/dev/assets/learning_transformation.md.BtKPMNbs.lean.js deleted file mode 100644 index 3875ead..0000000 --- a/dev/assets/learning_transformation.md.BtKPMNbs.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as i,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const g=JSON.parse('{"title":"Transformations Layer","description":"","frontmatter":{},"headers":[],"relativePath":"learning/transformation.md","filePath":"learning/transformation.md","lastUpdated":null}'),e={name:"learning/transformation.md"},n=t("",46),r=[n];function o(l,p,h,d,c,k){return a(),i("div",null,r)}const m=s(e,[["render",o]]);export{g as __pageData,m as default}; diff --git a/dev/assets/meta_meta_strategist.md.CuHkGJNL.js b/dev/assets/meta_meta_strategist.md.CuHkGJNL.js deleted file mode 100644 index 388cf6b..0000000 --- a/dev/assets/meta_meta_strategist.md.CuHkGJNL.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as s,o as r,m as t,a as e}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"MetaStrategist.jl","description":"","frontmatter":{},"headers":[],"relativePath":"meta/meta_strategist.md","filePath":"meta/meta_strategist.md","lastUpdated":null}'),o={name:"meta/meta_strategist.md"},i=t("h1",{id:"MetaStrategist.jl",tabindex:"-1"},[e("MetaStrategist.jl "),t("a",{class:"header-anchor",href:"#MetaStrategist.jl","aria-label":'Permalink to "MetaStrategist.jl {#MetaStrategist.jl}"'},"​")],-1),l=t("p",null,[e("Documentation for "),t("code",null,"MetaStrategist.jl"),e(".")],-1),n=[i,l];function c(d,_,m,p,g,h){return r(),s("div",null,n)}const S=a(o,[["render",c]]);export{u as __pageData,S as default}; diff --git a/dev/assets/meta_meta_strategist.md.CuHkGJNL.lean.js b/dev/assets/meta_meta_strategist.md.CuHkGJNL.lean.js deleted file mode 100644 index 388cf6b..0000000 --- a/dev/assets/meta_meta_strategist.md.CuHkGJNL.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as s,o as r,m as t,a as e}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"MetaStrategist.jl","description":"","frontmatter":{},"headers":[],"relativePath":"meta/meta_strategist.md","filePath":"meta/meta_strategist.md","lastUpdated":null}'),o={name:"meta/meta_strategist.md"},i=t("h1",{id:"MetaStrategist.jl",tabindex:"-1"},[e("MetaStrategist.jl "),t("a",{class:"header-anchor",href:"#MetaStrategist.jl","aria-label":'Permalink to "MetaStrategist.jl {#MetaStrategist.jl}"'},"​")],-1),l=t("p",null,[e("Documentation for "),t("code",null,"MetaStrategist.jl"),e(".")],-1),n=[i,l];function c(d,_,m,p,g,h){return r(),s("div",null,n)}const S=a(o,[["render",c]]);export{u as __pageData,S as default}; diff --git a/dev/assets/perf_benchmark_ext.md.CVYCQYDt.js b/dev/assets/perf_benchmark_ext.md.CVYCQYDt.js deleted file mode 100644 index 95486ea..0000000 --- a/dev/assets/perf_benchmark_ext.md.CVYCQYDt.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,c as a,o as t,m as e,a as n}from"./chunks/framework.aA95Gx5L.js";const f=JSON.parse('{"title":"BenchmarkTools Extension","description":"","frontmatter":{},"headers":[],"relativePath":"perf/benchmark_ext.md","filePath":"perf/benchmark_ext.md","lastUpdated":null}'),s={name:"perf/benchmark_ext.md"},r=e("h1",{id:"BenchmarkTools-Extension",tabindex:"-1"},[n("BenchmarkTools Extension "),e("a",{class:"header-anchor",href:"#BenchmarkTools-Extension","aria-label":'Permalink to "BenchmarkTools Extension {#BenchmarkTools-Extension}"'},"​")],-1),c=e("p",null,[n("A benchmarking extension, based on "),e("code",null,"BenchmarkTools.jl"),n(", has been interfaced with "),e("code",null,"PerfChecker.jl"),n(". This section (will) provides some usage examples, documentation, and links to related notebooks.")],-1),l=[r,c];function i(d,h,m,_,k,p){return t(),a("div",null,l)}const u=o(s,[["render",i]]);export{f as __pageData,u as default}; diff --git a/dev/assets/perf_benchmark_ext.md.CVYCQYDt.lean.js b/dev/assets/perf_benchmark_ext.md.CVYCQYDt.lean.js deleted file mode 100644 index 95486ea..0000000 --- a/dev/assets/perf_benchmark_ext.md.CVYCQYDt.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,c as a,o as t,m as e,a as n}from"./chunks/framework.aA95Gx5L.js";const f=JSON.parse('{"title":"BenchmarkTools Extension","description":"","frontmatter":{},"headers":[],"relativePath":"perf/benchmark_ext.md","filePath":"perf/benchmark_ext.md","lastUpdated":null}'),s={name:"perf/benchmark_ext.md"},r=e("h1",{id:"BenchmarkTools-Extension",tabindex:"-1"},[n("BenchmarkTools Extension "),e("a",{class:"header-anchor",href:"#BenchmarkTools-Extension","aria-label":'Permalink to "BenchmarkTools Extension {#BenchmarkTools-Extension}"'},"​")],-1),c=e("p",null,[n("A benchmarking extension, based on "),e("code",null,"BenchmarkTools.jl"),n(", has been interfaced with "),e("code",null,"PerfChecker.jl"),n(". This section (will) provides some usage examples, documentation, and links to related notebooks.")],-1),l=[r,c];function i(d,h,m,_,k,p){return t(),a("div",null,l)}const u=o(s,[["render",i]]);export{f as __pageData,u as default}; diff --git a/dev/assets/perf_perf_checker.md.C3kXwfzJ.js b/dev/assets/perf_perf_checker.md.C3kXwfzJ.js deleted file mode 100644 index eff51d3..0000000 --- a/dev/assets/perf_perf_checker.md.C3kXwfzJ.js +++ /dev/null @@ -1,9 +0,0 @@ -import{_ as e,c as r,o as s,a7 as i}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"PerfChecker.jl","description":"","frontmatter":{},"headers":[],"relativePath":"perf/perf_checker.md","filePath":"perf/perf_checker.md","lastUpdated":null}'),a={name:"perf/perf_checker.md"},t=i(`

PerfChecker.jl

Documentation for PerfChecker.jl.

# PerfChecker.arrange_breakingMethod.

Outputs the last breaking or next breaking version.

source


# PerfChecker.arrange_majorMethod.

Outputs the earlier or next major version.

source


# PerfChecker.arrange_patchesMethod.

Outputs the last patch or first patch of a version.

source


# PerfChecker.get_pkg_versionsFunction.

Finds all versions of a package in all the installed registries and returns it as a vector.

Example:

julia
julia> get_pkg_versions("ConstraintLearning")
-7-element Vector{VersionNumber}:
- v"0.1.4"
- v"0.1.5"
- v"0.1.0"
- v"0.1.6"
- v"0.1.1"
- v"0.1.3"
- v"0.1.2"

source


`,10),n=[t];function l(o,p,h,k,c,d){return s(),r("div",null,n)}const g=e(a,[["render",l]]);export{b as __pageData,g as default}; diff --git a/dev/assets/perf_perf_checker.md.C3kXwfzJ.lean.js b/dev/assets/perf_perf_checker.md.C3kXwfzJ.lean.js deleted file mode 100644 index 6837f7a..0000000 --- a/dev/assets/perf_perf_checker.md.C3kXwfzJ.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as r,o as s,a7 as i}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"PerfChecker.jl","description":"","frontmatter":{},"headers":[],"relativePath":"perf/perf_checker.md","filePath":"perf/perf_checker.md","lastUpdated":null}'),a={name:"perf/perf_checker.md"},t=i("",10),n=[t];function l(o,p,h,k,c,d){return s(),r("div",null,n)}const g=e(a,[["render",l]]);export{b as __pageData,g as default}; diff --git a/dev/assets/perf_perf_interface.md.DaCOMv6z.js b/dev/assets/perf_perf_interface.md.DaCOMv6z.js deleted file mode 100644 index 9c49dff..0000000 --- a/dev/assets/perf_perf_interface.md.DaCOMv6z.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as r,c as t,o as a,m as e,a as n}from"./chunks/framework.aA95Gx5L.js";const P=JSON.parse('{"title":"Interfacing PerfChecker","description":"","frontmatter":{},"headers":[],"relativePath":"perf/perf_interface.md","filePath":"perf/perf_interface.md","lastUpdated":null}'),c={name:"perf/perf_interface.md"},f=e("h1",{id:"Interfacing-PerfChecker",tabindex:"-1"},[n("Interfacing PerfChecker "),e("a",{class:"header-anchor",href:"#Interfacing-PerfChecker","aria-label":'Permalink to "Interfacing PerfChecker {#Interfacing-PerfChecker}"'},"​")],-1),i=e("p",null,"PerfChecker was build as an easy to extend interface. This section will cover the few method required.",-1),s=[f,i];function o(d,h,l,_,p,m){return a(),t("div",null,s)}const u=r(c,[["render",o]]);export{P as __pageData,u as default}; diff --git a/dev/assets/perf_perf_interface.md.DaCOMv6z.lean.js b/dev/assets/perf_perf_interface.md.DaCOMv6z.lean.js deleted file mode 100644 index 9c49dff..0000000 --- a/dev/assets/perf_perf_interface.md.DaCOMv6z.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as r,c as t,o as a,m as e,a as n}from"./chunks/framework.aA95Gx5L.js";const P=JSON.parse('{"title":"Interfacing PerfChecker","description":"","frontmatter":{},"headers":[],"relativePath":"perf/perf_interface.md","filePath":"perf/perf_interface.md","lastUpdated":null}'),c={name:"perf/perf_interface.md"},f=e("h1",{id:"Interfacing-PerfChecker",tabindex:"-1"},[n("Interfacing PerfChecker "),e("a",{class:"header-anchor",href:"#Interfacing-PerfChecker","aria-label":'Permalink to "Interfacing PerfChecker {#Interfacing-PerfChecker}"'},"​")],-1),i=e("p",null,"PerfChecker was build as an easy to extend interface. This section will cover the few method required.",-1),s=[f,i];function o(d,h,l,_,p,m){return a(),t("div",null,s)}const u=r(c,[["render",o]]);export{P as __pageData,u as default}; diff --git a/dev/assets/public_api.md.ByXB8t1V.js b/dev/assets/public_api.md.ByXB8t1V.js deleted file mode 100644 index bef9d26..0000000 --- a/dev/assets/public_api.md.ByXB8t1V.js +++ /dev/null @@ -1,16 +0,0 @@ -import{_ as i,c as s,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"Public API","description":"","frontmatter":{},"headers":[],"relativePath":"public_api.md","filePath":"public_api.md","lastUpdated":null}'),e={name:"public_api.md"},n=t(`

Public API

# ConstraintCommons.AutomatonType.
julia
Automaton{S, T, F <: Union{S, Vector{S}, Set{S}}} <: AbstractAutomaton

A minimal implementation of a deterministic automaton structure.

source


# ConstraintCommons.MDDType.
julia
MDD{S,T} <: AbstractMultivaluedDecisionDiagram

A minimal implementation of a multivalued decision diagram structure.

source


# ConstraintCommons.acceptMethod.
julia
accept(a::Union{Automaton, MDD}, w)

Return true if a accepts the word w and false otherwise.

source


# ConstraintCommons.extract_parametersMethod.
julia
extract_parameters(m::Union{Method, Function}; parameters)

Extracts the intersection between the kargs of m and parameters (defaults to USUAL_CONSTRAINT_PARAMETERS).

source


# ConstraintCommons.incsert!Function.
julia
incsert!(d::Union{AbstractDict, AbstractDictionary}, ind, val = 1)

Increase or insert a counter in a dictionary-based collection. The counter insertion defaults to val = 1.

source


# ConstraintCommons.oversampleMethod.
julia
oversample(X, f)

Oversample elements of X until the boolean function f has as many true and false configurations.

source


# ConstraintCommons.symconFunction.
julia
Base.:*(s1::Symbol, s2::Symbol, connector::AbstractString="_")

Extends * to Symbols multiplication by connecting the symbols by an _.

source


# ConstraintCommons.δ_extremaMethod.
julia
δ_extrema(X...)

Compute both the difference between the maximum and the minimum of over all the collections of X.

source


# ConstraintDomains.AbstractDomainType.
julia
AbstractDomain

An abstract super type for any domain type. A domain type D <: AbstractDomain must implement the following methods to properly interface AbstractDomain.

  • Base.∈(val, ::D)

  • Base.rand(::D)

  • Base.length(::D) that is the number of elements in a discrete domain, and the distance between bounds or similar for a continuous domain

Additionally, if the domain is used in a dynamic context, it can extend

  • add!(::D, args)

  • delete!(::D, args)

where args depends on D's structure

source


# ConstraintDomains.ContinuousDomainType.
julia
ContinuousDomain{T <: Real} <: AbstractDomain

An abstract supertype for all continuous domains.

source


# ConstraintDomains.DiscreteDomainType.
julia
DiscreteDomain{T <: Number} <: AbstractDomain

An abstract supertype for discrete domains (set, range).

source


# ConstraintDomains.ExploreSettingsMethod.
julia
ExploreSettings(
-    domains;
-    complete_search_limit = 10^6,
-    max_samplings = sum(domain_size, domains),
-    search = :flexible,
-    solutions_limit = floor(Int, sqrt(max_samplings)),
-)

Settings for the exploration of a search space composed by a collection of domains.

source


# ConstraintDomains.RangeDomainType.
julia
RangeDomain

A discrete domain defined by a range <: AbstractRange{Real}. As ranges are immutable in Julia, changes in RangeDomain must use set_domain!.

source


# Base.delete!Method.
julia
Base.delete!(d::SetDomain, value)(d::SetDomain, value)

Delete value from the list of points in d.

source


# ConstraintDomains.add!Method.
julia
add!(d::SetDomain, value)

Add value to the list of points in d.

source


# ConstraintDomains.domainMethod.
julia
domain(values)
-domain(range::R) where {T <: Real, R <: AbstractRange{T}}

Construct either a SetDomain or a \`RangeDomain\`\`.

julia
d1 = domain(1:5)
-d2 = domain([53.69, 89.2, 0.12])
-d3 = domain([2//3, 89//123])
-d4 = domain(4.3)
-d5 = domain(1,42,86.9)

source


# ConstraintDomains.domainMethod.
julia
domain()

Construct an EmptyDomain.

source


# ConstraintDomains.domainMethod.
julia
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
-domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}

Construct a domain of continuous interval(s).

source


# ConstraintDomains.domain_sizeMethod.
julia
domain_size(itv::Intervals)

Return the difference between the highest and lowest values in itv.

source


# ConstraintDomains.domain_sizeMethod.
julia
domain_size(d <: AbstractDomain)

Fallback method for domain_size(d) that return length(d).

source


# ConstraintDomains.domain_sizeMethod.
julia
domain_size(d::D) where D <: DiscreteDomain

Return the maximum distance between two points in d.

source


# ConstraintDomains.exploreMethod.
julia
explore(domains, concept, param = nothing; search_limit = 1000, solutions_limit = 100)

Search (a part of) a search space and returns a pair of vector of configurations: (solutions, non_solutions). If the search space size is over search_limit, then both solutions and non_solutions are limited to solutions_limit.

Beware that if the density of the solutions in the search space is low, solutions_limit needs to be reduced. This process will be automatic in the future (simple reinforcement learning).

Arguments:

  • domains: a collection of domains

  • concept: the concept of the targeted constraint

  • param: an optional parameter of the constraint

  • sol_number: the required number of solutions (half of the number of configurations), default to 100

source


# ConstraintDomains.generate_parametersMethod.
julia
generate_parameters(d<:AbstractDomain, param)

Generates random parameters based on the domain d and the kind of parameters param.

source


# ConstraintDomains.get_domainMethod.
julia
get_domain(::AbstractDomain)

Access the internal structure of any domain type.

source


# ConstraintDomains.intersect_domainsMethod.
julia
intersect_domains(d₁, d₂)

Compute the intersections of two domains.

source


# ConstraintDomains.merge_domainsMethod.
julia
merge_domains(d₁::AbstractDomain, d₂::AbstractDomain)

Merge two domains of same nature (discrete/contiuous).

source


# ConstraintDomains.to_domainsMethod.
julia
to_domains(args...)

Convert various arguments into valid domains format.

source


# Constraints.USUAL_CONSTRAINTSConstant.
julia
USUAL_CONSTRAINTS::Dict

Dictionary that contains all the usual constraints defined in Constraint.jl. It is based on XCSP3-core specifications available at https://arxiv.org/abs/2009.00514

Adding a new constraint is as simple as defining a new function with the same name as the constraint and using the @usual macro to define it. The macro will take care of adding the new constraint to the USUAL_CONSTRAINTS dictionary.

Example

julia
@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals)

source


# Constraints.USUAL_SYMMETRIESConstant.
julia
USUAL_SYMMETRIES

A Dictionary that contains the function to apply for each symmetry to avoid searching a whole space.

source


# Constraints.ConstraintType.
julia
Constraint

Parametric structure with the following fields.

  • concept: a Boolean function that, given an assignment x, outputs true if x satisfies the constraint, and false otherwise.

  • error: a positive function that works as preferences over invalid assignments. Return 0.0 if the constraint is satisfied, and a strictly positive real otherwise.

source


# ConstraintCommons.extract_parametersFunction.
julia
extract_parameters(s::Symbol, constraints_dict=USUAL_CONSTRAINTS; parameters=ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS)

Return the parameters of the constraint s in constraints_dict.

Arguments

  • s::Symbol: the constraint name.

  • constraints_dict::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

  • parameters::Vector{Symbol}: vector of parameters. Default is ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS.

Example

julia
extract_parameters(:all_different)

source


# Constraints.argsMethod.
julia
args(c::Constraint)

Return the expected length restriction of the arguments in a constraint c. The value nothing indicates that any strictly positive number of value is accepted.

source


# Constraints.conceptMethod.
julia
concept(c::Constraint)

Return the concept (function) of constraint c. concept(c::Constraint, x...; param = nothing) Apply the concept of c to values x and optionally param.

source


# Constraints.conceptMethod.
julia
concept(s::Symbol, args...; kargs...)

Return the concept of the constraint s applied to args and kargs. This is a shortcut for concept(USUAL_CONSTRAINTS[s])(args...; kargs...).

Arguments

  • s::Symbol: the constraint name.

  • args...: the arguments to apply the concept to.

  • kargs...: the keyword arguments to apply the concept to.

Example

julia
concept(:all_different, [1, 2, 3])

source


# Constraints.constraints_descriptionsFunction.
julia
constraints_descriptions(C=USUAL_CONSTRAINTS)

Return a pretty table with the descriptions of the constraints in C.

Arguments

  • C::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

Example

julia
constraints_descriptions()

source


# Constraints.constraints_parametersFunction.
julia
constraints_parameters(C=USUAL_CONSTRAINTS)

Return a pretty table with the parameters of the constraints in C.

Arguments

  • C::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

Example

julia
constraints_parameters()

source


# Constraints.describeFunction.
julia
describe(constraints::Dict{Symbol,Constraint}=USUAL_CONSTRAINTS; width=150)

Return a pretty table with the description of the constraints in constraints.

Arguments

  • constraints::Dict{Symbol,Constraint}: dictionary of constraints to describe. Default is USUAL_CONSTRAINTS.

  • width::Int: width of the table.

Example

julia
describe()

source


# Constraints.error_fMethod.
julia
error_f(c::Constraint)

Return the error function of constraint c. error_f(c::Constraint, x; param = nothing) Apply the error function of c to values x and optionally param.

source


# Constraints.params_lengthMethod.
julia
params_length(c::Constraint)

Return the expected length restriction of the arguments in a constraint c. The value nothing indicates that any strictly positive number of parameters is accepted.

source


# Constraints.symmetriesMethod.
julia
symmetries(c::Constraint)

Return the list of symmetries of c.

source


# CompositionalNetworks.CompositionMethod.
julia
Composition(f::F, symbols) where {F<:Function}

Construct a Composition.

source


# CompositionalNetworks.CompositionType.
julia
struct Composition{F<:Function}

Store the all the information of a composition learned by an ICN.

source


# CompositionalNetworks.ICNType.
julia
ICN(; nvars, dom_size, param, transformation, arithmetic, aggregation, comparison)

Construct an Interpretable Compositional Network, with the following arguments:

  • nvars: number of variable in the constraint

  • dom_size: maximum domain size of any variable in the constraint

  • param: optional parameter (default to nothing)

  • transformation: a transformation layer (optional)

  • arithmetic: a arithmetic layer (optional)

  • aggregation: a aggregation layer (optional)

  • comparison: a comparison layer (optional)

source


# CompositionalNetworks.aggregation_layerMethod.
julia
aggregation_layer()

Generate the layer of aggregations of the ICN. The operations are mutually exclusive, that is only one will be selected.

source


# CompositionalNetworks.arithmetic_layerMethod.
julia
arithmetic_layer()

Generate the layer of arithmetic operations of the ICN. The operations are mutually exclusive, that is only one will be selected.

source


# CompositionalNetworks.codeFunction.
julia
code(c::Composition, lang=:maths; name="composition")

Access the code of a composition c in a given language lang. The name of the generated method is optional.

source


# CompositionalNetworks.comparison_layerFunction.
julia
comparison_layer(param = false)

Generate the layer of transformations functions of the ICN. Iff param value is set, also includes all the parametric comparison with that value. The operations are mutually exclusive, that is only one will be selected.

source


# CompositionalNetworks.composeFunction.
julia
compose(icn, weights=nothing)

Return a function composed by some of the operations of a given ICN. Can be applied to any vector of variables. If weights are given, will assign to icn.

source


# CompositionalNetworks.compose_to_file!Method.
julia
compose_to_file!(concept, name, path; domains, param = nothing, language = :Julia, search = :complete, global_iter = 10, local_iter = 100, metric = hamming, popSize = 200)

Explore, learn and compose a function and write it to a file.

Arguments:

  • concept: the concept to learn

  • name: the name to give to the constraint

  • path: path of the output file

Keywords arguments:

  • domains: domains that defines the search space

  • param: an optional parameter of the constraint

  • language: the language to export to, default to :julia

  • search: either :partial or :complete search

  • global_iter: number of learning iteration

  • local_iter: number of generation in the genetic algorithm

  • metric: the metric to measure the distance between a configuration and known solutions

  • popSize: size of the population in the genetic algorithm

source


# CompositionalNetworks.compositionMethod.
julia
composition(c::Composition)

Access the actual method of an ICN composition c.

source


# CompositionalNetworks.composition_to_file!Function.
julia
composition_to_file!(c::Composition, path, name, language=:Julia)

Write the composition code in a given language into a file at path.

source


# CompositionalNetworks.explore_learn_composeMethod.
julia
explore_learn_compose(concept; domains, param = nothing, search = :complete, global_iter = 10, local_iter = 100, metric = hamming, popSize = 200, action = :composition)

Explore a search space, learn a composition from an ICN, and compose an error function.

Arguments:

  • concept: the concept of the targeted constraint

  • domains: domains of the variables that define the training space

  • param: an optional parameter of the constraint

  • search: either flexible,:partial or :complete search. Flexible search will use search_limit and solutions_limit to determine if the search space needs to be partially or completely explored

  • global_iter: number of learning iteration

  • local_iter: number of generation in the genetic algorithm

  • metric: the metric to measure the distance between a configuration and known solutions

  • popSize: size of the population in the genetic algorithm

  • action: either :symbols to have a description of the composition or :composition to have the composed function itself

source


# CompositionalNetworks.hammingMethod.
julia
hamming(x, X)

Compute the hamming distance of x over a collection of solutions X, i.e. the minimal number of variables to switch in xto reach a solution.

source


# CompositionalNetworks.lazyMethod.
julia
lazy(funcs::Function...)

Generate methods extended to a vector instead of one of its components. A function f should have the following signature: f(i::Int, x::V).

source


# CompositionalNetworks.lazy_paramMethod.
julia
lazy_param(funcs::Function...)

Generate methods extended to a vector instead of one of its components. A function f should have the following signature: f(i::Int, x::V; param).

source


# CompositionalNetworks.learn_composeMethod.
julia
learn_compose(;
-    nvars, dom_size, param=nothing, icn=ICN(nvars, dom_size, param),
-    X, X_sols, global_iter=100, local_iter=100, metric=hamming, popSize=200
-)

Create an ICN, optimize it, and return its composition.

source


# CompositionalNetworks.manhattanMethod.
julia
manhattan(x, X)

source


# CompositionalNetworks.minkowskiMethod.
julia
minkowski(x, X, p)

source


# CompositionalNetworks.nbitsMethod.
julia
nbits(icn)

Return the expected number of bits of a viable weight of an ICN.

source


# CompositionalNetworks.regularizationMethod.
julia
regularization(icn)

Return the regularization value of an ICN weights, which is proportional to the normalized number of operations selected in the icn layers.

source


# CompositionalNetworks.show_layersMethod.
julia
show_layers(icn)

Return a formatted string with each layers in the icn.

source


# CompositionalNetworks.symbolsMethod.
julia
symbols(c::Composition)

Output the composition as a layered collection of Symbols.

source


# CompositionalNetworks.transformation_layerFunction.
julia
transformation_layer(param = false)

Generate the layer of transformations functions of the ICN. Iff param value is true, also includes all the parametric transformations.

source


# CompositionalNetworks.weights!Method.
julia
weights!(icn, weights)

Set the weights of an ICN with a BitVector.

source


# CompositionalNetworks.weightsMethod.
julia
weights(icn)

Access the current set of weights of an ICN.

source


# CompositionalNetworks.weights_biasMethod.
julia
weights_bias(x)

A metric that bias x towards operations with a lower bit. Do not affect the main metric.

source


# QUBOConstraints.QUBO_linear_sumMethod.
julia
QUBO_linear_sum(n, σ)

One valid QUBO matrix given n variables and parameter σ for the linear sum constraint.

source


# QUBOConstraints.binarizeMethod.
julia
binarize(x[, domain]; binarization = :one_hot)

Binarize x following the binarization encoding. If x is a vector (instead of a number per say), domain is optional.

source


# QUBOConstraints.debinarizeMethod.
julia
debinarize(x[, domain]; binarization = :one_hot)

Transform a binary vector into a number or a set of number. If domain is not given, it will compute a default value based on binarization and x.

source


# QUBOConstraints.is_validFunction.
julia
is_valid(x, encoding::Symbol = :none)

Check if x has a valid format for encoding.

For instance, if encoding == :one_hot, at most one bit of x can be set to 1.

source


# QUBOConstraints.trainMethod.
julia
train(args...)

Default train method for any AbstractOptimizer.

source


`,143),o=[n];function l(r,p,h,d,c,k){return a(),s("div",null,o)}const g=i(e,[["render",l]]);export{b as __pageData,g as default}; diff --git a/dev/assets/public_api.md.ByXB8t1V.lean.js b/dev/assets/public_api.md.ByXB8t1V.lean.js deleted file mode 100644 index b3693c3..0000000 --- a/dev/assets/public_api.md.ByXB8t1V.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as s,o as a,a7 as t}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"Public API","description":"","frontmatter":{},"headers":[],"relativePath":"public_api.md","filePath":"public_api.md","lastUpdated":null}'),e={name:"public_api.md"},n=t("",143),o=[n];function l(r,p,h,d,c,k){return a(),s("div",null,o)}const g=i(e,[["render",l]]);export{b as __pageData,g as default}; diff --git a/dev/assets/solvers_cbls.md.BxYapv-Y.js b/dev/assets/solvers_cbls.md.BxYapv-Y.js deleted file mode 100644 index dd8bb42..0000000 --- a/dev/assets/solvers_cbls.md.BxYapv-Y.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as s,o as a,a7 as e}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"CBLS.jl","description":"","frontmatter":{},"headers":[],"relativePath":"solvers/cbls.md","filePath":"solvers/cbls.md","lastUpdated":null}'),t={name:"solvers/cbls.md"},l=e('

CBLS.jl

Documentation for CBLS.jl.

# CBLS.AllDifferentType.

Global constraint ensuring that all the values of a given configuration are unique.

julia
@constraint(model, X in AllDifferent())

source


# CBLS.AllEqualType.

Global constraint ensuring that all the values of X are all equal.

julia
@constraint(model, X in AllEqual())

source


# CBLS.AllEqualParamType.

Global constraint ensuring that all the values of X are all equal to a given parameter param.

julia
@constraint(model, X in AllEqualParam(param))

source


# CBLS.AlwaysTrueType.

Always return true. Mainly used for testing purpose.

julia
@constraint(model, X in AlwaysTrue())

source


# CBLS.DiscreteSetType.
julia
DiscreteSet(values)

source


# CBLS.DistDifferentType.

Local constraint ensuring that, given a vector X of size 4, |X[1] - X[2]| ≠ |X[3] - X[4]|).

julia
@constraint(model, X in DistDifferent())

source


# CBLS.EqType.

Equality between two variables.

julia
@constraint(model, X in Eq())

source


# CBLS.ErrorType.
julia
Error{F <: Function} <: JuMP.AbstractVectorSet

The solver will compute a straightforward error function based on the concept. To run the solver efficiently, it is possible to provide an error function err instead of concept. err must return a nonnegative real number.

julia
@constraint(model, X in Error(err))

source


# CBLS.LessThanParamType.

Constraint ensuring that the value of x is less than a given parameter param.

julia
@constraint(model, x in LessThanParam(param))

source


# CBLS.MOIAllDifferentType.
julia
MOIAllDifferent <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOIAllEqualType.
julia
MOIAllEqual <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOIAllEqualParamType.
julia
MOIAllEqualParam{T <: Number} <: MOI.AbstractVectorSet

DOCSTRING

Arguments:

  • param::T: DESCRIPTION

  • dimension::Int: DESCRIPTION

  • MOIAllEqualParam(param, dim = 0) = begin #= none:5 =# new{typeof(param)}(param, dim) end: DESCRIPTION

source


# CBLS.MOIAlwaysTrueType.
julia
MOIAlwaysTrue <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOIDistDifferentType.
julia
MOIDistDifferent <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOIEqType.
julia
MOIEq <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOIErrorType.
julia
MOIError{F <: Function} <: MOI.AbstractVectorSet

DOCSTRING

Arguments:

  • f::F: DESCRIPTION

  • dimension::Int: DESCRIPTION

  • MOIError(f, dim = 0) = begin #= none:5 =# new{typeof(f)}(f, dim) end: DESCRIPTION

source


# CBLS.MOILessThanParamType.
julia
MOILessThanParam{T <: Number} <: MOI.AbstractVectorSet

DOCSTRING

Arguments:

  • param::T: DESCRIPTION

  • dimension::Int: DESCRIPTION

  • MOILessThanParam(param, dim = 0) = begin #= none:5 =# new{typeof(param)}(param, dim) end: DESCRIPTION

source


# CBLS.MOIMinusEqualParamType.
julia
MOIMinusEqualParam{T <: Number} <: MOI.AbstractVectorSet

DOCSTRING

Arguments:

  • param::T: DESCRIPTION

  • dimension::Int: DESCRIPTION

  • MOIMinusEqualParam(param, dim = 0) = begin #= none:5 =# new{typeof(param)}(param, dim) end: DESCRIPTION

source


# CBLS.MOIOrderedType.
julia
MOIOrdered <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOIPredicateType.
julia
MOIPredicate{F <: Function} <: MOI.AbstractVectorSet

DOCSTRING

Arguments:

  • f::F: DESCRIPTION

  • dimension::Int: DESCRIPTION

  • MOIPredicate(f, dim = 0) = begin #= none:5 =# new{typeof(f)}(f, dim) end: DESCRIPTION

source


# CBLS.MOISequentialTasksType.
julia
MOISequentialTasks <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOISumEqualParamType.
julia
MOISumEqualParam{T <: Number} <: MOI.AbstractVectorSet

DOCSTRING

Arguments:

  • param::T: DESCRIPTION

  • dimension::Int: DESCRIPTION

  • MOISumEqualParam(param, dim = 0) = begin #= none:5 =# new{typeof(param)}(param, dim) end: DESCRIPTION

source


# CBLS.MinusEqualParamType.

Constraint ensuring that the value of x is less than a given parameter param.

julia
@constraint(model, x in MinusEqualParam(param))

source


# CBLS.OptimizerType.
julia
Optimizer(model = Model(); options = Options())

DOCSTRING

source


# CBLS.OptimizerType.
julia
Optimizer <: MOI.AbstractOptimizer

DOCSTRING

Arguments:

  • solver::Solver: DESCRIPTION

  • status::MOI.TerminationStatusCode: DESCRIPTION

  • options::Options: DESCRIPTION

source


# CBLS.OrderedType.

Global constraint ensuring that all the values of x are ordered.

julia
@constraint(model, X in Ordered())

source


# CBLS.PredicateType.
julia
Predicate{F <: Function} <: JuMP.AbstractVectorSet

Assuming X is a (collection of) variables, concept a boolean function over X, and that a model is defined. In JuMP syntax we can create a constraint based on concept as follows.

julia
@constraint(model, X in Predicate(concept))

source


# CBLS.ScalarFunctionType.
julia
ScalarFunction{F <: Function, V <: Union{Nothing, VOV}} <: MOI.AbstractScalarFunction

A container to express any function with real value in JuMP syntax. Used with the @objective macro.

Arguments:

  • f::F: function to be applied to X

  • X::V: a subset of the variables of the model.

Given a model, and some (collection of) variables X to optimize. an objective function f can be added as follows. Note that only Min for minimization us currently defined. Max will come soon.

julia
# Applies to all variables in order of insertion.\n# Recommended only when the function argument order does not matter.\n@objective(model, ScalarFunction(f))\n\n# Generic use\n@objective(model, ScalarFunction(f, X))

source


# CBLS.SequentialTasksType.

Local constraint ensuring that, given a vector X of size 4, |X[1] - X[2]| ≠ |X[3] - X[4]|).

julia
@constraint(model, X in SequentialTasks())

source


# CBLS.SumEqualParamType.

Global constraint ensuring that the sum of the values of X is equal to a given parameter param.

julia
@constraint(model, X in SumEqualParam(param))

source


# Base.copyMethod.
julia
Base.copy(set::MOIError) = begin

DOCSTRING

source


# Base.copyMethod.
julia
Base.copy(set::DiscreteSet) = begin

DOCSTRING

source


# JuMP.build_variableMethod.
julia
JuMP.build_variable(::Function, info::JuMP.VariableInfo, set::T) where T <: MOI.AbstractScalarSet

DOCSTRING

Arguments:

  • ``: DESCRIPTION

  • info: DESCRIPTION

  • set: DESCRIPTION

source


# MathOptInterface.add_constraintMethod.
julia
MOI.add_constraint(optimizer::Optimizer, vars::MOI.VectorOfVariables, set::MOIError)

DOCSTRING

Arguments:

  • optimizer: DESCRIPTION

  • vars: DESCRIPTION

  • set: DESCRIPTION

source


# MathOptInterface.add_constraintMethod.
julia
MOI.add_constraint(optimizer::Optimizer, v::VI, set::DiscreteSet{T}) where T <: Number

DOCSTRING

Arguments:

  • optimizer: DESCRIPTION

  • v: DESCRIPTION

  • set: DESCRIPTION

source


# MathOptInterface.add_variableMethod.
julia
MOI.add_variable(model::Optimizer) = begin

DOCSTRING

source


# MathOptInterface.empty!Method.
julia
MOI.empty!(opt) = begin

DOCSTRING

source


# MathOptInterface.getMethod.
julia
MOI.get(::Optimizer, ::MOI.SolverName) = begin

DOCSTRING

source


# MathOptInterface.is_emptyMethod.
julia
MOI.is_empty(model::Optimizer) = begin

DOCSTRING

source


# MathOptInterface.optimize!Method.
julia
MOI.optimize!(model::Optimizer)

source


# MathOptInterface.setFunction.
julia
MOI.set(::Optimizer, ::MOI.Silent, bool = true) = begin

DOCSTRING

Arguments:

  • ``: DESCRIPTION

  • ``: DESCRIPTION

  • bool: DESCRIPTION

source


# MathOptInterface.setMethod.
julia
MOI.set(model::Optimizer, p::MOI.RawOptimizerAttribute, value)

Set a RawOptimizerAttribute to value

source


# MathOptInterface.setMethod.
julia
MOI.set(model::Optimizer, ::MOI.TimeLimitSec, value::Union{Nothing,Float64})

Set the time limit

source


# MathOptInterface.supports_constraintMethod.
julia
MOI.supports_constraint(::Optimizer, ::Type{VOV}, ::Type{MOIError}) = begin

DOCSTRING

Arguments:

  • ``: DESCRIPTION

  • ``: DESCRIPTION

  • ``: DESCRIPTION

source


# MathOptInterface.supports_incremental_interfaceMethod.

Copy constructor for the optimizer

source


',92),r=[l];function p(n,h,d,o,k,c){return a(),s("div",null,r)}const g=i(t,[["render",p]]);export{b as __pageData,g as default}; diff --git a/dev/assets/solvers_cbls.md.BxYapv-Y.lean.js b/dev/assets/solvers_cbls.md.BxYapv-Y.lean.js deleted file mode 100644 index cabdc8d..0000000 --- a/dev/assets/solvers_cbls.md.BxYapv-Y.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as i,c as s,o as a,a7 as e}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"CBLS.jl","description":"","frontmatter":{},"headers":[],"relativePath":"solvers/cbls.md","filePath":"solvers/cbls.md","lastUpdated":null}'),t={name:"solvers/cbls.md"},l=e("",92),r=[l];function p(n,h,d,o,k,c){return a(),s("div",null,r)}const g=i(t,[["render",p]]);export{b as __pageData,g as default}; diff --git a/dev/assets/solvers_intro.md.BOddHRCt.js b/dev/assets/solvers_intro.md.BOddHRCt.js deleted file mode 100644 index 2e28887..0000000 --- a/dev/assets/solvers_intro.md.BOddHRCt.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as t,c as o,o as s,m as e,a as r}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"Solvers","description":"","frontmatter":{},"headers":[],"relativePath":"solvers/intro.md","filePath":"solvers/intro.md","lastUpdated":null}'),a={name:"solvers/intro.md"},l=e("h1",{id:"Solvers",tabindex:"-1"},[r("Solvers "),e("a",{class:"header-anchor",href:"#Solvers","aria-label":'Permalink to "Solvers {#Solvers}"'},"​")],-1),n=e("p",null,"About solvers.",-1),c=[l,n];function i(d,_,p,v,h,m){return s(),o("div",null,c)}const S=t(a,[["render",i]]);export{u as __pageData,S as default}; diff --git a/dev/assets/solvers_intro.md.BOddHRCt.lean.js b/dev/assets/solvers_intro.md.BOddHRCt.lean.js deleted file mode 100644 index 2e28887..0000000 --- a/dev/assets/solvers_intro.md.BOddHRCt.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as t,c as o,o as s,m as e,a as r}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"Solvers","description":"","frontmatter":{},"headers":[],"relativePath":"solvers/intro.md","filePath":"solvers/intro.md","lastUpdated":null}'),a={name:"solvers/intro.md"},l=e("h1",{id:"Solvers",tabindex:"-1"},[r("Solvers "),e("a",{class:"header-anchor",href:"#Solvers","aria-label":'Permalink to "Solvers {#Solvers}"'},"​")],-1),n=e("p",null,"About solvers.",-1),c=[l,n];function i(d,_,p,v,h,m){return s(),o("div",null,c)}const S=t(a,[["render",i]]);export{u as __pageData,S as default}; diff --git a/dev/assets/solvers_local_search_solvers.md.BuFLqJZe.js b/dev/assets/solvers_local_search_solvers.md.BuFLqJZe.js deleted file mode 100644 index a62c39d..0000000 --- a/dev/assets/solvers_local_search_solvers.md.BuFLqJZe.js +++ /dev/null @@ -1,36 +0,0 @@ -import{_ as s,c as i,o as a,a7 as e}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"LocalSearchSolvers.jl","description":"","frontmatter":{},"headers":[],"relativePath":"solvers/local_search_solvers.md","filePath":"solvers/local_search_solvers.md","lastUpdated":null}'),l={name:"solvers/local_search_solvers.md"},t=e(`

LocalSearchSolvers.jl

Documentation for LocalSearchSolvers.jl.

# LocalSearchSolvers.AbstractSolverType.
julia
AbstractSolver

Abstract type to encapsulate the different solver types such as Solver or _SubSolver.

source


# LocalSearchSolvers.ConstraintType.
julia
Constraint{F <: Function}

Structure to store an error function and the variables it constrains.

source


# LocalSearchSolvers.LeadSolverType.
julia
LeadSolver <: MetaSolver

Solver managed remotely by a MainSolver. Can manage its own set of local sub solvers.

source


# LocalSearchSolvers.MainSolverType.
julia
MainSolver <: AbstractSolver

Main solver. Handle the solving of a model, and optional multithreaded and/or distributed subsolvers.

Arguments:

  • model::Model: A formal description of the targeted problem

  • state::_State: An internal state to store the info necessary to a solving run

  • options::Options: User options for this solver

  • subs::Vector{_SubSolver}: Optional subsolvers

source


# LocalSearchSolvers.MetaSolverType.

Abstract type to encapsulate all solver types that manages other solvers.

source


# LocalSearchSolvers.ObjectiveType.
julia
Objective{F <: Function}

A structure to handle objectives in a solver. \`struct Objective{F <: Function} name::String f::F end\`\`

source


# LocalSearchSolvers.ObjectiveMethod.
julia
Objective(F, o::Objective{F2}) where {F2 <: Function}

Constructor used in specializing a solver. Should never be called externally.

source


# LocalSearchSolvers.OptionsType.
julia
Options()

Arguments:

  • dynamic::Bool: is the model dynamic?

  • iteration::Union{Int, Float64}: limit on the number of iterations

  • print_level::Symbol: verbosity to choose among :silent, :minimal, :partial, :verbose

  • solutions::Int: number of solutions to return

  • specialize::Bool: should the types of the model be specialized or not. Usually yes for static problems. For dynamic in depends if the user intend to introduce new types. The specialized model is about 10% faster.

  • tabu_time::Int: DESCRIPTION

  • tabu_local::Int: DESCRIPTION

  • tabu_delta::Float64: DESCRIPTION

  • threads::Int: Number of threads to use

  • time_limit::Float64: time limit in seconds

  • \`function Options(; dynamic = false, iteration = 10000, print_level = :minimal, solutions = 1, specialize = !dynamic, tabu_time = 0, tabu_local = 0, tabu_delta = 0.0, threads = typemax(0), time_limit = Inf)

julia
# Setting options in JuMP syntax: print_level, time_limit, iteration
-model = Model(CBLS.Optimizer)
-set_optimizer_attribute(model, "iteration", 100)
-set_optimizer_attribute(model, "print_level", :verbose)
-set_time_limit_sec(model, 5.0)

source


# LocalSearchSolvers.VariableType.
julia
Variable{D <: AbstractDomain}

A structure containing the necessary information for a solver's variables: name, domain, and constraints it belongs.

struct Variable{D <: AbstractDomain}
-    domain::D
-    constraints::Indices{Int}
-end

source


# LocalSearchSolvers._ModelType.
julia
_Model{V <: Variable{<:AbstractDomain},C <: Constraint{<:Function},O <: Objective{<:Function}}

A struct to model a problem as a set of variables, domains, constraints, and objectives.

struct _Model{V <: Variable{<:AbstractDomain},C <: Constraint{<:Function},O <: Objective{<:Function}}
-    variables::Dictionary{Int,V}
-    constraints::Dictionary{Int,C}
-    objectives::Dictionary{Int,O}
-
-    # counter to add new variables: vars, cons, objs
-    max_vars::Ref{Int}
-    max_cons::Ref{Int}
-    max_objs::Ref{Int}
-
-    # Bool to indicate if the _Model instance has been specialized (relatively to types)
-    specialized::Ref{Bool}
-
-    # Symbol to indicate the kind of model for specialized methods such as pretty printing
-    kind::Symbol
-end

source


# LocalSearchSolvers._StateType.
julia
GeneralState{T <: Number}

A mutable structure to store the general state of a solver. All methods applied to GeneralState are forwarded to S <: AbstractSolver.

mutable struct GeneralState{T <: Number} <: AbstractState
-    configuration::Configuration{T}
-    cons_costs::Dictionary{Int, Float64}
-    last_improvement::Int
-    tabu::Dictionary{Int, Int}
-    vars_costs::Dictionary{Int, Float64}
-end

source


# LocalSearchSolvers._SubSolverType.
julia
_SubSolver <: AbstractSolver

An internal solver type called by MetaSolver when multithreading is enabled.

Arguments:

  • id::Int: subsolver id for debugging

  • model::Model: a ref to the model of the main solver

  • state::_State: a deepcopy of the main solver that evolves independently

  • options::Options: a ref to the options of the main solver

source


# Base.empty!Method.
julia
empty!(s::Solver)

source


# Base.empty!Method.
julia
empty!(m::Model)

DOCSTRING

source


# Base.inMethod.
julia
var::Int c::Constraint

source


# Base.inMethod.
julia
x::Variable constraint
-value  x::Variable

Check if a variable x is restricted by a constraint::Int, or if a value belongs to the domain of x.

source


# LocalSearchSolvers._add!Method.
julia
_add!(c::Constraint, x)

Add the variable of indice x to c.

source


# LocalSearchSolvers._add_to_constraint!Method.
julia
_add_to_constraint!(x::Variable, id)

Add a constraint id to the list of constraints of x.

source


# LocalSearchSolvers._check_restartMethod.
julia
_check_restart(s)

Check if a restart of s is necessary. If s has subsolvers, this check is independent for all of them.

source


# LocalSearchSolvers._check_subsMethod.
julia
_check_subs(s)

Check if any subsolver of a main solver s, for

  • Satisfaction, has a solution, then return it, resume the run otherwise

  • Optimization, has a better solution, then assign it to its internal state

source


# LocalSearchSolvers._compute!Method.
julia
_compute!(s; o::Int = 1, cons_lst = Indices{Int}())

Compute the objective o's value if s is satisfied and return the current error.

Arguments:

  • s: a solver

  • o: targeted objective

  • cons_lst: list of targeted constraints, if empty compute for the whole set

source


# LocalSearchSolvers._compute_cost!Method.
julia
_compute_cost!(s, ind, c)

Compute the cost of constraint c with index ind.

source


# LocalSearchSolvers._compute_costs!Method.
julia
_compute_costs!(s; cons_lst::Indices{Int} = Indices{Int}())

Compute the cost of constraints c in cons_lst. If cons_lst is empty, compute the cost for all the constraints in s.

source


# LocalSearchSolvers._compute_objective!Method.
julia
_compute_objective!(s, o::Objective)
-_compute_objective!(s, o = 1)

Compute the objective o's value.

source


# LocalSearchSolvers._cons_cost!Method.
julia
_cons_cost!(s::S, c, cost) where S <: Union{_State, AbstractSolver}

Set the cost of constraint c.

source


# LocalSearchSolvers._cons_costMethod.
julia
_cons_cost(s::S, c) where S <: Union{_State, AbstractSolver}

Return the cost of constraint c.

source


# LocalSearchSolvers._cons_costs!Method.
julia
_cons_costs!(s::S, costs) where S <: Union{_State, AbstractSolver}

Set the constraints costs.

source


# LocalSearchSolvers._cons_costsMethod.
julia
_cons_costs(s::S) where S <: Union{_State, AbstractSolver}

Access the constraints costs.

source


# LocalSearchSolvers._constrictionMethod.
julia
_constriction(x::Variable)

Return the cosntriction of x, i.e. the number of constraints restricting x.

source


# LocalSearchSolvers._delete!Method.
julia
_delete!(c::Constraint, x::Int)

Delete x from c.

source


# LocalSearchSolvers._delete_from_constraint!Method.
julia
_delete_from_constraint!(x::Variable, id)

Delete a constraint id from the list of constraints of x.

source


# LocalSearchSolvers._draw!Method.
julia
_draw!(s)

Draw a random (re-)starting configuration.

source


# LocalSearchSolvers._dynamic!Method.
julia
_dynamic!(options, dynamic) = begin

DOCSTRING

source


# LocalSearchSolvers._dynamicMethod.
julia
_dynamic(options) = begin

DOCSTRING

source


# LocalSearchSolvers._find_rand_argmaxMethod.
julia
_find_rand_argmax(d::DictionaryView)

Compute argmax of d and select one element randomly.

source


# LocalSearchSolvers._get_constraintsMethod.
julia
_get_constraints(x::Variable)

Access the list of constraints of x.

source


# LocalSearchSolvers._get_varsMethod.
julia
_get_vars(c::Constraint)

Returns the variables constrained by c.

source


# LocalSearchSolvers._inc_cons!Method.
julia
_inc_vars!(m::M) where M <: Union{Model, AbstractSolver}

Increment the maximum constraint id that has been attributed to m.

source


# LocalSearchSolvers._inc_objs!Method.
julia
_inc_vars!(m::M) where M <: Union{Model, AbstractSolver}

Increment the maximum objective id that has been attributed to m.

source


# LocalSearchSolvers._inc_vars!Method.
julia
_inc_vars!(m::M) where M <: Union{Model, AbstractSolver}

Increment the maximum variable id that has been attributed to m.

source


# LocalSearchSolvers._info_path!Method.
julia
_info_path!(options, iterations) = begin

DOCSTRING

source


# LocalSearchSolvers._info_pathMethod.
julia
_info_path(options, path)

DOCSTRING

source


# LocalSearchSolvers._is_emptyMethod.
julia
_is_empty(m::Model)

DOCSTRING

source


# LocalSearchSolvers._iteration!Method.
julia
_iteration!(options, iterations) = begin

DOCSTRING

source


# LocalSearchSolvers._iterationMethod.
julia
_iteration(options) = begin

DOCSTRING

source


# LocalSearchSolvers._lengthMethod.
julia
_length(c::Constraint)

Return the number of constrained variables by c.

source


# LocalSearchSolvers._max_consMethod.
julia
_max_cons(m::M) where M <: Union{Model, AbstractSolver}

Access the maximum constraint id that has been attributed to m.

source


# LocalSearchSolvers._max_objsMethod.
julia
_max_objs(m::M) where M <: Union{Model, AbstractSolver}

Access the maximum objective id that has been attributed to m.

source


# LocalSearchSolvers._max_varsMethod.
julia
_max_vars(m::M) where M <: Union{Model, AbstractSolver}

Access the maximum variable id that has been attributed to m.

source


# LocalSearchSolvers._move!Function.
julia
_move!(s, x::Int, dim::Int = 0)

Perform an improving move in x neighbourhood if possible.

Arguments:

  • s: a solver of type S <: AbstractSolver

  • x: selected variable id

  • dim: describe the dimension of the considered neighbourhood

source


# LocalSearchSolvers._neighboursFunction.
julia
_neighbours(s, x, dim = 0)

DOCSTRING

Arguments:

  • s: DESCRIPTION

  • x: DESCRIPTION

  • dim: DESCRIPTION

source


# LocalSearchSolvers._optimizing!Method.
julia
_optimizing!(s::S) where S <: Union{_State, AbstractSolver}

Set the solver optimizing status to true.

source


# LocalSearchSolvers._optimizingMethod.
julia
_optimizing(s::S) where S <: Union{_State, AbstractSolver}

Check if s is in an optimizing state.

source


# LocalSearchSolvers._print_level!Method.
julia
_print_level!(options, level) = begin

DOCSTRING

source


# LocalSearchSolvers._print_levelMethod.
julia
_print_level(options) = begin

DOCSTRING

source


# LocalSearchSolvers._restart!Function.
julia
_restart!(s, k = 10)

Restart a solver.

source


# LocalSearchSolvers._satisfying!Method.
julia
_satisfying!(s::S) where S <: Union{_State, AbstractSolver}

Set the solver optimizing status to false.

source


# LocalSearchSolvers._select_worseMethod.
julia
_select_worse(s::S) where S <: Union{_State, AbstractSolver}

Within the non-tabu variables, select the one with the worse error .

source


# LocalSearchSolvers._set!Method.
julia
_set!(s::S, x, val) where S <: Union{_State, AbstractSolver}

Set the value of variable x to val.

source


# LocalSearchSolvers._set_domain!Method.
julia
_set_domain!(m::Model, x, values)

DOCSTRING

Arguments:

  • m: DESCRIPTION

  • x: DESCRIPTION

  • values: DESCRIPTION

source


# LocalSearchSolvers._solutions!Method.
julia
_solutions!(options, solutions) = begin

DOCSTRING

source


# LocalSearchSolvers._solutionsMethod.
julia
_solutions(options) = begin

DOCSTRING

source


# LocalSearchSolvers._specialize!Method.
julia
_specialize!(options, specialize) = begin

DOCSTRING

source


# LocalSearchSolvers._specializeMethod.
julia
_specialize(options) = begin

DOCSTRING

source


# LocalSearchSolvers._step!Method.
julia
_step!(s)

Iterate a step of the solver run.

source


# LocalSearchSolvers._swap_value!Method.
julia
_set!(s::S, x, y) where S <: Union{_State, AbstractSolver}

Swap the values of variables x and y.

source


# LocalSearchSolvers._tabu_delta!Method.
julia
_tabu_delta!(options, time) = begin

DOCSTRING

source


# LocalSearchSolvers._tabu_deltaMethod.
julia
_tabu_delta(options) = begin

DOCSTRING

source


# LocalSearchSolvers._tabu_local!Method.
julia
_tabu_local!(options, time) = begin

DOCSTRING

source


# LocalSearchSolvers._tabu_localMethod.
julia
_tabu_local(options) = begin

DOCSTRING

source


# LocalSearchSolvers._tabu_time!Method.
julia
_tabu_time!(options, time) = begin

DOCSTRING

source


# LocalSearchSolvers._tabu_timeMethod.
julia
_tabu_time(options) = begin

DOCSTRING

source


# LocalSearchSolvers._threads!Method.
julia
_threads!(options, threads) = begin

DOCSTRING

source


# LocalSearchSolvers._threadsMethod.
julia
_threads(options) = begin

DOCSTRING

source


# LocalSearchSolvers._time_limit!Method.
julia
_time_limit!(options, time::Time) = begin

DOCSTRING

source


# LocalSearchSolvers._time_limitMethod.
julia
_time_limit(options) = begin

DOCSTRING

source


# LocalSearchSolvers._to_unionMethod.
julia
_to_union(datatype)

Make a minimal Union type from a collection of data types.

source


# LocalSearchSolvers._value!Method.
julia
_value!(s::S, x, val) where S <: Union{_State, AbstractSolver}

Set the value of variable x to val.

source


# LocalSearchSolvers._valueMethod.
julia
_value(s::S, x) where S <: Union{_State, AbstractSolver}

Return the value of variable x.

source


# LocalSearchSolvers._values!Method.
julia
_values!(s::S, values) where S <: Union{_State, AbstractSolver}

Set the variables values.

source


# LocalSearchSolvers._valuesMethod.
julia
_vars_costs(s::S) where S <: Union{_State, AbstractSolver}

Access the variables costs.

source


# LocalSearchSolvers._var_cost!Method.
julia
_var_cost!(s::S, x, cost) where S <: Union{_State, AbstractSolver}

Set the cost of variable x.

source


# LocalSearchSolvers._var_costMethod.
julia
_var_cost(s::S, x) where S <: Union{_State, AbstractSolver}

Return the cost of variable x.

source


# LocalSearchSolvers._vars_costs!Method.
julia
_vars_costs!(s::S, costs) where S <: Union{_State, AbstractSolver}

Set the variables costs.

source


# LocalSearchSolvers._vars_costsMethod.
julia
_vars_costs(s::S) where S <: Union{_State, AbstractSolver}

Access the variables costs.

source


# LocalSearchSolvers._verboseMethod.
julia
_verbose(settings, str)

Temporary logging function. #TODO: use better log instead (LoggingExtra.jl)

source


# LocalSearchSolvers.add!Method.
julia
mts = - get_time_stamp(model)

return TimeStamps(mts, mts, mts, mts, mts, mts, mts) end

add!(m::M, x) where M <: Union{Model, AbstractSolver}
-add!(m::M, c) where M <: Union{Model, AbstractSolver}
-add!(m::M, o) where M <: Union{Model, AbstractSolver}

Add a variable x, a constraint c, or an objective o to m.

source


# LocalSearchSolvers.add_value!Method.
julia
add_value!(m::M, x, val) where M <: Union{Model, AbstractSolver}

Add val to x domain.

source


# LocalSearchSolvers.add_var_to_cons!Method.
julia
add_var_to_cons!(m::M, c, x) where M <: Union{Model, AbstractSolver}

Add x to the constraint c list of restricted variables.

source


# LocalSearchSolvers.constraint!Method.
julia
constraint!(m::M, func, vars) where M <: Union{Model, AbstractSolver}

Add a constraint with an error function func defined over variables vars.

source


# LocalSearchSolvers.constraintMethod.
julia
constraint(f, vars)

DOCSTRING

source


# LocalSearchSolvers.constrictionMethod.
julia
constriction(m::M, x) where M <: Union{Model, AbstractSolver}

Return the constriction of variable x.

source


# LocalSearchSolvers.decay_tabu!Method.
julia
_decay_tabu!(s::S) where S <: Union{_State, AbstractSolver}

Decay the tabu list.

source


# LocalSearchSolvers.decrease_tabu!Method.
julia
_decrease_tabu!(s::S, x) where S <: Union{_State, AbstractSolver}

Decrement the tabu value of variable x.

source


# LocalSearchSolvers.delete_tabu!Method.
julia
_delete_tabu!(s::S, x) where S <: Union{_State, AbstractSolver}

Delete the tabu entry of variable x.

source


# LocalSearchSolvers.delete_value!Method.
julia
delete_value(m::M, x, val) where M <: Union{Model, AbstractSolver}

Delete val from x domain.

source


# LocalSearchSolvers.delete_var_from_cons!Method.
julia
delete_var_from_cons(m::M, c, x) where M <: Union{Model, AbstractSolver}

Delete x from the constraint c list of restricted variables.

source


# LocalSearchSolvers.describeMethod.
julia
describe(m::M) where M <: Union{Model, AbstractSolver}

Describe the model.

source


# LocalSearchSolvers.domain_sizeMethod.
julia
domain_size(m::Model, x) = begin

DOCSTRING

source


# LocalSearchSolvers.drawMethod.
julia
draw(m::M, x) where M <: Union{Model, AbstractSolver}

Draw a random value of x domain.

source


# LocalSearchSolvers.empty_tabu!Method.
julia
_empty_tabu!(s::S) where S <: Union{_State, AbstractSolver}

Empty the tabu list.

source


# LocalSearchSolvers.get_cons_from_varMethod.
julia
get_cons_from_var(m::M, x) where M <: Union{Model, AbstractSolver}

Access the constraints restricting variable x.

source


# LocalSearchSolvers.get_constraintMethod.
julia
get_constraint(m::M, c) where M <: Union{Model, AbstractSolver}

Access the constraint c.

source


# LocalSearchSolvers.get_constraintsMethod.
julia
get_constraints(m::M) where M <: Union{Model, AbstractSolver}

Access the constraints of m.

source


# LocalSearchSolvers.get_domainMethod.
julia
get_domain(m::M, x) where M <: Union{Model, AbstractSolver}

Access the domain of variable x.

source


# LocalSearchSolvers.get_kindMethod.
julia
get_kind(m::M) where M <: Union{Model, AbstractSolver}

Access the kind of m, such as :sudoku or :generic (default).

source


# LocalSearchSolvers.get_nameMethod.
julia
get_name(m::M, x) where M <: Union{Model, AbstractSolver}

Access the name of variable x.

source


# LocalSearchSolvers.get_objectiveMethod.
julia
get_objective(m::M, o) where M <: Union{Model, AbstractSolver}

Access the objective o.

source


# LocalSearchSolvers.get_objectivesMethod.
julia
get_objectives(m::M) where M <: Union{Model, AbstractSolver}

Access the objectives of m.

source


# LocalSearchSolvers.get_time_stampMethod.
julia
get_time_stamp(m::M) where M <: Union{Model, AbstractSolver}

Access the time (since epoch) when the model was created. This time stamp is for internal performance measurement.

source


# LocalSearchSolvers.get_variableMethod.
julia
get_variable(m::M, x) where M <: Union{Model, AbstractSolver}

Access the variable x.

source


# LocalSearchSolvers.get_variablesMethod.
julia
get_variables(m::M) where M <: Union{Model, AbstractSolver}

Access the variables of m.

source


# LocalSearchSolvers.get_vars_from_consMethod.
julia
get_vars_from_cons(m::M, c) where M <: Union{Model, AbstractSolver}

Access the variables restricted by constraint c.

source


# LocalSearchSolvers.insert_tabu!Method.
julia
_insert_tabu!(s::S, x, tabu_time) where S <: Union{_State, AbstractSolver}

Insert the bariable x as tabu for tabu_time.

source


# LocalSearchSolvers.is_satMethod.
julia
is_sat(m::M) where M <: Union{Model, AbstractSolver}

Return true if m is a satisfaction model.

source


# LocalSearchSolvers.is_specializedMethod.
julia
is_specialized(m::M) where M <: Union{Model, AbstractSolver}

Return true if the model is already specialized.

source


# LocalSearchSolvers.length_consMethod.
julia
length_cons(m::M, c) where M <: Union{Model, AbstractSolver}

Return the length of constraint c.

source


# LocalSearchSolvers.length_consMethod.
julia
length_cons(m::M) where M <: Union{Model, AbstractSolver}

Return the number of constraints in m.

source


# LocalSearchSolvers.length_objsMethod.
julia
length_objs(m::M) where M <: Union{Model, AbstractSolver}

Return the number of objectives in m.

source


# LocalSearchSolvers.length_tabuMethod.
julia
_length_tabu!(s::S) where S <: Union{_State, AbstractSolver}

Return the length of the tabu list.

source


# LocalSearchSolvers.length_varMethod.
julia
length_var(m::M, x) where M <: Union{Model, AbstractSolver}

Return the domain length of variable x.

source


# LocalSearchSolvers.length_varsMethod.
julia
length_vars(m::M) where M <: Union{Model, AbstractSolver}

Return the number of variables in m.

source


# LocalSearchSolvers.max_domains_sizeMethod.
julia
max_domains_size(m::Model, vars) = begin

DOCSTRING

source


# LocalSearchSolvers.modelMethod.
julia
model()

Construct a _Model, empty by default. It is recommended to add the constraints, variables, and objectives from an empty _Model. The following keyword arguments are available,

  • vars=Dictionary{Int,Variable}(): collection of variables

  • cons=Dictionary{Int,Constraint}(): collection of constraints

  • objs=Dictionary{Int,Objective}(): collection of objectives

  • kind=:generic: the kind of problem modeled (useful for specialized methods such as pretty printing)

source


# LocalSearchSolvers.o_dist_extremaMethod.
julia
dist_extrema(values::T...) where {T <: Number}

Computes the distance between extrema in an ordered set.

source


# LocalSearchSolvers.o_mincutMethod.
julia
o_mincut(graph, values; interdiction = 0)

Compute the capacity of a cut (determined by the state of the solver) with a possible interdiction on the highest capacited links.

source


# LocalSearchSolvers.objective!Method.
julia
objective!(m::M, func) where M <: Union{Model, AbstractSolver}

Add an objective evaluated by func.

source


# LocalSearchSolvers.objectiveMethod.
julia
objective(func, name)

Construct an objective with a function func that should be applied to a collection of variables.

source


# LocalSearchSolvers.post_processMethod.
julia
post_process(s::MainSolver)

Launch a series of tasks to round-up a solving run, for instance, export a run's info.

source


# LocalSearchSolvers.remote_dispatch!Method.
julia
remote_dispatch!(solver)

Starts the LeadSolvers attached to the MainSolver.

source


# LocalSearchSolvers.remote_stop!Method.
julia
remote_stop!!(solver)

Fetch the pool of solutions from LeadSolvers and merge it into the MainSolver.

source


# LocalSearchSolvers.solutionMethod.
julia
solution(s)

Return the only/best known solution of a satisfaction/optimization model.

source


# LocalSearchSolvers.solve_for_loop!Method.
julia
solve_for_loop!(solver, stop, sat, iter)

First loop in the solving process that starts LeadSolvers from the MainSolver, and _SubSolvers from each MetaSolver.

source


# LocalSearchSolvers.solve_while_loop!Method.
julia
solve_while_loop!(s, )

Search the space of configurations.

source


# LocalSearchSolvers.specialize!Method.
julia
specialize!(solver)

Replace the model of solver by one with specialized types (variables, constraints, objectives).

source


# LocalSearchSolvers.specializeMethod.
julia
specialize(m::M) where M <: Union{Model, AbstractSolver}

Specialize the structure of a model to avoid dynamic type attribution at runtime.

source


# LocalSearchSolvers.statusMethod.
julia
status(solver)

Return the status of a MainSolver.

source


# LocalSearchSolvers.stop_while_loopMethod.
julia
stop_while_loop()

Check the stop conditions of the solve! while inner loop.

source


# LocalSearchSolvers.tabu_listMethod.
julia
_tabu(s::S) where S <: Union{_State, AbstractSolver}

Access the list of tabu variables.

source


# LocalSearchSolvers.tabu_valueMethod.
julia
_tabu(s::S, x) where S <: Union{_State, AbstractSolver}

Return the tabu value of variable x.

source


# LocalSearchSolvers.variable!Function.
julia
variable!(m::M, d) where M <: Union{Model, AbstractSolver}

Add a variable with domain d to m.

source


# LocalSearchSolvers.variableMethod.
julia
variable(values::AbstractVector{T}, name::AbstractString; domain = :set) where T <: Number
-variable(domain::AbstractDomain, name::AbstractString) where D <: AbstractDomain

Construct a variable with discrete domain. See the domain method for other options.

julia
d = domain([1,2,3,4], types = :indices)
-x1 = variable(d, "x1")
-x2 = variable([-89,56,28], "x2", domain = :indices)

source


`,286),r=[t];function o(h,n,p,d,c,k){return a(),i("div",null,r)}const g=s(l,[["render",o]]);export{u as __pageData,g as default}; diff --git a/dev/assets/solvers_local_search_solvers.md.BuFLqJZe.lean.js b/dev/assets/solvers_local_search_solvers.md.BuFLqJZe.lean.js deleted file mode 100644 index 377bcfd..0000000 --- a/dev/assets/solvers_local_search_solvers.md.BuFLqJZe.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as i,o as a,a7 as e}from"./chunks/framework.aA95Gx5L.js";const u=JSON.parse('{"title":"LocalSearchSolvers.jl","description":"","frontmatter":{},"headers":[],"relativePath":"solvers/local_search_solvers.md","filePath":"solvers/local_search_solvers.md","lastUpdated":null}'),l={name:"solvers/local_search_solvers.md"},t=e("",286),r=[t];function o(h,n,p,d,c,k){return a(),i("div",null,r)}const g=s(l,[["render",o]]);export{u as __pageData,g as default}; diff --git a/dev/assets/style.Bq13Ojh9.css b/dev/assets/style.Bq13Ojh9.css deleted file mode 100644 index 697633f..0000000 --- a/dev/assets/style.Bq13Ojh9.css +++ /dev/null @@ -1 +0,0 @@ -@import"https://fonts.googleapis.com/css?family=Space+Mono:regular,italic,700,700italic";@import"https://fonts.googleapis.com/css?family=Space+Grotesk:regular,italic,700,700italic";@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/dev/assets/inter-roman-cyrillic.CMhn1ESj.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/dev/assets/inter-roman-cyrillic-ext.DxP3Awbn.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/dev/assets/inter-roman-greek.JvnBZ4YD.woff2) format("woff2");unicode-range:U+0370-03FF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/dev/assets/inter-roman-greek-ext.D0mI3NpI.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/dev/assets/inter-roman-latin.Bu8hRsVA.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/dev/assets/inter-roman-latin-ext.ZlYT4o7i.woff2) format("woff2");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/dev/assets/inter-roman-vietnamese.ClpjcLMQ.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/dev/assets/inter-italic-cyrillic.D6csxwjC.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/dev/assets/inter-italic-cyrillic-ext.5XJwZIOp.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/dev/assets/inter-italic-greek.9J96vYpw.woff2) format("woff2");unicode-range:U+0370-03FF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/dev/assets/inter-italic-greek-ext.CHOfFY1k.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/dev/assets/inter-italic-latin.DbsTr1gm.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/dev/assets/inter-italic-latin-ext.BGcWXLrn.woff2) format("woff2");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/dev/assets/inter-italic-vietnamese.DHNAd7Wr.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:Chinese Quotes;src:local("PingFang SC Regular"),local("PingFang SC"),local("SimHei"),local("Source Han Sans SC");unicode-range:U+2018,U+2019,U+201C,U+201D}:root{--vp-c-white: #ffffff;--vp-c-black: #000000;--vp-c-neutral: var(--vp-c-black);--vp-c-neutral-inverse: var(--vp-c-white)}.dark{--vp-c-neutral: var(--vp-c-white);--vp-c-neutral-inverse: var(--vp-c-black)}:root{--vp-c-gray-1: #dddde3;--vp-c-gray-2: #e4e4e9;--vp-c-gray-3: #ebebef;--vp-c-gray-soft: rgba(142, 150, 170, .14);--vp-c-indigo-1: #3451b2;--vp-c-indigo-2: #3a5ccc;--vp-c-indigo-3: #5672cd;--vp-c-indigo-soft: rgba(100, 108, 255, .14);--vp-c-purple-1: #6f42c1;--vp-c-purple-2: #7e4cc9;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .14);--vp-c-green-1: #18794e;--vp-c-green-2: #299764;--vp-c-green-3: #30a46c;--vp-c-green-soft: rgba(16, 185, 129, .14);--vp-c-yellow-1: #915930;--vp-c-yellow-2: #946300;--vp-c-yellow-3: #9f6a00;--vp-c-yellow-soft: rgba(234, 179, 8, .14);--vp-c-red-1: #b8272c;--vp-c-red-2: #d5393e;--vp-c-red-3: #e0575b;--vp-c-red-soft: rgba(244, 63, 94, .14);--vp-c-sponsor: #db2777}.dark{--vp-c-gray-1: #515c67;--vp-c-gray-2: #414853;--vp-c-gray-3: #32363f;--vp-c-gray-soft: rgba(101, 117, 133, .16);--vp-c-indigo-1: #a8b1ff;--vp-c-indigo-2: #5c73e7;--vp-c-indigo-3: #3e63dd;--vp-c-indigo-soft: rgba(100, 108, 255, .16);--vp-c-purple-1: #c8abfa;--vp-c-purple-2: #a879e6;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .16);--vp-c-green-1: #3dd68c;--vp-c-green-2: #30a46c;--vp-c-green-3: #298459;--vp-c-green-soft: rgba(16, 185, 129, .16);--vp-c-yellow-1: #f9b44e;--vp-c-yellow-2: #da8b17;--vp-c-yellow-3: #a46a0a;--vp-c-yellow-soft: rgba(234, 179, 8, .16);--vp-c-red-1: #f66f81;--vp-c-red-2: #f14158;--vp-c-red-3: #b62a3c;--vp-c-red-soft: rgba(244, 63, 94, .16)}:root{--vp-c-bg: #ffffff;--vp-c-bg-alt: #f6f6f7;--vp-c-bg-elv: #ffffff;--vp-c-bg-soft: #f6f6f7}.dark{--vp-c-bg: #1b1b1f;--vp-c-bg-alt: #161618;--vp-c-bg-elv: #202127;--vp-c-bg-soft: #202127}:root{--vp-c-border: #c2c2c4;--vp-c-divider: #e2e2e3;--vp-c-gutter: #e2e2e3}.dark{--vp-c-border: #3c3f44;--vp-c-divider: #2e2e32;--vp-c-gutter: #000000}:root{--vp-c-text-1: rgba(60, 60, 67);--vp-c-text-2: rgba(60, 60, 67, .78);--vp-c-text-3: rgba(60, 60, 67, .56)}.dark{--vp-c-text-1: rgba(255, 255, 245, .86);--vp-c-text-2: rgba(235, 235, 245, .6);--vp-c-text-3: rgba(235, 235, 245, .38)}:root{--vp-c-default-1: var(--vp-c-gray-1);--vp-c-default-2: var(--vp-c-gray-2);--vp-c-default-3: var(--vp-c-gray-3);--vp-c-default-soft: var(--vp-c-gray-soft);--vp-c-brand-1: var(--vp-c-indigo-1);--vp-c-brand-2: var(--vp-c-indigo-2);--vp-c-brand-3: var(--vp-c-indigo-3);--vp-c-brand-soft: var(--vp-c-indigo-soft);--vp-c-brand: var(--vp-c-brand-1);--vp-c-tip-1: var(--vp-c-brand-1);--vp-c-tip-2: var(--vp-c-brand-2);--vp-c-tip-3: var(--vp-c-brand-3);--vp-c-tip-soft: var(--vp-c-brand-soft);--vp-c-note-1: var(--vp-c-brand-1);--vp-c-note-2: var(--vp-c-brand-2);--vp-c-note-3: var(--vp-c-brand-3);--vp-c-note-soft: var(--vp-c-brand-soft);--vp-c-success-1: var(--vp-c-green-1);--vp-c-success-2: var(--vp-c-green-2);--vp-c-success-3: var(--vp-c-green-3);--vp-c-success-soft: var(--vp-c-green-soft);--vp-c-important-1: var(--vp-c-purple-1);--vp-c-important-2: var(--vp-c-purple-2);--vp-c-important-3: var(--vp-c-purple-3);--vp-c-important-soft: var(--vp-c-purple-soft);--vp-c-warning-1: var(--vp-c-yellow-1);--vp-c-warning-2: var(--vp-c-yellow-2);--vp-c-warning-3: var(--vp-c-yellow-3);--vp-c-warning-soft: var(--vp-c-yellow-soft);--vp-c-danger-1: var(--vp-c-red-1);--vp-c-danger-2: var(--vp-c-red-2);--vp-c-danger-3: var(--vp-c-red-3);--vp-c-danger-soft: var(--vp-c-red-soft);--vp-c-caution-1: var(--vp-c-red-1);--vp-c-caution-2: var(--vp-c-red-2);--vp-c-caution-3: var(--vp-c-red-3);--vp-c-caution-soft: var(--vp-c-red-soft)}:root{--vp-font-family-base: "Chinese Quotes", "Inter var", "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Helvetica, Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--vp-font-family-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}:root{--vp-shadow-1: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--vp-shadow-2: 0 3px 12px rgba(0, 0, 0, .07), 0 1px 4px rgba(0, 0, 0, .07);--vp-shadow-3: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);--vp-shadow-4: 0 14px 44px rgba(0, 0, 0, .12), 0 3px 9px rgba(0, 0, 0, .12);--vp-shadow-5: 0 18px 56px rgba(0, 0, 0, .16), 0 4px 12px rgba(0, 0, 0, .16)}:root{--vp-z-index-footer: 10;--vp-z-index-local-nav: 20;--vp-z-index-nav: 30;--vp-z-index-layout-top: 40;--vp-z-index-backdrop: 50;--vp-z-index-sidebar: 60}@media (min-width: 960px){:root{--vp-z-index-sidebar: 25}}:root{--vp-layout-max-width: 1440px}:root{--vp-header-anchor-symbol: "#"}:root{--vp-code-line-height: 1.7;--vp-code-font-size: .875em;--vp-code-color: var(--vp-c-brand-1);--vp-code-link-color: var(--vp-c-brand-1);--vp-code-link-hover-color: var(--vp-c-brand-2);--vp-code-bg: var(--vp-c-default-soft);--vp-code-block-color: var(--vp-c-text-2);--vp-code-block-bg: var(--vp-c-bg-alt);--vp-code-block-divider-color: var(--vp-c-gutter);--vp-code-lang-color: var(--vp-c-text-3);--vp-code-line-highlight-color: var(--vp-c-default-soft);--vp-code-line-number-color: var(--vp-c-text-3);--vp-code-line-diff-add-color: var(--vp-c-success-soft);--vp-code-line-diff-add-symbol-color: var(--vp-c-success-1);--vp-code-line-diff-remove-color: var(--vp-c-danger-soft);--vp-code-line-diff-remove-symbol-color: var(--vp-c-danger-1);--vp-code-line-warning-color: var(--vp-c-warning-soft);--vp-code-line-error-color: var(--vp-c-danger-soft);--vp-code-copy-code-border-color: var(--vp-c-divider);--vp-code-copy-code-bg: var(--vp-c-bg-soft);--vp-code-copy-code-hover-border-color: var(--vp-c-divider);--vp-code-copy-code-hover-bg: var(--vp-c-bg);--vp-code-copy-code-active-text: var(--vp-c-text-2);--vp-code-copy-copied-text-content: "Copied";--vp-code-tab-divider: var(--vp-code-block-divider-color);--vp-code-tab-text-color: var(--vp-c-text-2);--vp-code-tab-bg: var(--vp-code-block-bg);--vp-code-tab-hover-text-color: var(--vp-c-text-1);--vp-code-tab-active-text-color: var(--vp-c-text-1);--vp-code-tab-active-bar-color: var(--vp-c-brand-1)}:root{--vp-button-brand-border: transparent;--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand-3);--vp-button-brand-hover-border: transparent;--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-2);--vp-button-brand-active-border: transparent;--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-1);--vp-button-alt-border: transparent;--vp-button-alt-text: var(--vp-c-text-1);--vp-button-alt-bg: var(--vp-c-default-3);--vp-button-alt-hover-border: transparent;--vp-button-alt-hover-text: var(--vp-c-text-1);--vp-button-alt-hover-bg: var(--vp-c-default-2);--vp-button-alt-active-border: transparent;--vp-button-alt-active-text: var(--vp-c-text-1);--vp-button-alt-active-bg: var(--vp-c-default-1);--vp-button-sponsor-border: var(--vp-c-text-2);--vp-button-sponsor-text: var(--vp-c-text-2);--vp-button-sponsor-bg: transparent;--vp-button-sponsor-hover-border: var(--vp-c-sponsor);--vp-button-sponsor-hover-text: var(--vp-c-sponsor);--vp-button-sponsor-hover-bg: transparent;--vp-button-sponsor-active-border: var(--vp-c-sponsor);--vp-button-sponsor-active-text: var(--vp-c-sponsor);--vp-button-sponsor-active-bg: transparent}:root{--vp-custom-block-font-size: 14px;--vp-custom-block-code-font-size: 13px;--vp-custom-block-info-border: transparent;--vp-custom-block-info-text: var(--vp-c-text-1);--vp-custom-block-info-bg: var(--vp-c-default-soft);--vp-custom-block-info-code-bg: var(--vp-c-default-soft);--vp-custom-block-note-border: transparent;--vp-custom-block-note-text: var(--vp-c-text-1);--vp-custom-block-note-bg: var(--vp-c-default-soft);--vp-custom-block-note-code-bg: var(--vp-c-default-soft);--vp-custom-block-tip-border: transparent;--vp-custom-block-tip-text: var(--vp-c-text-1);--vp-custom-block-tip-bg: var(--vp-c-tip-soft);--vp-custom-block-tip-code-bg: var(--vp-c-tip-soft);--vp-custom-block-important-border: transparent;--vp-custom-block-important-text: var(--vp-c-text-1);--vp-custom-block-important-bg: var(--vp-c-important-soft);--vp-custom-block-important-code-bg: var(--vp-c-important-soft);--vp-custom-block-warning-border: transparent;--vp-custom-block-warning-text: var(--vp-c-text-1);--vp-custom-block-warning-bg: var(--vp-c-warning-soft);--vp-custom-block-warning-code-bg: var(--vp-c-warning-soft);--vp-custom-block-danger-border: transparent;--vp-custom-block-danger-text: var(--vp-c-text-1);--vp-custom-block-danger-bg: var(--vp-c-danger-soft);--vp-custom-block-danger-code-bg: var(--vp-c-danger-soft);--vp-custom-block-caution-border: transparent;--vp-custom-block-caution-text: var(--vp-c-text-1);--vp-custom-block-caution-bg: var(--vp-c-caution-soft);--vp-custom-block-caution-code-bg: var(--vp-c-caution-soft);--vp-custom-block-details-border: var(--vp-custom-block-info-border);--vp-custom-block-details-text: var(--vp-custom-block-info-text);--vp-custom-block-details-bg: var(--vp-custom-block-info-bg);--vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg)}:root{--vp-input-border-color: var(--vp-c-border);--vp-input-bg-color: var(--vp-c-bg-alt);--vp-input-switch-bg-color: var(--vp-c-default-soft)}:root{--vp-nav-height: 64px;--vp-nav-bg-color: var(--vp-c-bg);--vp-nav-screen-bg-color: var(--vp-c-bg);--vp-nav-logo-height: 24px}.hide-nav{--vp-nav-height: 0px}.hide-nav .VPSidebar{--vp-nav-height: 22px}:root{--vp-local-nav-bg-color: var(--vp-c-bg)}:root{--vp-sidebar-width: 272px;--vp-sidebar-bg-color: var(--vp-c-bg-alt)}:root{--vp-backdrop-bg-color: rgba(0, 0, 0, .6)}:root{--vp-home-hero-name-color: var(--vp-c-brand-1);--vp-home-hero-name-background: transparent;--vp-home-hero-image-background-image: none;--vp-home-hero-image-filter: none}:root{--vp-badge-info-border: transparent;--vp-badge-info-text: var(--vp-c-text-2);--vp-badge-info-bg: var(--vp-c-default-soft);--vp-badge-tip-border: transparent;--vp-badge-tip-text: var(--vp-c-tip-1);--vp-badge-tip-bg: var(--vp-c-tip-soft);--vp-badge-warning-border: transparent;--vp-badge-warning-text: var(--vp-c-warning-1);--vp-badge-warning-bg: var(--vp-c-warning-soft);--vp-badge-danger-border: transparent;--vp-badge-danger-text: var(--vp-c-danger-1);--vp-badge-danger-bg: var(--vp-c-danger-soft)}:root{--vp-carbon-ads-text-color: var(--vp-c-text-1);--vp-carbon-ads-poweredby-color: var(--vp-c-text-2);--vp-carbon-ads-bg-color: var(--vp-c-bg-soft);--vp-carbon-ads-hover-text-color: var(--vp-c-brand-1);--vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1)}:root{--vp-local-search-bg: var(--vp-c-bg);--vp-local-search-result-bg: var(--vp-c-bg);--vp-local-search-result-border: var(--vp-c-divider);--vp-local-search-result-selected-bg: var(--vp-c-bg);--vp-local-search-result-selected-border: var(--vp-c-brand-1);--vp-local-search-highlight-bg: var(--vp-c-brand-1);--vp-local-search-highlight-text: var(--vp-c-neutral-inverse)}@media (prefers-reduced-motion: reduce){*,:before,:after{animation-delay:-1ms!important;animation-duration:1ms!important;animation-iteration-count:1!important;background-attachment:initial!important;scroll-behavior:auto!important;transition-duration:0s!important;transition-delay:0s!important}}*,:before,:after{box-sizing:border-box}html{line-height:1.4;font-size:16px;-webkit-text-size-adjust:100%}html.dark{color-scheme:dark}body{margin:0;width:100%;min-width:320px;min-height:100vh;line-height:24px;font-family:var(--vp-font-family-base);font-size:16px;font-weight:400;color:var(--vp-c-text-1);background-color:var(--vp-c-bg);font-synthesis:style;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}main{display:block}h1,h2,h3,h4,h5,h6{margin:0;line-height:24px;font-size:16px;font-weight:400}p{margin:0}strong,b{font-weight:600}a,area,button,[role=button],input,label,select,summary,textarea{touch-action:manipulation}a{color:inherit;text-decoration:inherit}ol,ul{list-style:none;margin:0;padding:0}blockquote{margin:0}pre,code,kbd,samp{font-family:var(--vp-font-family-mono)}img,svg,video,canvas,audio,iframe,embed,object{display:block}figure{margin:0}img,video{max-width:100%;height:auto}button,input,optgroup,select,textarea{border:0;padding:0;line-height:inherit;color:inherit}button{padding:0;font-family:inherit;background-color:transparent;background-image:none}button:enabled,[role=button]:enabled{cursor:pointer}button:focus,button:focus-visible{outline:1px dotted;outline:4px auto -webkit-focus-ring-color}button:focus:not(:focus-visible){outline:none!important}input:focus,textarea:focus,select:focus{outline:none}table{border-collapse:collapse}input{background-color:transparent}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:var(--vp-c-text-3)}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:var(--vp-c-text-3)}input::placeholder,textarea::placeholder{color:var(--vp-c-text-3)}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}textarea{resize:vertical}select{-webkit-appearance:none}fieldset{margin:0;padding:0}h1,h2,h3,h4,h5,h6,li,p{overflow-wrap:break-word}vite-error-overlay{z-index:9999}mjx-container>svg{display:inline-block;margin:auto}[class^=vpi-],[class*=" vpi-"],.vp-icon{width:1em;height:1em}[class^=vpi-].bg,[class*=" vpi-"].bg,.vp-icon.bg{background-size:100% 100%;background-color:transparent}[class^=vpi-]:not(.bg),[class*=" vpi-"]:not(.bg),.vp-icon:not(.bg){-webkit-mask:var(--icon) no-repeat;mask:var(--icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit}.vpi-align-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M21 6H3M15 12H3M17 18H3'/%3E%3C/svg%3E")}.vpi-arrow-right,.vpi-arrow-down,.vpi-arrow-left,.vpi-arrow-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E")}.vpi-chevron-right,.vpi-chevron-down,.vpi-chevron-left,.vpi-chevron-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E")}.vpi-chevron-down,.vpi-arrow-down{transform:rotate(90deg)}.vpi-chevron-left,.vpi-arrow-left{transform:rotate(180deg)}.vpi-chevron-up,.vpi-arrow-up{transform:rotate(-90deg)}.vpi-square-pen{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7'/%3E%3Cpath d='M18.375 2.625a2.121 2.121 0 1 1 3 3L12 15l-4 1 1-4Z'/%3E%3C/svg%3E")}.vpi-plus{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5v14'/%3E%3C/svg%3E")}.vpi-sun{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41'/%3E%3C/svg%3E")}.vpi-moon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/%3E%3C/svg%3E")}.vpi-more-horizontal{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='1'/%3E%3Ccircle cx='19' cy='12' r='1'/%3E%3Ccircle cx='5' cy='12' r='1'/%3E%3C/svg%3E")}.vpi-languages{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m5 8 6 6M4 14l6-6 2-3M2 5h12M7 2h1M22 22l-5-10-5 10M14 18h6'/%3E%3C/svg%3E")}.vpi-heart{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E")}.vpi-search{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E")}.vpi-layout-list{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='7' height='7' x='3' y='3' rx='1'/%3E%3Crect width='7' height='7' x='3' y='14' rx='1'/%3E%3Cpath d='M14 4h7M14 9h7M14 15h7M14 20h7'/%3E%3C/svg%3E")}.vpi-delete{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M20 5H9l-7 7 7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2ZM18 9l-6 6M12 9l6 6'/%3E%3C/svg%3E")}.vpi-corner-down-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 10-5 5 5 5'/%3E%3Cpath d='M20 4v7a4 4 0 0 1-4 4H4'/%3E%3C/svg%3E")}:root{--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E")}.vpi-social-discord{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418Z'/%3E%3C/svg%3E")}.vpi-social-facebook{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z'/%3E%3C/svg%3E")}.vpi-social-github{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")}.vpi-social-instagram{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.03.084c-1.277.06-2.149.264-2.91.563a5.874 5.874 0 0 0-2.124 1.388 5.878 5.878 0 0 0-1.38 2.127C.321 4.926.12 5.8.064 7.076.008 8.354-.005 8.764.001 12.023c.007 3.259.021 3.667.083 4.947.061 1.277.264 2.149.563 2.911.308.789.72 1.457 1.388 2.123a5.872 5.872 0 0 0 2.129 1.38c.763.295 1.636.496 2.913.552 1.278.056 1.689.069 4.947.063 3.257-.007 3.668-.021 4.947-.082 1.28-.06 2.147-.265 2.91-.563a5.881 5.881 0 0 0 2.123-1.388 5.881 5.881 0 0 0 1.38-2.129c.295-.763.496-1.636.551-2.912.056-1.28.07-1.69.063-4.948-.006-3.258-.02-3.667-.081-4.947-.06-1.28-.264-2.148-.564-2.911a5.892 5.892 0 0 0-1.387-2.123 5.857 5.857 0 0 0-2.128-1.38C19.074.322 18.202.12 16.924.066 15.647.009 15.236-.006 11.977 0 8.718.008 8.31.021 7.03.084m.14 21.693c-1.17-.05-1.805-.245-2.228-.408a3.736 3.736 0 0 1-1.382-.895 3.695 3.695 0 0 1-.9-1.378c-.165-.423-.363-1.058-.417-2.228-.06-1.264-.072-1.644-.08-4.848-.006-3.204.006-3.583.061-4.848.05-1.169.246-1.805.408-2.228.216-.561.477-.96.895-1.382a3.705 3.705 0 0 1 1.379-.9c.423-.165 1.057-.361 2.227-.417 1.265-.06 1.644-.072 4.848-.08 3.203-.006 3.583.006 4.85.062 1.168.05 1.804.244 2.227.408.56.216.96.475 1.382.895.421.42.681.817.9 1.378.165.422.362 1.056.417 2.227.06 1.265.074 1.645.08 4.848.005 3.203-.006 3.583-.061 4.848-.051 1.17-.245 1.805-.408 2.23-.216.56-.477.96-.896 1.38a3.705 3.705 0 0 1-1.378.9c-.422.165-1.058.362-2.226.418-1.266.06-1.645.072-4.85.079-3.204.007-3.582-.006-4.848-.06m9.783-16.192a1.44 1.44 0 1 0 1.437-1.442 1.44 1.44 0 0 0-1.437 1.442M5.839 12.012a6.161 6.161 0 1 0 12.323-.024 6.162 6.162 0 0 0-12.323.024M8 12.008A4 4 0 1 1 12.008 16 4 4 0 0 1 8 12.008'/%3E%3C/svg%3E")}.vpi-social-linkedin{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z'/%3E%3C/svg%3E")}.vpi-social-mastodon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z'/%3E%3C/svg%3E")}.vpi-social-npm{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z'/%3E%3C/svg%3E")}.vpi-social-slack{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zm1.271 0a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zm0 1.271a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zm10.122 2.521a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zm-1.268 0a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zm-2.523 10.122a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zm0-1.268a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z'/%3E%3C/svg%3E")}.vpi-social-twitter,.vpi-social-x{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z'/%3E%3C/svg%3E")}.vpi-social-youtube{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z'/%3E%3C/svg%3E")}.visually-hidden{position:absolute;width:1px;height:1px;white-space:nowrap;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden}.custom-block{border:1px solid transparent;border-radius:8px;padding:16px 16px 8px;line-height:24px;font-size:var(--vp-custom-block-font-size);color:var(--vp-c-text-2)}.custom-block.info{border-color:var(--vp-custom-block-info-border);color:var(--vp-custom-block-info-text);background-color:var(--vp-custom-block-info-bg)}.custom-block.info a,.custom-block.info code{color:var(--vp-c-brand-1)}.custom-block.info a:hover,.custom-block.info a:hover>code{color:var(--vp-c-brand-2)}.custom-block.info code{background-color:var(--vp-custom-block-info-code-bg)}.custom-block.note{border-color:var(--vp-custom-block-note-border);color:var(--vp-custom-block-note-text);background-color:var(--vp-custom-block-note-bg)}.custom-block.note a,.custom-block.note code{color:var(--vp-c-brand-1)}.custom-block.note a:hover,.custom-block.note a:hover>code{color:var(--vp-c-brand-2)}.custom-block.note code{background-color:var(--vp-custom-block-note-code-bg)}.custom-block.tip{border-color:var(--vp-custom-block-tip-border);color:var(--vp-custom-block-tip-text);background-color:var(--vp-custom-block-tip-bg)}.custom-block.tip a,.custom-block.tip code{color:var(--vp-c-tip-1)}.custom-block.tip a:hover,.custom-block.tip a:hover>code{color:var(--vp-c-tip-2)}.custom-block.tip code{background-color:var(--vp-custom-block-tip-code-bg)}.custom-block.important{border-color:var(--vp-custom-block-important-border);color:var(--vp-custom-block-important-text);background-color:var(--vp-custom-block-important-bg)}.custom-block.important a,.custom-block.important code{color:var(--vp-c-important-1)}.custom-block.important a:hover,.custom-block.important a:hover>code{color:var(--vp-c-important-2)}.custom-block.important code{background-color:var(--vp-custom-block-important-code-bg)}.custom-block.warning{border-color:var(--vp-custom-block-warning-border);color:var(--vp-custom-block-warning-text);background-color:var(--vp-custom-block-warning-bg)}.custom-block.warning a,.custom-block.warning code{color:var(--vp-c-warning-1)}.custom-block.warning a:hover,.custom-block.warning a:hover>code{color:var(--vp-c-warning-2)}.custom-block.warning code{background-color:var(--vp-custom-block-warning-code-bg)}.custom-block.danger{border-color:var(--vp-custom-block-danger-border);color:var(--vp-custom-block-danger-text);background-color:var(--vp-custom-block-danger-bg)}.custom-block.danger a,.custom-block.danger code{color:var(--vp-c-danger-1)}.custom-block.danger a:hover,.custom-block.danger a:hover>code{color:var(--vp-c-danger-2)}.custom-block.danger code{background-color:var(--vp-custom-block-danger-code-bg)}.custom-block.caution{border-color:var(--vp-custom-block-caution-border);color:var(--vp-custom-block-caution-text);background-color:var(--vp-custom-block-caution-bg)}.custom-block.caution a,.custom-block.caution code{color:var(--vp-c-caution-1)}.custom-block.caution a:hover,.custom-block.caution a:hover>code{color:var(--vp-c-caution-2)}.custom-block.caution code{background-color:var(--vp-custom-block-caution-code-bg)}.custom-block.details{border-color:var(--vp-custom-block-details-border);color:var(--vp-custom-block-details-text);background-color:var(--vp-custom-block-details-bg)}.custom-block.details a{color:var(--vp-c-brand-1)}.custom-block.details a:hover,.custom-block.details a:hover>code{color:var(--vp-c-brand-2)}.custom-block.details code{background-color:var(--vp-custom-block-details-code-bg)}.custom-block-title{font-weight:600}.custom-block p+p{margin:8px 0}.custom-block.details summary{margin:0 0 8px;font-weight:700;cursor:pointer;-webkit-user-select:none;user-select:none}.custom-block.details summary+p{margin:8px 0}.custom-block a{color:inherit;font-weight:600;text-decoration:underline;text-underline-offset:2px;transition:opacity .25s}.custom-block a:hover{opacity:.75}.custom-block code{font-size:var(--vp-custom-block-code-font-size)}.custom-block.custom-block th,.custom-block.custom-block blockquote>p{font-size:var(--vp-custom-block-font-size);color:inherit}.dark .vp-code span{color:var(--shiki-dark, inherit)}html:not(.dark) .vp-code span{color:var(--shiki-light, inherit)}.vp-code-group{margin-top:16px}.vp-code-group .tabs{position:relative;display:flex;margin-right:-24px;margin-left:-24px;padding:0 12px;background-color:var(--vp-code-tab-bg);overflow-x:auto;overflow-y:hidden;box-shadow:inset 0 -1px var(--vp-code-tab-divider)}@media (min-width: 640px){.vp-code-group .tabs{margin-right:0;margin-left:0;border-radius:8px 8px 0 0}}.vp-code-group .tabs input{position:fixed;opacity:0;pointer-events:none}.vp-code-group .tabs label{position:relative;display:inline-block;border-bottom:1px solid transparent;padding:0 12px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-code-tab-text-color);white-space:nowrap;cursor:pointer;transition:color .25s}.vp-code-group .tabs label:after{position:absolute;right:8px;bottom:-1px;left:8px;z-index:1;height:2px;border-radius:2px;content:"";background-color:transparent;transition:background-color .25s}.vp-code-group label:hover{color:var(--vp-code-tab-hover-text-color)}.vp-code-group input:checked+label{color:var(--vp-code-tab-active-text-color)}.vp-code-group input:checked+label:after{background-color:var(--vp-code-tab-active-bar-color)}.vp-code-group div[class*=language-],.vp-block{display:none;margin-top:0!important;border-top-left-radius:0!important;border-top-right-radius:0!important}.vp-code-group div[class*=language-].active,.vp-block.active{display:block}.vp-block{padding:20px 24px}.vp-doc h1,.vp-doc h2,.vp-doc h3,.vp-doc h4,.vp-doc h5,.vp-doc h6{position:relative;font-weight:600;outline:none}.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:28px}.vp-doc h2{margin:48px 0 16px;border-top:1px solid var(--vp-c-divider);padding-top:24px;letter-spacing:-.02em;line-height:32px;font-size:24px}.vp-doc h3{margin:32px 0 0;letter-spacing:-.01em;line-height:28px;font-size:20px}.vp-doc .header-anchor{position:absolute;top:0;left:0;margin-left:-.87em;font-weight:500;-webkit-user-select:none;user-select:none;opacity:0;text-decoration:none;transition:color .25s,opacity .25s}.vp-doc .header-anchor:before{content:var(--vp-header-anchor-symbol)}.vp-doc h1:hover .header-anchor,.vp-doc h1 .header-anchor:focus,.vp-doc h2:hover .header-anchor,.vp-doc h2 .header-anchor:focus,.vp-doc h3:hover .header-anchor,.vp-doc h3 .header-anchor:focus,.vp-doc h4:hover .header-anchor,.vp-doc h4 .header-anchor:focus,.vp-doc h5:hover .header-anchor,.vp-doc h5 .header-anchor:focus,.vp-doc h6:hover .header-anchor,.vp-doc h6 .header-anchor:focus{opacity:1}@media (min-width: 768px){.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:32px}}.vp-doc h2 .header-anchor{top:24px}.vp-doc p,.vp-doc summary{margin:16px 0}.vp-doc p{line-height:28px}.vp-doc blockquote{margin:16px 0;border-left:2px solid var(--vp-c-divider);padding-left:16px;transition:border-color .5s}.vp-doc blockquote>p{margin:0;font-size:16px;color:var(--vp-c-text-2);transition:color .5s}.vp-doc a{font-weight:500;color:var(--vp-c-brand-1);text-decoration:underline;text-underline-offset:2px;transition:color .25s,opacity .25s}.vp-doc a:hover{color:var(--vp-c-brand-2)}.vp-doc strong{font-weight:600}.vp-doc ul,.vp-doc ol{padding-left:1.25rem;margin:16px 0}.vp-doc ul{list-style:disc}.vp-doc ol{list-style:decimal}.vp-doc li+li{margin-top:8px}.vp-doc li>ol,.vp-doc li>ul{margin:8px 0 0}.vp-doc table{display:block;border-collapse:collapse;margin:20px 0;overflow-x:auto}.vp-doc tr{background-color:var(--vp-c-bg);border-top:1px solid var(--vp-c-divider);transition:background-color .5s}.vp-doc tr:nth-child(2n){background-color:var(--vp-c-bg-soft)}.vp-doc th,.vp-doc td{border:1px solid var(--vp-c-divider);padding:8px 16px}.vp-doc th{text-align:left;font-size:14px;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-doc td{font-size:14px}.vp-doc hr{margin:16px 0;border:none;border-top:1px solid var(--vp-c-divider)}.vp-doc .custom-block{margin:16px 0}.vp-doc .custom-block p{margin:8px 0;line-height:24px}.vp-doc .custom-block p:first-child{margin:0}.vp-doc .custom-block div[class*=language-]{margin:8px 0;border-radius:8px}.vp-doc .custom-block div[class*=language-] code{font-weight:400;background-color:transparent}.vp-doc .custom-block .vp-code-group .tabs{margin:0;border-radius:8px 8px 0 0}.vp-doc :not(pre,h1,h2,h3,h4,h5,h6)>code{font-size:var(--vp-code-font-size);color:var(--vp-code-color)}.vp-doc :not(pre)>code{border-radius:4px;padding:3px 6px;background-color:var(--vp-code-bg);transition:color .25s,background-color .5s}.vp-doc a>code{color:var(--vp-code-link-color)}.vp-doc a:hover>code{color:var(--vp-code-link-hover-color)}.vp-doc h1>code,.vp-doc h2>code,.vp-doc h3>code{font-size:.9em}.vp-doc div[class*=language-],.vp-block{position:relative;margin:16px -24px;background-color:var(--vp-code-block-bg);overflow-x:auto;transition:background-color .5s}@media (min-width: 640px){.vp-doc div[class*=language-],.vp-block{border-radius:8px;margin:16px 0}}@media (max-width: 639px){.vp-doc li div[class*=language-]{border-radius:8px 0 0 8px}}.vp-doc div[class*=language-]+div[class*=language-],.vp-doc div[class$=-api]+div[class*=language-],.vp-doc div[class*=language-]+div[class$=-api]>div[class*=language-]{margin-top:-8px}.vp-doc [class*=language-] pre,.vp-doc [class*=language-] code{direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}.vp-doc [class*=language-] pre{position:relative;z-index:1;margin:0;padding:20px 0;background:transparent;overflow-x:auto}.vp-doc [class*=language-] code{display:block;padding:0 24px;width:fit-content;min-width:100%;line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-block-color);transition:color .5s}.vp-doc [class*=language-] code .highlighted{background-color:var(--vp-code-line-highlight-color);transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .highlighted.error{background-color:var(--vp-code-line-error-color)}.vp-doc [class*=language-] code .highlighted.warning{background-color:var(--vp-code-line-warning-color)}.vp-doc [class*=language-] code .diff{transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .diff:before{position:absolute;left:10px}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){filter:blur(.095rem);opacity:.4;transition:filter .35s,opacity .35s}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){opacity:.7;transition:filter .35s,opacity .35s}.vp-doc [class*=language-]:hover .has-focused-lines .line:not(.has-focus){filter:blur(0);opacity:1}.vp-doc [class*=language-] code .diff.remove{background-color:var(--vp-code-line-diff-remove-color);opacity:.7}.vp-doc [class*=language-] code .diff.remove:before{content:"-";color:var(--vp-code-line-diff-remove-symbol-color)}.vp-doc [class*=language-] code .diff.add{background-color:var(--vp-code-line-diff-add-color)}.vp-doc [class*=language-] code .diff.add:before{content:"+";color:var(--vp-code-line-diff-add-symbol-color)}.vp-doc div[class*=language-].line-numbers-mode{padding-left:32px}.vp-doc .line-numbers-wrapper{position:absolute;top:0;bottom:0;left:0;z-index:3;border-right:1px solid var(--vp-code-block-divider-color);padding-top:20px;width:32px;text-align:center;font-family:var(--vp-font-family-mono);line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-line-number-color);transition:border-color .5s,color .5s}.vp-doc [class*=language-]>button.copy{direction:ltr;position:absolute;top:12px;right:12px;z-index:3;border:1px solid var(--vp-code-copy-code-border-color);border-radius:4px;width:40px;height:40px;background-color:var(--vp-code-copy-code-bg);opacity:0;cursor:pointer;background-image:var(--vp-icon-copy);background-position:50%;background-size:20px;background-repeat:no-repeat;transition:border-color .25s,background-color .25s,opacity .25s}.vp-doc [class*=language-]:hover>button.copy,.vp-doc [class*=language-]>button.copy:focus{opacity:1}.vp-doc [class*=language-]>button.copy:hover,.vp-doc [class*=language-]>button.copy.copied{border-color:var(--vp-code-copy-code-hover-border-color);background-color:var(--vp-code-copy-code-hover-bg)}.vp-doc [class*=language-]>button.copy.copied,.vp-doc [class*=language-]>button.copy:hover.copied{border-radius:0 4px 4px 0;background-color:var(--vp-code-copy-code-hover-bg);background-image:var(--vp-icon-copied)}.vp-doc [class*=language-]>button.copy.copied:before,.vp-doc [class*=language-]>button.copy:hover.copied:before{position:relative;top:-1px;transform:translate(calc(-100% - 1px));display:flex;justify-content:center;align-items:center;border:1px solid var(--vp-code-copy-code-hover-border-color);border-right:0;border-radius:4px 0 0 4px;padding:0 10px;width:fit-content;height:40px;text-align:center;font-size:12px;font-weight:500;color:var(--vp-code-copy-code-active-text);background-color:var(--vp-code-copy-code-hover-bg);white-space:nowrap;content:var(--vp-code-copy-copied-text-content)}.vp-doc [class*=language-]>span.lang{position:absolute;top:2px;right:8px;z-index:2;font-size:12px;font-weight:500;color:var(--vp-code-lang-color);transition:color .4s,opacity .4s}.vp-doc [class*=language-]:hover>button.copy+span.lang,.vp-doc [class*=language-]>button.copy:focus+span.lang{opacity:0}.vp-doc .VPTeamMembers{margin-top:24px}.vp-doc .VPTeamMembers.small.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}.vp-doc .VPTeamMembers.small.count-2 .container,.vp-doc .VPTeamMembers.small.count-3 .container{max-width:100%!important}.vp-doc .VPTeamMembers.medium.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}:is(.vp-external-link-icon,.vp-doc a[href*="://"],.vp-doc a[target=_blank]):not(.no-icon):after{display:inline-block;margin-top:-1px;margin-left:4px;width:11px;height:11px;background:currentColor;color:var(--vp-c-text-3);flex-shrink:0;--icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");-webkit-mask-image:var(--icon);mask-image:var(--icon)}.vp-external-link-icon:after{content:""}.external-link-icon-enabled :is(.vp-doc a[href*="://"],.vp-doc a[target=_blank]):after{content:"";color:currentColor}.vp-sponsor{border-radius:16px;overflow:hidden}.vp-sponsor.aside{border-radius:12px}.vp-sponsor-section+.vp-sponsor-section{margin-top:4px}.vp-sponsor-tier{margin:0 0 4px!important;text-align:center;letter-spacing:1px!important;line-height:24px;width:100%;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-sponsor.normal .vp-sponsor-tier{padding:13px 0 11px;font-size:14px}.vp-sponsor.aside .vp-sponsor-tier{padding:9px 0 7px;font-size:12px}.vp-sponsor-grid+.vp-sponsor-tier{margin-top:4px}.vp-sponsor-grid{display:flex;flex-wrap:wrap;gap:4px}.vp-sponsor-grid.xmini .vp-sponsor-grid-link{height:64px}.vp-sponsor-grid.xmini .vp-sponsor-grid-image{max-width:64px;max-height:22px}.vp-sponsor-grid.mini .vp-sponsor-grid-link{height:72px}.vp-sponsor-grid.mini .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.small .vp-sponsor-grid-link{height:96px}.vp-sponsor-grid.small .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.medium .vp-sponsor-grid-link{height:112px}.vp-sponsor-grid.medium .vp-sponsor-grid-image{max-width:120px;max-height:36px}.vp-sponsor-grid.big .vp-sponsor-grid-link{height:184px}.vp-sponsor-grid.big .vp-sponsor-grid-image{max-width:192px;max-height:56px}.vp-sponsor-grid[data-vp-grid="2"] .vp-sponsor-grid-item{width:calc((100% - 4px)/2)}.vp-sponsor-grid[data-vp-grid="3"] .vp-sponsor-grid-item{width:calc((100% - 4px * 2) / 3)}.vp-sponsor-grid[data-vp-grid="4"] .vp-sponsor-grid-item{width:calc((100% - 12px)/4)}.vp-sponsor-grid[data-vp-grid="5"] .vp-sponsor-grid-item{width:calc((100% - 16px)/5)}.vp-sponsor-grid[data-vp-grid="6"] .vp-sponsor-grid-item{width:calc((100% - 4px * 5) / 6)}.vp-sponsor-grid-item{flex-shrink:0;width:100%;background-color:var(--vp-c-bg-soft);transition:background-color .25s}.vp-sponsor-grid-item:hover{background-color:var(--vp-c-default-soft)}.vp-sponsor-grid-item:hover .vp-sponsor-grid-image{filter:grayscale(0) invert(0)}.vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.dark .vp-sponsor-grid-item:hover{background-color:var(--vp-c-white)}.dark .vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.vp-sponsor-grid-link{display:flex}.vp-sponsor-grid-box{display:flex;justify-content:center;align-items:center;width:100%}.vp-sponsor-grid-image{max-width:100%;filter:grayscale(1);transition:filter .25s}.dark .vp-sponsor-grid-image{filter:grayscale(1) invert(1)}.VPBadge{display:inline-block;margin-left:2px;border:1px solid transparent;border-radius:12px;padding:0 10px;line-height:22px;font-size:12px;font-weight:500;transform:translateY(-2px)}.VPBadge.small{padding:0 6px;line-height:18px;font-size:10px;transform:translateY(-8px)}.VPDocFooter .VPBadge{display:none}.vp-doc h1>.VPBadge{margin-top:4px;vertical-align:top}.vp-doc h2>.VPBadge{margin-top:3px;padding:0 8px;vertical-align:top}.vp-doc h3>.VPBadge{vertical-align:middle}.vp-doc h4>.VPBadge,.vp-doc h5>.VPBadge,.vp-doc h6>.VPBadge{vertical-align:middle;line-height:18px}.VPBadge.info{border-color:var(--vp-badge-info-border);color:var(--vp-badge-info-text);background-color:var(--vp-badge-info-bg)}.VPBadge.tip{border-color:var(--vp-badge-tip-border);color:var(--vp-badge-tip-text);background-color:var(--vp-badge-tip-bg)}.VPBadge.warning{border-color:var(--vp-badge-warning-border);color:var(--vp-badge-warning-text);background-color:var(--vp-badge-warning-bg)}.VPBadge.danger{border-color:var(--vp-badge-danger-border);color:var(--vp-badge-danger-text);background-color:var(--vp-badge-danger-bg)}.VPBackdrop[data-v-b06cdb19]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--vp-z-index-backdrop);background:var(--vp-backdrop-bg-color);transition:opacity .5s}.VPBackdrop.fade-enter-from[data-v-b06cdb19],.VPBackdrop.fade-leave-to[data-v-b06cdb19]{opacity:0}.VPBackdrop.fade-leave-active[data-v-b06cdb19]{transition-duration:.25s}@media (min-width: 1280px){.VPBackdrop[data-v-b06cdb19]{display:none}}.NotFound[data-v-792811ca]{padding:64px 24px 96px;text-align:center}@media (min-width: 768px){.NotFound[data-v-792811ca]{padding:96px 32px 168px}}.code[data-v-792811ca]{line-height:64px;font-size:64px;font-weight:600}.title[data-v-792811ca]{padding-top:12px;letter-spacing:2px;line-height:20px;font-size:20px;font-weight:700}.divider[data-v-792811ca]{margin:24px auto 18px;width:64px;height:1px;background-color:var(--vp-c-divider)}.quote[data-v-792811ca]{margin:0 auto;max-width:256px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.action[data-v-792811ca]{padding-top:20px}.link[data-v-792811ca]{display:inline-block;border:1px solid var(--vp-c-brand-1);border-radius:16px;padding:3px 16px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:border-color .25s,color .25s}.link[data-v-792811ca]:hover{border-color:var(--vp-c-brand-2);color:var(--vp-c-brand-2)}.root[data-v-3f927ebe]{position:relative;z-index:1}.nested[data-v-3f927ebe]{padding-right:16px;padding-left:16px}.outline-link[data-v-3f927ebe]{display:block;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .5s}.outline-link[data-v-3f927ebe]:hover,.outline-link.active[data-v-3f927ebe]{color:var(--vp-c-text-1);transition:color .25s}.outline-link.nested[data-v-3f927ebe]{padding-left:13px}.VPDocAsideOutline[data-v-c14bfc45]{display:none}.VPDocAsideOutline.has-outline[data-v-c14bfc45]{display:block}.content[data-v-c14bfc45]{position:relative;border-left:1px solid var(--vp-c-divider);padding-left:16px;font-size:13px;font-weight:500}.outline-marker[data-v-c14bfc45]{position:absolute;top:32px;left:-1px;z-index:0;opacity:0;width:2px;border-radius:2px;height:18px;background-color:var(--vp-c-brand-1);transition:top .25s cubic-bezier(0,1,.5,1),background-color .5s,opacity .25s}.outline-title[data-v-c14bfc45]{line-height:32px;font-size:14px;font-weight:600}.VPDocAside[data-v-6d7b3c46]{display:flex;flex-direction:column;flex-grow:1}.spacer[data-v-6d7b3c46]{flex-grow:1}.VPDocAside[data-v-6d7b3c46] .spacer+.VPDocAsideSponsors,.VPDocAside[data-v-6d7b3c46] .spacer+.VPDocAsideCarbonAds{margin-top:24px}.VPDocAside[data-v-6d7b3c46] .VPDocAsideSponsors+.VPDocAsideCarbonAds{margin-top:16px}.VPLastUpdated[data-v-9da12f1d]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 640px){.VPLastUpdated[data-v-9da12f1d]{line-height:32px;font-size:14px;font-weight:500}}.VPDocFooter[data-v-87be45d1]{margin-top:64px}.edit-info[data-v-87be45d1]{padding-bottom:18px}@media (min-width: 640px){.edit-info[data-v-87be45d1]{display:flex;justify-content:space-between;align-items:center;padding-bottom:14px}}.edit-link-button[data-v-87be45d1]{display:flex;align-items:center;border:0;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.edit-link-button[data-v-87be45d1]:hover{color:var(--vp-c-brand-2)}.edit-link-icon[data-v-87be45d1]{margin-right:8px}.prev-next[data-v-87be45d1]{border-top:1px solid var(--vp-c-divider);padding-top:24px;display:grid;grid-row-gap:8px}@media (min-width: 640px){.prev-next[data-v-87be45d1]{grid-template-columns:repeat(2,1fr);grid-column-gap:16px}}.pager-link[data-v-87be45d1]{display:block;border:1px solid var(--vp-c-divider);border-radius:8px;padding:11px 16px 13px;width:100%;height:100%;transition:border-color .25s}.pager-link[data-v-87be45d1]:hover{border-color:var(--vp-c-brand-1)}.pager-link.next[data-v-87be45d1]{margin-left:auto;text-align:right}.desc[data-v-87be45d1]{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.title[data-v-87be45d1]{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.VPDoc[data-v-83890dd9]{padding:32px 24px 96px;width:100%}@media (min-width: 768px){.VPDoc[data-v-83890dd9]{padding:48px 32px 128px}}@media (min-width: 960px){.VPDoc[data-v-83890dd9]{padding:48px 32px 0}.VPDoc:not(.has-sidebar) .container[data-v-83890dd9]{display:flex;justify-content:center;max-width:992px}.VPDoc:not(.has-sidebar) .content[data-v-83890dd9]{max-width:752px}}@media (min-width: 1280px){.VPDoc .container[data-v-83890dd9]{display:flex;justify-content:center}.VPDoc .aside[data-v-83890dd9]{display:block}}@media (min-width: 1440px){.VPDoc:not(.has-sidebar) .content[data-v-83890dd9]{max-width:784px}.VPDoc:not(.has-sidebar) .container[data-v-83890dd9]{max-width:1104px}}.container[data-v-83890dd9]{margin:0 auto;width:100%}.aside[data-v-83890dd9]{position:relative;display:none;order:2;flex-grow:1;padding-left:32px;width:100%;max-width:256px}.left-aside[data-v-83890dd9]{order:1;padding-left:unset;padding-right:32px}.aside-container[data-v-83890dd9]{position:fixed;top:0;padding-top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 48px);width:224px;height:100vh;overflow-x:hidden;overflow-y:auto;scrollbar-width:none}.aside-container[data-v-83890dd9]::-webkit-scrollbar{display:none}.aside-curtain[data-v-83890dd9]{position:fixed;bottom:0;z-index:10;width:224px;height:32px;background:linear-gradient(transparent,var(--vp-c-bg) 70%)}.aside-content[data-v-83890dd9]{display:flex;flex-direction:column;min-height:calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px));padding-bottom:32px}.content[data-v-83890dd9]{position:relative;margin:0 auto;width:100%}@media (min-width: 960px){.content[data-v-83890dd9]{padding:0 32px 128px}}@media (min-width: 1280px){.content[data-v-83890dd9]{order:1;margin:0;min-width:640px}}.content-container[data-v-83890dd9]{margin:0 auto}.VPDoc.has-aside .content-container[data-v-83890dd9]{max-width:688px}.VPButton[data-v-14206e74]{display:inline-block;border:1px solid transparent;text-align:center;font-weight:600;white-space:nowrap;transition:color .25s,border-color .25s,background-color .25s}.VPButton[data-v-14206e74]:active{transition:color .1s,border-color .1s,background-color .1s}.VPButton.medium[data-v-14206e74]{border-radius:20px;padding:0 20px;line-height:38px;font-size:14px}.VPButton.big[data-v-14206e74]{border-radius:24px;padding:0 24px;line-height:46px;font-size:16px}.VPButton.brand[data-v-14206e74]{border-color:var(--vp-button-brand-border);color:var(--vp-button-brand-text);background-color:var(--vp-button-brand-bg)}.VPButton.brand[data-v-14206e74]:hover{border-color:var(--vp-button-brand-hover-border);color:var(--vp-button-brand-hover-text);background-color:var(--vp-button-brand-hover-bg)}.VPButton.brand[data-v-14206e74]:active{border-color:var(--vp-button-brand-active-border);color:var(--vp-button-brand-active-text);background-color:var(--vp-button-brand-active-bg)}.VPButton.alt[data-v-14206e74]{border-color:var(--vp-button-alt-border);color:var(--vp-button-alt-text);background-color:var(--vp-button-alt-bg)}.VPButton.alt[data-v-14206e74]:hover{border-color:var(--vp-button-alt-hover-border);color:var(--vp-button-alt-hover-text);background-color:var(--vp-button-alt-hover-bg)}.VPButton.alt[data-v-14206e74]:active{border-color:var(--vp-button-alt-active-border);color:var(--vp-button-alt-active-text);background-color:var(--vp-button-alt-active-bg)}.VPButton.sponsor[data-v-14206e74]{border-color:var(--vp-button-sponsor-border);color:var(--vp-button-sponsor-text);background-color:var(--vp-button-sponsor-bg)}.VPButton.sponsor[data-v-14206e74]:hover{border-color:var(--vp-button-sponsor-hover-border);color:var(--vp-button-sponsor-hover-text);background-color:var(--vp-button-sponsor-hover-bg)}.VPButton.sponsor[data-v-14206e74]:active{border-color:var(--vp-button-sponsor-active-border);color:var(--vp-button-sponsor-active-text);background-color:var(--vp-button-sponsor-active-bg)}html:not(.dark) .VPImage.dark[data-v-35a7d0b8]{display:none}.dark .VPImage.light[data-v-35a7d0b8]{display:none}.VPHero[data-v-955009fc]{margin-top:calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px}@media (min-width: 640px){.VPHero[data-v-955009fc]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px}}@media (min-width: 960px){.VPHero[data-v-955009fc]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px}}.container[data-v-955009fc]{display:flex;flex-direction:column;margin:0 auto;max-width:1152px}@media (min-width: 960px){.container[data-v-955009fc]{flex-direction:row}}.main[data-v-955009fc]{position:relative;z-index:10;order:2;flex-grow:1;flex-shrink:0}.VPHero.has-image .container[data-v-955009fc]{text-align:center}@media (min-width: 960px){.VPHero.has-image .container[data-v-955009fc]{text-align:left}}@media (min-width: 960px){.main[data-v-955009fc]{order:1;width:calc((100% / 3) * 2)}.VPHero.has-image .main[data-v-955009fc]{max-width:592px}}.name[data-v-955009fc],.text[data-v-955009fc]{max-width:392px;letter-spacing:-.4px;line-height:40px;font-size:32px;font-weight:700;white-space:pre-wrap}.VPHero.has-image .name[data-v-955009fc],.VPHero.has-image .text[data-v-955009fc]{margin:0 auto}.name[data-v-955009fc]{color:var(--vp-home-hero-name-color)}.clip[data-v-955009fc]{background:var(--vp-home-hero-name-background);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:var(--vp-home-hero-name-color)}@media (min-width: 640px){.name[data-v-955009fc],.text[data-v-955009fc]{max-width:576px;line-height:56px;font-size:48px}}@media (min-width: 960px){.name[data-v-955009fc],.text[data-v-955009fc]{line-height:64px;font-size:56px}.VPHero.has-image .name[data-v-955009fc],.VPHero.has-image .text[data-v-955009fc]{margin:0}}.tagline[data-v-955009fc]{padding-top:8px;max-width:392px;line-height:28px;font-size:18px;font-weight:500;white-space:pre-wrap;color:var(--vp-c-text-2)}.VPHero.has-image .tagline[data-v-955009fc]{margin:0 auto}@media (min-width: 640px){.tagline[data-v-955009fc]{padding-top:12px;max-width:576px;line-height:32px;font-size:20px}}@media (min-width: 960px){.tagline[data-v-955009fc]{line-height:36px;font-size:24px}.VPHero.has-image .tagline[data-v-955009fc]{margin:0}}.actions[data-v-955009fc]{display:flex;flex-wrap:wrap;margin:-6px;padding-top:24px}.VPHero.has-image .actions[data-v-955009fc]{justify-content:center}@media (min-width: 640px){.actions[data-v-955009fc]{padding-top:32px}}@media (min-width: 960px){.VPHero.has-image .actions[data-v-955009fc]{justify-content:flex-start}}.action[data-v-955009fc]{flex-shrink:0;padding:6px}.image[data-v-955009fc]{order:1;margin:-76px -24px -48px}@media (min-width: 640px){.image[data-v-955009fc]{margin:-108px -24px -48px}}@media (min-width: 960px){.image[data-v-955009fc]{flex-grow:1;order:2;margin:0;min-height:100%}}.image-container[data-v-955009fc]{position:relative;margin:0 auto;width:320px;height:320px}@media (min-width: 640px){.image-container[data-v-955009fc]{width:392px;height:392px}}@media (min-width: 960px){.image-container[data-v-955009fc]{display:flex;justify-content:center;align-items:center;width:100%;height:100%;transform:translate(-32px,-32px)}}.image-bg[data-v-955009fc]{position:absolute;top:50%;left:50%;border-radius:50%;width:192px;height:192px;background-image:var(--vp-home-hero-image-background-image);filter:var(--vp-home-hero-image-filter);transform:translate(-50%,-50%)}@media (min-width: 640px){.image-bg[data-v-955009fc]{width:256px;height:256px}}@media (min-width: 960px){.image-bg[data-v-955009fc]{width:320px;height:320px}}[data-v-955009fc] .image-src{position:absolute;top:50%;left:50%;max-width:192px;max-height:192px;transform:translate(-50%,-50%)}@media (min-width: 640px){[data-v-955009fc] .image-src{max-width:256px;max-height:256px}}@media (min-width: 960px){[data-v-955009fc] .image-src{max-width:320px;max-height:320px}}.VPFeature[data-v-f5e9645b]{display:block;border:1px solid var(--vp-c-bg-soft);border-radius:12px;height:100%;background-color:var(--vp-c-bg-soft);transition:border-color .25s,background-color .25s}.VPFeature.link[data-v-f5e9645b]:hover{border-color:var(--vp-c-brand-1)}.box[data-v-f5e9645b]{display:flex;flex-direction:column;padding:24px;height:100%}.box[data-v-f5e9645b]>.VPImage{margin-bottom:20px}.icon[data-v-f5e9645b]{display:flex;justify-content:center;align-items:center;margin-bottom:20px;border-radius:6px;background-color:var(--vp-c-default-soft);width:48px;height:48px;font-size:24px;transition:background-color .25s}.title[data-v-f5e9645b]{line-height:24px;font-size:16px;font-weight:600}.details[data-v-f5e9645b]{flex-grow:1;padding-top:8px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.link-text[data-v-f5e9645b]{padding-top:8px}.link-text-value[data-v-f5e9645b]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.link-text-icon[data-v-f5e9645b]{margin-left:6px}.VPFeatures[data-v-d0a190d7]{position:relative;padding:0 24px}@media (min-width: 640px){.VPFeatures[data-v-d0a190d7]{padding:0 48px}}@media (min-width: 960px){.VPFeatures[data-v-d0a190d7]{padding:0 64px}}.container[data-v-d0a190d7]{margin:0 auto;max-width:1152px}.items[data-v-d0a190d7]{display:flex;flex-wrap:wrap;margin:-8px}.item[data-v-d0a190d7]{padding:8px;width:100%}@media (min-width: 640px){.item.grid-2[data-v-d0a190d7],.item.grid-4[data-v-d0a190d7],.item.grid-6[data-v-d0a190d7]{width:50%}}@media (min-width: 768px){.item.grid-2[data-v-d0a190d7],.item.grid-4[data-v-d0a190d7]{width:50%}.item.grid-3[data-v-d0a190d7],.item.grid-6[data-v-d0a190d7]{width:calc(100% / 3)}}@media (min-width: 960px){.item.grid-4[data-v-d0a190d7]{width:25%}}.container[data-v-c43247eb]{margin:auto;width:100%;max-width:1280px;padding:0 24px}@media (min-width: 640px){.container[data-v-c43247eb]{padding:0 48px}}@media (min-width: 960px){.container[data-v-c43247eb]{width:100%;padding:0 64px}}.vp-doc[data-v-c43247eb] .VPHomeSponsors,.vp-doc[data-v-c43247eb] .VPTeamPage{margin-left:var(--vp-offset, calc(50% - 50vw) );margin-right:var(--vp-offset, calc(50% - 50vw) )}.vp-doc[data-v-c43247eb] .VPHomeSponsors h2{border-top:none;letter-spacing:normal}.vp-doc[data-v-c43247eb] .VPHomeSponsors a,.vp-doc[data-v-c43247eb] .VPTeamPage a{text-decoration:none}.VPHome[data-v-cbb6ec48]{margin-bottom:96px}@media (min-width: 768px){.VPHome[data-v-cbb6ec48]{margin-bottom:128px}}.VPContent[data-v-91765379]{flex-grow:1;flex-shrink:0;margin:var(--vp-layout-top-height, 0px) auto 0;width:100%}.VPContent.is-home[data-v-91765379]{width:100%;max-width:100%}.VPContent.has-sidebar[data-v-91765379]{margin:0}@media (min-width: 960px){.VPContent[data-v-91765379]{padding-top:var(--vp-nav-height)}.VPContent.has-sidebar[data-v-91765379]{margin:var(--vp-layout-top-height, 0px) 0 0;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPContent.has-sidebar[data-v-91765379]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.VPFooter[data-v-c970a860]{position:relative;z-index:var(--vp-z-index-footer);border-top:1px solid var(--vp-c-gutter);padding:32px 24px;background-color:var(--vp-c-bg)}.VPFooter.has-sidebar[data-v-c970a860]{display:none}.VPFooter[data-v-c970a860] a{text-decoration-line:underline;text-underline-offset:2px;transition:color .25s}.VPFooter[data-v-c970a860] a:hover{color:var(--vp-c-text-1)}@media (min-width: 768px){.VPFooter[data-v-c970a860]{padding:32px}}.container[data-v-c970a860]{margin:0 auto;max-width:var(--vp-layout-max-width);text-align:center}.message[data-v-c970a860],.copyright[data-v-c970a860]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.VPLocalNavOutlineDropdown[data-v-c9ba27ad]{padding:12px 20px 11px}@media (min-width: 960px){.VPLocalNavOutlineDropdown[data-v-c9ba27ad]{padding:12px 36px 11px}}.VPLocalNavOutlineDropdown button[data-v-c9ba27ad]{display:block;font-size:12px;font-weight:500;line-height:24px;color:var(--vp-c-text-2);transition:color .5s;position:relative}.VPLocalNavOutlineDropdown button[data-v-c9ba27ad]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPLocalNavOutlineDropdown button.open[data-v-c9ba27ad]{color:var(--vp-c-text-1)}.icon[data-v-c9ba27ad]{display:inline-block;vertical-align:middle;margin-left:2px;font-size:14px;transform:rotate(0);transition:transform .25s}@media (min-width: 960px){.VPLocalNavOutlineDropdown button[data-v-c9ba27ad]{font-size:14px}.icon[data-v-c9ba27ad]{font-size:16px}}.open>.icon[data-v-c9ba27ad]{transform:rotate(90deg)}.items[data-v-c9ba27ad]{position:absolute;top:40px;right:16px;left:16px;display:grid;gap:1px;border:1px solid var(--vp-c-border);border-radius:8px;background-color:var(--vp-c-gutter);max-height:calc(var(--vp-vh, 100vh) - 86px);overflow:hidden auto;box-shadow:var(--vp-shadow-3)}@media (min-width: 960px){.items[data-v-c9ba27ad]{right:auto;left:calc(var(--vp-sidebar-width) + 32px);width:320px}}.header[data-v-c9ba27ad]{background-color:var(--vp-c-bg-soft)}.top-link[data-v-c9ba27ad]{display:block;padding:0 16px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.outline[data-v-c9ba27ad]{padding:8px 0;background-color:var(--vp-c-bg-soft)}.flyout-enter-active[data-v-c9ba27ad]{transition:all .2s ease-out}.flyout-leave-active[data-v-c9ba27ad]{transition:all .15s ease-in}.flyout-enter-from[data-v-c9ba27ad],.flyout-leave-to[data-v-c9ba27ad]{opacity:0;transform:translateY(-16px)}.VPLocalNav[data-v-070ab83d]{position:sticky;top:0;left:0;z-index:var(--vp-z-index-local-nav);border-bottom:1px solid var(--vp-c-gutter);padding-top:var(--vp-layout-top-height, 0px);width:100%;background-color:var(--vp-local-nav-bg-color)}.VPLocalNav.fixed[data-v-070ab83d]{position:fixed}@media (min-width: 960px){.VPLocalNav[data-v-070ab83d]{top:var(--vp-nav-height)}.VPLocalNav.has-sidebar[data-v-070ab83d]{padding-left:var(--vp-sidebar-width)}.VPLocalNav.empty[data-v-070ab83d]{display:none}}@media (min-width: 1280px){.VPLocalNav[data-v-070ab83d]{display:none}}@media (min-width: 1440px){.VPLocalNav.has-sidebar[data-v-070ab83d]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.container[data-v-070ab83d]{display:flex;justify-content:space-between;align-items:center}.menu[data-v-070ab83d]{display:flex;align-items:center;padding:12px 24px 11px;line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.menu[data-v-070ab83d]:hover{color:var(--vp-c-text-1);transition:color .25s}@media (min-width: 768px){.menu[data-v-070ab83d]{padding:0 32px}}@media (min-width: 960px){.menu[data-v-070ab83d]{display:none}}.menu-icon[data-v-070ab83d]{margin-right:8px;font-size:14px}.VPOutlineDropdown[data-v-070ab83d]{padding:12px 24px 11px}@media (min-width: 768px){.VPOutlineDropdown[data-v-070ab83d]{padding:12px 32px 11px}}.VPSwitch[data-v-4a1c76db]{position:relative;border-radius:11px;display:block;width:40px;height:22px;flex-shrink:0;border:1px solid var(--vp-input-border-color);background-color:var(--vp-input-switch-bg-color);transition:border-color .25s!important}.VPSwitch[data-v-4a1c76db]:hover{border-color:var(--vp-c-brand-1)}.check[data-v-4a1c76db]{position:absolute;top:1px;left:1px;width:18px;height:18px;border-radius:50%;background-color:var(--vp-c-neutral-inverse);box-shadow:var(--vp-shadow-1);transition:transform .25s!important}.icon[data-v-4a1c76db]{position:relative;display:block;width:18px;height:18px;border-radius:50%;overflow:hidden}.icon[data-v-4a1c76db] [class^=vpi-]{position:absolute;top:3px;left:3px;width:12px;height:12px;color:var(--vp-c-text-2)}.dark .icon[data-v-4a1c76db] [class^=vpi-]{color:var(--vp-c-text-1);transition:opacity .25s!important}.sun[data-v-b79b56d4]{opacity:1}.moon[data-v-b79b56d4],.dark .sun[data-v-b79b56d4]{opacity:0}.dark .moon[data-v-b79b56d4]{opacity:1}.dark .VPSwitchAppearance[data-v-b79b56d4] .check{transform:translate(18px)}.VPNavBarAppearance[data-v-ead91a81]{display:none}@media (min-width: 1280px){.VPNavBarAppearance[data-v-ead91a81]{display:flex;align-items:center}}.VPMenuGroup+.VPMenuLink[data-v-8b74d055]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.link[data-v-8b74d055]{display:block;border-radius:6px;padding:0 12px;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);white-space:nowrap;transition:background-color .25s,color .25s}.link[data-v-8b74d055]:hover{color:var(--vp-c-brand-1);background-color:var(--vp-c-default-soft)}.link.active[data-v-8b74d055]{color:var(--vp-c-brand-1)}.VPMenuGroup[data-v-48c802d0]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.VPMenuGroup[data-v-48c802d0]:first-child{margin-top:0;border-top:0;padding-top:0}.VPMenuGroup+.VPMenuGroup[data-v-48c802d0]{margin-top:12px;border-top:1px solid var(--vp-c-divider)}.title[data-v-48c802d0]{padding:0 12px;line-height:32px;font-size:14px;font-weight:600;color:var(--vp-c-text-2);white-space:nowrap;transition:color .25s}.VPMenu[data-v-97491713]{border-radius:12px;padding:12px;min-width:128px;border:1px solid var(--vp-c-divider);background-color:var(--vp-c-bg-elv);box-shadow:var(--vp-shadow-3);transition:background-color .5s;max-height:calc(100vh - var(--vp-nav-height));overflow-y:auto}.VPMenu[data-v-97491713] .group{margin:0 -12px;padding:0 12px 12px}.VPMenu[data-v-97491713] .group+.group{border-top:1px solid var(--vp-c-divider);padding:11px 12px 12px}.VPMenu[data-v-97491713] .group:last-child{padding-bottom:0}.VPMenu[data-v-97491713] .group+.item{border-top:1px solid var(--vp-c-divider);padding:11px 16px 0}.VPMenu[data-v-97491713] .item{padding:0 16px;white-space:nowrap}.VPMenu[data-v-97491713] .label{flex-grow:1;line-height:28px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.VPMenu[data-v-97491713] .action{padding-left:24px}.VPFlyout[data-v-e5380155]{position:relative}.VPFlyout[data-v-e5380155]:hover{color:var(--vp-c-brand-1);transition:color .25s}.VPFlyout:hover .text[data-v-e5380155]{color:var(--vp-c-text-2)}.VPFlyout:hover .icon[data-v-e5380155]{fill:var(--vp-c-text-2)}.VPFlyout.active .text[data-v-e5380155]{color:var(--vp-c-brand-1)}.VPFlyout.active:hover .text[data-v-e5380155]{color:var(--vp-c-brand-2)}.VPFlyout:hover .menu[data-v-e5380155],.button[aria-expanded=true]+.menu[data-v-e5380155]{opacity:1;visibility:visible;transform:translateY(0)}.button[aria-expanded=false]+.menu[data-v-e5380155]{opacity:0;visibility:hidden;transform:translateY(0)}.button[data-v-e5380155]{display:flex;align-items:center;padding:0 12px;height:var(--vp-nav-height);color:var(--vp-c-text-1);transition:color .5s}.text[data-v-e5380155]{display:flex;align-items:center;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.option-icon[data-v-e5380155]{margin-right:0;font-size:16px}.text-icon[data-v-e5380155]{margin-left:4px;font-size:14px}.icon[data-v-e5380155]{font-size:20px;transition:fill .25s}.menu[data-v-e5380155]{position:absolute;top:calc(var(--vp-nav-height) / 2 + 20px);right:0;opacity:0;visibility:hidden;transition:opacity .25s,visibility .25s,transform .25s}.VPSocialLink[data-v-717b8b75]{display:flex;justify-content:center;align-items:center;width:36px;height:36px;color:var(--vp-c-text-2);transition:color .5s}.VPSocialLink[data-v-717b8b75]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPSocialLink[data-v-717b8b75]>svg,.VPSocialLink[data-v-717b8b75]>[class^=vpi-social-]{width:20px;height:20px;fill:currentColor}.VPSocialLinks[data-v-ee7a9424]{display:flex;justify-content:center}.VPNavBarExtra[data-v-9b536d0b]{display:none;margin-right:-12px}@media (min-width: 768px){.VPNavBarExtra[data-v-9b536d0b]{display:block}}@media (min-width: 1280px){.VPNavBarExtra[data-v-9b536d0b]{display:none}}.trans-title[data-v-9b536d0b]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.item.appearance[data-v-9b536d0b],.item.social-links[data-v-9b536d0b]{display:flex;align-items:center;padding:0 12px}.item.appearance[data-v-9b536d0b]{min-width:176px}.appearance-action[data-v-9b536d0b]{margin-right:-2px}.social-links-list[data-v-9b536d0b]{margin:-4px -8px}.VPNavBarHamburger[data-v-5dea55bf]{display:flex;justify-content:center;align-items:center;width:48px;height:var(--vp-nav-height)}@media (min-width: 768px){.VPNavBarHamburger[data-v-5dea55bf]{display:none}}.container[data-v-5dea55bf]{position:relative;width:16px;height:14px;overflow:hidden}.VPNavBarHamburger:hover .top[data-v-5dea55bf]{top:0;left:0;transform:translate(4px)}.VPNavBarHamburger:hover .middle[data-v-5dea55bf]{top:6px;left:0;transform:translate(0)}.VPNavBarHamburger:hover .bottom[data-v-5dea55bf]{top:12px;left:0;transform:translate(8px)}.VPNavBarHamburger.active .top[data-v-5dea55bf]{top:6px;transform:translate(0) rotate(225deg)}.VPNavBarHamburger.active .middle[data-v-5dea55bf]{top:6px;transform:translate(16px)}.VPNavBarHamburger.active .bottom[data-v-5dea55bf]{top:6px;transform:translate(0) rotate(135deg)}.VPNavBarHamburger.active:hover .top[data-v-5dea55bf],.VPNavBarHamburger.active:hover .middle[data-v-5dea55bf],.VPNavBarHamburger.active:hover .bottom[data-v-5dea55bf]{background-color:var(--vp-c-text-2);transition:top .25s,background-color .25s,transform .25s}.top[data-v-5dea55bf],.middle[data-v-5dea55bf],.bottom[data-v-5dea55bf]{position:absolute;width:16px;height:2px;background-color:var(--vp-c-text-1);transition:top .25s,background-color .5s,transform .25s}.top[data-v-5dea55bf]{top:0;left:0;transform:translate(0)}.middle[data-v-5dea55bf]{top:6px;left:0;transform:translate(8px)}.bottom[data-v-5dea55bf]{top:12px;left:0;transform:translate(4px)}.VPNavBarMenuLink[data-v-2781b5e7]{display:flex;align-items:center;padding:0 12px;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.VPNavBarMenuLink.active[data-v-2781b5e7],.VPNavBarMenuLink[data-v-2781b5e7]:hover{color:var(--vp-c-brand-1)}.VPNavBarMenu[data-v-492ea56d]{display:none}@media (min-width: 768px){.VPNavBarMenu[data-v-492ea56d]{display:flex}}/*! @docsearch/css 3.6.0 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 1px 0 rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 1px 1px 0 rgba(3,4,9,.30196078431372547);--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;-webkit-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;position:relative;padding:0 0 2px;border:0;top:-1px;width:20px}.DocSearch-Button-Key--pressed{transform:translate3d(0,1px,0);box-shadow:var(--docsearch-key-pressed-shadow)}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{animation:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0;stroke-width:var(--docsearch-icon-stroke-width)}}.DocSearch-Reset{animation:fade-in .1s ease-in forwards;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0;stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;stroke-width:var(--docsearch-icon-stroke-width);width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color);stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:2px;box-shadow:var(--docsearch-key-shadow);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;color:var(--docsearch-muted-color);border:0;width:20px}.DocSearch-VisuallyHiddenForAccessibility{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;-webkit-user-select:none;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}[class*=DocSearch]{--docsearch-primary-color: var(--vp-c-brand-1);--docsearch-highlight-color: var(--docsearch-primary-color);--docsearch-text-color: var(--vp-c-text-1);--docsearch-muted-color: var(--vp-c-text-2);--docsearch-searchbox-shadow: none;--docsearch-searchbox-background: transparent;--docsearch-searchbox-focus-background: transparent;--docsearch-key-gradient: transparent;--docsearch-key-shadow: none;--docsearch-modal-background: var(--vp-c-bg-soft);--docsearch-footer-background: var(--vp-c-bg)}.dark [class*=DocSearch]{--docsearch-modal-shadow: none;--docsearch-footer-shadow: none;--docsearch-logo-color: var(--vp-c-text-2);--docsearch-hit-background: var(--vp-c-default-soft);--docsearch-hit-color: var(--vp-c-text-2);--docsearch-hit-shadow: none}.DocSearch-Button{display:flex;justify-content:center;align-items:center;margin:0;padding:0;width:48px;height:55px;background:transparent;transition:border-color .25s}.DocSearch-Button:hover{background:transparent}.DocSearch-Button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.DocSearch-Button:focus:not(:focus-visible){outline:none!important}@media (min-width: 768px){.DocSearch-Button{justify-content:flex-start;border:1px solid transparent;border-radius:8px;padding:0 10px 0 12px;width:100%;height:40px;background-color:var(--vp-c-bg-alt)}.DocSearch-Button:hover{border-color:var(--vp-c-brand-1);background:var(--vp-c-bg-alt)}}.DocSearch-Button .DocSearch-Button-Container{display:flex;align-items:center}.DocSearch-Button .DocSearch-Search-Icon{position:relative;width:16px;height:16px;color:var(--vp-c-text-1);fill:currentColor;transition:color .5s}.DocSearch-Button:hover .DocSearch-Search-Icon{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Search-Icon{top:1px;margin-right:8px;width:14px;height:14px;color:var(--vp-c-text-2)}}.DocSearch-Button .DocSearch-Button-Placeholder{display:none;margin-top:2px;padding:0 16px 0 0;font-size:13px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.DocSearch-Button:hover .DocSearch-Button-Placeholder{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Placeholder{display:inline-block}}.DocSearch-Button .DocSearch-Button-Keys{direction:ltr;display:none;min-width:auto}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Keys{display:flex;align-items:center}}.DocSearch-Button .DocSearch-Button-Key{display:block;margin:2px 0 0;border:1px solid var(--vp-c-divider);border-right:none;border-radius:4px 0 0 4px;padding-left:6px;min-width:0;width:auto;height:22px;line-height:22px;font-family:var(--vp-font-family-base);font-size:12px;font-weight:500;transition:color .5s,border-color .5s}.DocSearch-Button .DocSearch-Button-Key+.DocSearch-Button-Key{border-right:1px solid var(--vp-c-divider);border-left:none;border-radius:0 4px 4px 0;padding-left:2px;padding-right:6px}.DocSearch-Button .DocSearch-Button-Key:first-child{font-size:0!important}.DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"Ctrl";font-size:12px;letter-spacing:normal;color:var(--docsearch-muted-color)}.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"⌘"}.DocSearch-Button .DocSearch-Button-Key:first-child>*{display:none}.DocSearch-Search-Icon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke-width='1.6' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' d='m14.386 14.386 4.088 4.088-4.088-4.088A7.533 7.533 0 1 1 3.733 3.733a7.533 7.533 0 0 1 10.653 10.653z'/%3E%3C/svg%3E")}.VPNavBarSearch{display:flex;align-items:center}@media (min-width: 768px){.VPNavBarSearch{flex-grow:1;padding-left:24px}}@media (min-width: 960px){.VPNavBarSearch{padding-left:32px}}.dark .DocSearch-Footer{border-top:1px solid var(--vp-c-divider)}.DocSearch-Form{border:1px solid var(--vp-c-brand-1);background-color:var(--vp-c-white)}.dark .DocSearch-Form{background-color:var(--vp-c-default-soft)}.DocSearch-Screen-Icon>svg{margin:auto}.VPNavBarSocialLinks[data-v-164c457f]{display:none}@media (min-width: 1280px){.VPNavBarSocialLinks[data-v-164c457f]{display:flex;align-items:center}}.title[data-v-28a961f9]{display:flex;align-items:center;border-bottom:1px solid transparent;width:100%;height:var(--vp-nav-height);font-size:16px;font-weight:600;color:var(--vp-c-text-1);transition:opacity .25s}@media (min-width: 960px){.title[data-v-28a961f9]{flex-shrink:0}.VPNavBarTitle.has-sidebar .title[data-v-28a961f9]{border-bottom-color:var(--vp-c-divider)}}[data-v-28a961f9] .logo{margin-right:8px;height:var(--vp-nav-logo-height)}.VPNavBarTranslations[data-v-c80d9ad0]{display:none}@media (min-width: 1280px){.VPNavBarTranslations[data-v-c80d9ad0]{display:flex;align-items:center}}.title[data-v-c80d9ad0]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.VPNavBar[data-v-b9c8b02d]{position:relative;height:var(--vp-nav-height);pointer-events:none;white-space:nowrap;transition:background-color .5s}.VPNavBar.has-local-nav[data-v-b9c8b02d]{background-color:var(--vp-nav-bg-color)}@media (min-width: 960px){.VPNavBar.has-local-nav[data-v-b9c8b02d]{background-color:transparent}.VPNavBar[data-v-b9c8b02d]:not(.has-sidebar):not(.top){background-color:var(--vp-nav-bg-color)}}.wrapper[data-v-b9c8b02d]{padding:0 8px 0 24px}@media (min-width: 768px){.wrapper[data-v-b9c8b02d]{padding:0 32px}}@media (min-width: 960px){.VPNavBar.has-sidebar .wrapper[data-v-b9c8b02d]{padding:0}}.container[data-v-b9c8b02d]{display:flex;justify-content:space-between;margin:0 auto;max-width:calc(var(--vp-layout-max-width) - 64px);height:var(--vp-nav-height);pointer-events:none}.container>.title[data-v-b9c8b02d],.container>.content[data-v-b9c8b02d]{pointer-events:none}.container[data-v-b9c8b02d] *{pointer-events:auto}@media (min-width: 960px){.VPNavBar.has-sidebar .container[data-v-b9c8b02d]{max-width:100%}}.title[data-v-b9c8b02d]{flex-shrink:0;height:calc(var(--vp-nav-height) - 1px);transition:background-color .5s}@media (min-width: 960px){.VPNavBar.has-sidebar .title[data-v-b9c8b02d]{position:absolute;top:0;left:0;z-index:2;padding:0 32px;width:var(--vp-sidebar-width);height:var(--vp-nav-height);background-color:transparent}}@media (min-width: 1440px){.VPNavBar.has-sidebar .title[data-v-b9c8b02d]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}.content[data-v-b9c8b02d]{flex-grow:1}@media (min-width: 960px){.VPNavBar.has-sidebar .content[data-v-b9c8b02d]{position:relative;z-index:1;padding-right:32px;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .content[data-v-b9c8b02d]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2 + 32px);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.content-body[data-v-b9c8b02d]{display:flex;justify-content:flex-end;align-items:center;height:var(--vp-nav-height);transition:background-color .5s}@media (min-width: 960px){.VPNavBar:not(.top) .content-body[data-v-b9c8b02d]{position:relative;background-color:var(--vp-nav-bg-color)}.VPNavBar:not(.has-sidebar):not(.top) .content-body[data-v-b9c8b02d]{background-color:transparent}}@media (max-width: 767px){.content-body[data-v-b9c8b02d]{column-gap:.5rem}}.menu+.translations[data-v-b9c8b02d]:before,.menu+.appearance[data-v-b9c8b02d]:before,.menu+.social-links[data-v-b9c8b02d]:before,.translations+.appearance[data-v-b9c8b02d]:before,.appearance+.social-links[data-v-b9c8b02d]:before{margin-right:8px;margin-left:8px;width:1px;height:24px;background-color:var(--vp-c-divider);content:""}.menu+.appearance[data-v-b9c8b02d]:before,.translations+.appearance[data-v-b9c8b02d]:before{margin-right:16px}.appearance+.social-links[data-v-b9c8b02d]:before{margin-left:16px}.social-links[data-v-b9c8b02d]{margin-right:-8px}.divider[data-v-b9c8b02d]{width:100%;height:1px}@media (min-width: 960px){.VPNavBar.has-sidebar .divider[data-v-b9c8b02d]{padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .divider[data-v-b9c8b02d]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.divider-line[data-v-b9c8b02d]{width:100%;height:1px;transition:background-color .5s}.VPNavBar.has-local-nav .divider-line[data-v-b9c8b02d]{background-color:var(--vp-c-gutter)}@media (min-width: 960px){.VPNavBar:not(.top) .divider-line[data-v-b9c8b02d]{background-color:var(--vp-c-gutter)}.VPNavBar:not(.has-sidebar):not(.top) .divider[data-v-b9c8b02d]{background-color:var(--vp-c-gutter)}}.VPNavScreenAppearance[data-v-2b89f08b]{display:flex;justify-content:space-between;align-items:center;border-radius:8px;padding:12px 14px 12px 16px;background-color:var(--vp-c-bg-soft)}.text[data-v-2b89f08b]{line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.VPNavScreenMenuLink[data-v-d45ba3e8]{display:block;border-bottom:1px solid var(--vp-c-divider);padding:12px 0 11px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:border-color .25s,color .25s}.VPNavScreenMenuLink[data-v-d45ba3e8]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupLink[data-v-7179dbb7]{display:block;margin-left:12px;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-1);transition:color .25s}.VPNavScreenMenuGroupLink[data-v-7179dbb7]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupSection[data-v-4b8941ac]{display:block}.title[data-v-4b8941ac]{line-height:32px;font-size:13px;font-weight:700;color:var(--vp-c-text-2);transition:color .25s}.VPNavScreenMenuGroup[data-v-c9df2649]{border-bottom:1px solid var(--vp-c-divider);height:48px;overflow:hidden;transition:border-color .5s}.VPNavScreenMenuGroup .items[data-v-c9df2649]{visibility:hidden}.VPNavScreenMenuGroup.open .items[data-v-c9df2649]{visibility:visible}.VPNavScreenMenuGroup.open[data-v-c9df2649]{padding-bottom:10px;height:auto}.VPNavScreenMenuGroup.open .button[data-v-c9df2649]{padding-bottom:6px;color:var(--vp-c-brand-1)}.VPNavScreenMenuGroup.open .button-icon[data-v-c9df2649]{transform:rotate(45deg)}.button[data-v-c9df2649]{display:flex;justify-content:space-between;align-items:center;padding:12px 4px 11px 0;width:100%;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.button[data-v-c9df2649]:hover{color:var(--vp-c-brand-1)}.button-icon[data-v-c9df2649]{transition:transform .25s}.group[data-v-c9df2649]:first-child{padding-top:0}.group+.group[data-v-c9df2649],.group+.item[data-v-c9df2649]{padding-top:4px}.VPNavScreenTranslations[data-v-362991c2]{height:24px;overflow:hidden}.VPNavScreenTranslations.open[data-v-362991c2]{height:auto}.title[data-v-362991c2]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-text-1)}.icon[data-v-362991c2]{font-size:16px}.icon.lang[data-v-362991c2]{margin-right:8px}.icon.chevron[data-v-362991c2]{margin-left:4px}.list[data-v-362991c2]{padding:4px 0 0 24px}.link[data-v-362991c2]{line-height:32px;font-size:13px;color:var(--vp-c-text-1)}.VPNavScreen[data-v-382f42e9]{position:fixed;top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 1px);right:0;bottom:0;left:0;padding:0 32px;width:100%;background-color:var(--vp-nav-screen-bg-color);overflow-y:auto;transition:background-color .5s;pointer-events:auto}.VPNavScreen.fade-enter-active[data-v-382f42e9],.VPNavScreen.fade-leave-active[data-v-382f42e9]{transition:opacity .25s}.VPNavScreen.fade-enter-active .container[data-v-382f42e9],.VPNavScreen.fade-leave-active .container[data-v-382f42e9]{transition:transform .25s ease}.VPNavScreen.fade-enter-from[data-v-382f42e9],.VPNavScreen.fade-leave-to[data-v-382f42e9]{opacity:0}.VPNavScreen.fade-enter-from .container[data-v-382f42e9],.VPNavScreen.fade-leave-to .container[data-v-382f42e9]{transform:translateY(-8px)}@media (min-width: 768px){.VPNavScreen[data-v-382f42e9]{display:none}}.container[data-v-382f42e9]{margin:0 auto;padding:24px 0 96px;max-width:288px}.menu+.translations[data-v-382f42e9],.menu+.appearance[data-v-382f42e9],.translations+.appearance[data-v-382f42e9]{margin-top:24px}.menu+.social-links[data-v-382f42e9]{margin-top:16px}.appearance+.social-links[data-v-382f42e9]{margin-top:16px}.VPNav[data-v-f1e365da]{position:relative;top:var(--vp-layout-top-height, 0px);left:0;z-index:var(--vp-z-index-nav);width:100%;pointer-events:none;transition:background-color .5s}@media (min-width: 960px){.VPNav[data-v-f1e365da]{position:fixed}}.VPSidebarItem.level-0[data-v-f24171a4]{padding-bottom:24px}.VPSidebarItem.collapsed.level-0[data-v-f24171a4]{padding-bottom:10px}.item[data-v-f24171a4]{position:relative;display:flex;width:100%}.VPSidebarItem.collapsible>.item[data-v-f24171a4]{cursor:pointer}.indicator[data-v-f24171a4]{position:absolute;top:6px;bottom:6px;left:-17px;width:2px;border-radius:2px;transition:background-color .25s}.VPSidebarItem.level-2.is-active>.item>.indicator[data-v-f24171a4],.VPSidebarItem.level-3.is-active>.item>.indicator[data-v-f24171a4],.VPSidebarItem.level-4.is-active>.item>.indicator[data-v-f24171a4],.VPSidebarItem.level-5.is-active>.item>.indicator[data-v-f24171a4]{background-color:var(--vp-c-brand-1)}.link[data-v-f24171a4]{display:flex;align-items:center;flex-grow:1}.text[data-v-f24171a4]{flex-grow:1;padding:4px 0;line-height:24px;font-size:14px;transition:color .25s}.VPSidebarItem.level-0 .text[data-v-f24171a4]{font-weight:700;color:var(--vp-c-text-1)}.VPSidebarItem.level-1 .text[data-v-f24171a4],.VPSidebarItem.level-2 .text[data-v-f24171a4],.VPSidebarItem.level-3 .text[data-v-f24171a4],.VPSidebarItem.level-4 .text[data-v-f24171a4],.VPSidebarItem.level-5 .text[data-v-f24171a4]{font-weight:500;color:var(--vp-c-text-2)}.VPSidebarItem.level-0.is-link>.item>.link:hover .text[data-v-f24171a4],.VPSidebarItem.level-1.is-link>.item>.link:hover .text[data-v-f24171a4],.VPSidebarItem.level-2.is-link>.item>.link:hover .text[data-v-f24171a4],.VPSidebarItem.level-3.is-link>.item>.link:hover .text[data-v-f24171a4],.VPSidebarItem.level-4.is-link>.item>.link:hover .text[data-v-f24171a4],.VPSidebarItem.level-5.is-link>.item>.link:hover .text[data-v-f24171a4]{color:var(--vp-c-brand-1)}.VPSidebarItem.level-0.has-active>.item>.text[data-v-f24171a4],.VPSidebarItem.level-1.has-active>.item>.text[data-v-f24171a4],.VPSidebarItem.level-2.has-active>.item>.text[data-v-f24171a4],.VPSidebarItem.level-3.has-active>.item>.text[data-v-f24171a4],.VPSidebarItem.level-4.has-active>.item>.text[data-v-f24171a4],.VPSidebarItem.level-5.has-active>.item>.text[data-v-f24171a4],.VPSidebarItem.level-0.has-active>.item>.link>.text[data-v-f24171a4],.VPSidebarItem.level-1.has-active>.item>.link>.text[data-v-f24171a4],.VPSidebarItem.level-2.has-active>.item>.link>.text[data-v-f24171a4],.VPSidebarItem.level-3.has-active>.item>.link>.text[data-v-f24171a4],.VPSidebarItem.level-4.has-active>.item>.link>.text[data-v-f24171a4],.VPSidebarItem.level-5.has-active>.item>.link>.text[data-v-f24171a4]{color:var(--vp-c-text-1)}.VPSidebarItem.level-0.is-active>.item .link>.text[data-v-f24171a4],.VPSidebarItem.level-1.is-active>.item .link>.text[data-v-f24171a4],.VPSidebarItem.level-2.is-active>.item .link>.text[data-v-f24171a4],.VPSidebarItem.level-3.is-active>.item .link>.text[data-v-f24171a4],.VPSidebarItem.level-4.is-active>.item .link>.text[data-v-f24171a4],.VPSidebarItem.level-5.is-active>.item .link>.text[data-v-f24171a4]{color:var(--vp-c-brand-1)}.caret[data-v-f24171a4]{display:flex;justify-content:center;align-items:center;margin-right:-7px;width:32px;height:32px;color:var(--vp-c-text-3);cursor:pointer;transition:color .25s;flex-shrink:0}.item:hover .caret[data-v-f24171a4]{color:var(--vp-c-text-2)}.item:hover .caret[data-v-f24171a4]:hover{color:var(--vp-c-text-1)}.caret-icon[data-v-f24171a4]{font-size:18px;transform:rotate(90deg);transition:transform .25s}.VPSidebarItem.collapsed .caret-icon[data-v-f24171a4]{transform:rotate(0)}.VPSidebarItem.level-1 .items[data-v-f24171a4],.VPSidebarItem.level-2 .items[data-v-f24171a4],.VPSidebarItem.level-3 .items[data-v-f24171a4],.VPSidebarItem.level-4 .items[data-v-f24171a4],.VPSidebarItem.level-5 .items[data-v-f24171a4]{border-left:1px solid var(--vp-c-divider);padding-left:16px}.VPSidebarItem.collapsed .items[data-v-f24171a4]{display:none}.VPSidebar[data-v-ec846e01]{position:fixed;top:var(--vp-layout-top-height, 0px);bottom:0;left:0;z-index:var(--vp-z-index-sidebar);padding:32px 32px 96px;width:calc(100vw - 64px);max-width:320px;background-color:var(--vp-sidebar-bg-color);opacity:0;box-shadow:var(--vp-c-shadow-3);overflow-x:hidden;overflow-y:auto;transform:translate(-100%);transition:opacity .5s,transform .25s ease;overscroll-behavior:contain}.VPSidebar.open[data-v-ec846e01]{opacity:1;visibility:visible;transform:translate(0);transition:opacity .25s,transform .5s cubic-bezier(.19,1,.22,1)}.dark .VPSidebar[data-v-ec846e01]{box-shadow:var(--vp-shadow-1)}@media (min-width: 960px){.VPSidebar[data-v-ec846e01]{padding-top:var(--vp-nav-height);width:var(--vp-sidebar-width);max-width:100%;background-color:var(--vp-sidebar-bg-color);opacity:1;visibility:visible;box-shadow:none;transform:translate(0)}}@media (min-width: 1440px){.VPSidebar[data-v-ec846e01]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}@media (min-width: 960px){.curtain[data-v-ec846e01]{position:sticky;top:-64px;left:0;z-index:1;margin-top:calc(var(--vp-nav-height) * -1);margin-right:-32px;margin-left:-32px;height:var(--vp-nav-height);background-color:var(--vp-sidebar-bg-color)}}.nav[data-v-ec846e01]{outline:0}.group+.group[data-v-ec846e01]{border-top:1px solid var(--vp-c-divider);padding-top:10px}@media (min-width: 960px){.group[data-v-ec846e01]{padding-top:10px;width:calc(var(--vp-sidebar-width) - 64px)}}.VPSkipLink[data-v-c3508ec8]{top:8px;left:8px;padding:8px 16px;z-index:999;border-radius:8px;font-size:12px;font-weight:700;text-decoration:none;color:var(--vp-c-brand-1);box-shadow:var(--vp-shadow-3);background-color:var(--vp-c-bg)}.VPSkipLink[data-v-c3508ec8]:focus{height:auto;width:auto;clip:auto;clip-path:none}@media (min-width: 1280px){.VPSkipLink[data-v-c3508ec8]{top:14px;left:16px}}.Layout[data-v-a9a9e638]{display:flex;flex-direction:column;min-height:100vh}.VPHomeSponsors[data-v-db81191c]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPHomeSponsors[data-v-db81191c]{margin:96px 0}@media (min-width: 768px){.VPHomeSponsors[data-v-db81191c]{margin:128px 0}}.VPHomeSponsors[data-v-db81191c]{padding:0 24px}@media (min-width: 768px){.VPHomeSponsors[data-v-db81191c]{padding:0 48px}}@media (min-width: 960px){.VPHomeSponsors[data-v-db81191c]{padding:0 64px}}.container[data-v-db81191c]{margin:0 auto;max-width:1152px}.love[data-v-db81191c]{margin:0 auto;width:fit-content;font-size:28px;color:var(--vp-c-text-3)}.icon[data-v-db81191c]{display:inline-block}.message[data-v-db81191c]{margin:0 auto;padding-top:10px;max-width:320px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.sponsors[data-v-db81191c]{padding-top:32px}.action[data-v-db81191c]{padding-top:40px;text-align:center}.VPTeamPage[data-v-c2f8e101]{margin:96px 0}@media (min-width: 768px){.VPTeamPage[data-v-c2f8e101]{margin:128px 0}}.VPHome .VPTeamPageTitle[data-v-c2f8e101-s]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPTeamPageSection+.VPTeamPageSection[data-v-c2f8e101-s],.VPTeamMembers+.VPTeamPageSection[data-v-c2f8e101-s]{margin-top:64px}.VPTeamMembers+.VPTeamMembers[data-v-c2f8e101-s]{margin-top:24px}@media (min-width: 768px){.VPTeamPageTitle+.VPTeamPageSection[data-v-c2f8e101-s]{margin-top:16px}.VPTeamPageSection+.VPTeamPageSection[data-v-c2f8e101-s],.VPTeamMembers+.VPTeamPageSection[data-v-c2f8e101-s]{margin-top:96px}}.VPTeamMembers[data-v-c2f8e101-s]{padding:0 24px}@media (min-width: 768px){.VPTeamMembers[data-v-c2f8e101-s]{padding:0 48px}}@media (min-width: 960px){.VPTeamMembers[data-v-c2f8e101-s]{padding:0 64px}}.VPTeamPageTitle[data-v-e277e15c]{padding:48px 32px;text-align:center}@media (min-width: 768px){.VPTeamPageTitle[data-v-e277e15c]{padding:64px 48px 48px}}@media (min-width: 960px){.VPTeamPageTitle[data-v-e277e15c]{padding:80px 64px 48px}}.title[data-v-e277e15c]{letter-spacing:0;line-height:44px;font-size:36px;font-weight:500}@media (min-width: 768px){.title[data-v-e277e15c]{letter-spacing:-.5px;line-height:56px;font-size:48px}}.lead[data-v-e277e15c]{margin:0 auto;max-width:512px;padding-top:12px;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 768px){.lead[data-v-e277e15c]{max-width:592px;letter-spacing:.15px;line-height:28px;font-size:20px}}.VPTeamPageSection[data-v-d43bc49d]{padding:0 32px}@media (min-width: 768px){.VPTeamPageSection[data-v-d43bc49d]{padding:0 48px}}@media (min-width: 960px){.VPTeamPageSection[data-v-d43bc49d]{padding:0 64px}}.title[data-v-d43bc49d]{position:relative;margin:0 auto;max-width:1152px;text-align:center;color:var(--vp-c-text-2)}.title-line[data-v-d43bc49d]{position:absolute;top:16px;left:0;width:100%;height:1px;background-color:var(--vp-c-divider)}.title-text[data-v-d43bc49d]{position:relative;display:inline-block;padding:0 24px;letter-spacing:0;line-height:32px;font-size:20px;font-weight:500;background-color:var(--vp-c-bg)}.lead[data-v-d43bc49d]{margin:0 auto;max-width:480px;padding-top:12px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.members[data-v-d43bc49d]{padding-top:40px}.VPTeamMembersItem[data-v-f9987cb6]{display:flex;flex-direction:column;gap:2px;border-radius:12px;width:100%;height:100%;overflow:hidden}.VPTeamMembersItem.small .profile[data-v-f9987cb6]{padding:32px}.VPTeamMembersItem.small .data[data-v-f9987cb6]{padding-top:20px}.VPTeamMembersItem.small .avatar[data-v-f9987cb6]{width:64px;height:64px}.VPTeamMembersItem.small .name[data-v-f9987cb6]{line-height:24px;font-size:16px}.VPTeamMembersItem.small .affiliation[data-v-f9987cb6]{padding-top:4px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .desc[data-v-f9987cb6]{padding-top:12px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .links[data-v-f9987cb6]{margin:0 -16px -20px;padding:10px 0 0}.VPTeamMembersItem.medium .profile[data-v-f9987cb6]{padding:48px 32px}.VPTeamMembersItem.medium .data[data-v-f9987cb6]{padding-top:24px;text-align:center}.VPTeamMembersItem.medium .avatar[data-v-f9987cb6]{width:96px;height:96px}.VPTeamMembersItem.medium .name[data-v-f9987cb6]{letter-spacing:.15px;line-height:28px;font-size:20px}.VPTeamMembersItem.medium .affiliation[data-v-f9987cb6]{padding-top:4px;font-size:16px}.VPTeamMembersItem.medium .desc[data-v-f9987cb6]{padding-top:16px;max-width:288px;font-size:16px}.VPTeamMembersItem.medium .links[data-v-f9987cb6]{margin:0 -16px -12px;padding:16px 12px 0}.profile[data-v-f9987cb6]{flex-grow:1;background-color:var(--vp-c-bg-soft)}.data[data-v-f9987cb6]{text-align:center}.avatar[data-v-f9987cb6]{position:relative;flex-shrink:0;margin:0 auto;border-radius:50%;box-shadow:var(--vp-shadow-3)}.avatar-img[data-v-f9987cb6]{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:50%;object-fit:cover}.name[data-v-f9987cb6]{margin:0;font-weight:600}.affiliation[data-v-f9987cb6]{margin:0;font-weight:500;color:var(--vp-c-text-2)}.org.link[data-v-f9987cb6]{color:var(--vp-c-text-2);transition:color .25s}.org.link[data-v-f9987cb6]:hover{color:var(--vp-c-brand-1)}.desc[data-v-f9987cb6]{margin:0 auto}.desc[data-v-f9987cb6] a{font-weight:500;color:var(--vp-c-brand-1);text-decoration-style:dotted;transition:color .25s}.links[data-v-f9987cb6]{display:flex;justify-content:center;height:56px}.sp-link[data-v-f9987cb6]{display:flex;justify-content:center;align-items:center;text-align:center;padding:16px;font-size:14px;font-weight:500;color:var(--vp-c-sponsor);background-color:var(--vp-c-bg-soft);transition:color .25s,background-color .25s}.sp .sp-link.link[data-v-f9987cb6]:hover,.sp .sp-link.link[data-v-f9987cb6]:focus{outline:none;color:var(--vp-c-white);background-color:var(--vp-c-sponsor)}.sp-icon[data-v-f9987cb6]{margin-right:8px;font-size:16px}.VPTeamMembers.small .container[data-v-fba19bad]{grid-template-columns:repeat(auto-fit,minmax(224px,1fr))}.VPTeamMembers.small.count-1 .container[data-v-fba19bad]{max-width:276px}.VPTeamMembers.small.count-2 .container[data-v-fba19bad]{max-width:576px}.VPTeamMembers.small.count-3 .container[data-v-fba19bad]{max-width:876px}.VPTeamMembers.medium .container[data-v-fba19bad]{grid-template-columns:repeat(auto-fit,minmax(256px,1fr))}@media (min-width: 375px){.VPTeamMembers.medium .container[data-v-fba19bad]{grid-template-columns:repeat(auto-fit,minmax(288px,1fr))}}.VPTeamMembers.medium.count-1 .container[data-v-fba19bad]{max-width:368px}.VPTeamMembers.medium.count-2 .container[data-v-fba19bad]{max-width:760px}.container[data-v-fba19bad]{display:grid;gap:24px;margin:0 auto;max-width:1152px}:root{--vp-plugin-tabs-tab-text-color: var(--vp-c-text-2);--vp-plugin-tabs-tab-active-text-color: var(--vp-c-text-1);--vp-plugin-tabs-tab-hover-text-color: var(--vp-c-text-1);--vp-plugin-tabs-tab-bg: var(--vp-c-bg-soft);--vp-plugin-tabs-tab-divider: var(--vp-c-divider);--vp-plugin-tabs-tab-active-bar-color: var(--vp-c-brand-1)}.plugin-tabs{margin:16px 0;background-color:var(--vp-plugin-tabs-tab-bg);border-radius:8px}.plugin-tabs--tab-list{position:relative;padding:0 12px;overflow-x:auto;overflow-y:hidden}.plugin-tabs--tab-list:after{content:"";position:absolute;bottom:0;left:0;right:0;height:2px;background-color:var(--vp-plugin-tabs-tab-divider)}.plugin-tabs--tab{position:relative;padding:0 12px;line-height:48px;border-bottom:2px solid transparent;color:var(--vp-plugin-tabs-tab-text-color);font-size:14px;font-weight:500;white-space:nowrap;transition:color .25s}.plugin-tabs--tab[aria-selected=true]{color:var(--vp-plugin-tabs-tab-active-text-color)}.plugin-tabs--tab:hover{color:var(--vp-plugin-tabs-tab-hover-text-color)}.plugin-tabs--tab:after{content:"";position:absolute;bottom:-2px;left:8px;right:8px;height:2px;background-color:transparent;transition:background-color .25s;z-index:1}.plugin-tabs--tab[aria-selected=true]:after{background-color:var(--vp-plugin-tabs-tab-active-bar-color)}.plugin-tabs--content[data-v-9b0d03d2]{padding:16px}.plugin-tabs--content[data-v-9b0d03d2]>:first-child:first-child{margin-top:0}.plugin-tabs--content[data-v-9b0d03d2]>:last-child:last-child{margin-bottom:0}.plugin-tabs--content[data-v-9b0d03d2]>div[class*=language-]{border-radius:8px;margin:16px 0}:root:not(.dark) .plugin-tabs--content[data-v-9b0d03d2] div[class*=language-]{background-color:var(--vp-c-bg)}.VPHero .clip{white-space:pre;max-width:500px}:root{--vp-font-family-base: "Barlow", "Inter var experimental", "Inter var", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;--vp-font-family-mono: "Space Mono", Menlo, Monaco, Consolas, "Courier New", monospace}.mono{font-feature-settings:"calt" 0}:root{--julia-blue: #4063D8;--julia-purple: #9558B2;--julia-red: #CB3C33;--julia-green: #389826;--vp-c-brand: #389826;--vp-c-brand-light: #3dd027;--vp-c-brand-lighter: #9499ff;--vp-c-brand-lightest: #bcc0ff;--vp-c-brand-dark: #535bf2;--vp-c-brand-darker: #454ce1;--vp-c-brand-dimm: #212425}:root{--vp-button-brand-border: var(--vp-c-brand-light);--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand);--vp-button-brand-hover-border: var(--vp-c-brand-light);--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-light);--vp-button-brand-active-border: var(--vp-c-brand-light);--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-button-brand-bg)}:root{--vp-home-hero-name-color: transparent;--vp-home-hero-name-background: -webkit-linear-gradient( 120deg, #9558B2 30%, #CB3C33 );--vp-home-hero-image-background-image: linear-gradient( -45deg, #9558B2 30%, #389826 30%, #CB3C33 );--vp-home-hero-image-filter: blur(40px)}@media (min-width: 640px){:root{--vp-home-hero-image-filter: blur(56px)}}@media (min-width: 960px){:root{--vp-home-hero-image-filter: blur(72px)}}:root.dark{--vp-custom-block-tip-border: var(--vp-c-brand);--vp-custom-block-tip-text: var(--vp-c-brand-lightest);--vp-custom-block-tip-bg: var(--vp-c-brand-dimm);--vp-c-black: hsl(220 20% 9%);--vp-c-black-pure: hsl(220, 24%, 4%);--vp-c-black-soft: hsl(220 16% 13%);--vp-c-black-mute: hsl(220 14% 17%);--vp-c-gray: hsl(220 8% 56%);--vp-c-gray-dark-1: hsl(220 10% 39%);--vp-c-gray-dark-2: hsl(220 12% 28%);--vp-c-gray-dark-3: hsl(220 12% 23%);--vp-c-gray-dark-4: hsl(220 14% 17%);--vp-c-gray-dark-5: hsl(220 16% 13%);--vp-custom-block-info-bg: hsl(220 14% 17%)}.DocSearch{--docsearch-primary-color: var(--vp-c-brand) !important}mjx-container>svg{display:block;margin:auto}mjx-container{padding:.5rem 0}mjx-container{display:inline-block;margin:auto 2px -2px}mjx-container>svg{margin:auto;display:inline-block}:root{--vp-c-brand-1: #CB3C33;--vp-c-brand-2: #CB3C33;--vp-c-brand-3: #CB3C33;--vp-c-sponsor: #ca2971;--vitest-c-sponsor-hover: #c13071}.dark{--vp-c-brand-1: #91dd33;--vp-c-brand-2: #91dd33;--vp-c-brand-3: #91dd33;--vp-c-sponsor: #91dd33;--vitest-c-sponsor-hover: #e51370}.VPLocalSearchBox[data-v-f5c68218]{position:fixed;z-index:100;top:0;right:0;bottom:0;left:0;display:flex}.backdrop[data-v-f5c68218]{position:absolute;top:0;right:0;bottom:0;left:0;background:var(--vp-backdrop-bg-color);transition:opacity .5s}.shell[data-v-f5c68218]{position:relative;padding:12px;margin:64px auto;display:flex;flex-direction:column;gap:16px;background:var(--vp-local-search-bg);width:min(100vw - 60px,900px);height:min-content;max-height:min(100vh - 128px,900px);border-radius:6px}@media (max-width: 767px){.shell[data-v-f5c68218]{margin:0;width:100vw;height:100vh;max-height:none;border-radius:0}}.search-bar[data-v-f5c68218]{border:1px solid var(--vp-c-divider);border-radius:4px;display:flex;align-items:center;padding:0 12px;cursor:text}@media (max-width: 767px){.search-bar[data-v-f5c68218]{padding:0 8px}}.search-bar[data-v-f5c68218]:focus-within{border-color:var(--vp-c-brand-1)}.local-search-icon[data-v-f5c68218]{display:block;font-size:18px}.navigate-icon[data-v-f5c68218]{display:block;font-size:14px}.search-icon[data-v-f5c68218]{margin:8px}@media (max-width: 767px){.search-icon[data-v-f5c68218]{display:none}}.search-input[data-v-f5c68218]{padding:6px 12px;font-size:inherit;width:100%}@media (max-width: 767px){.search-input[data-v-f5c68218]{padding:6px 4px}}.search-actions[data-v-f5c68218]{display:flex;gap:4px}@media (any-pointer: coarse){.search-actions[data-v-f5c68218]{gap:8px}}@media (min-width: 769px){.search-actions.before[data-v-f5c68218]{display:none}}.search-actions button[data-v-f5c68218]{padding:8px}.search-actions button[data-v-f5c68218]:not([disabled]):hover,.toggle-layout-button.detailed-list[data-v-f5c68218]{color:var(--vp-c-brand-1)}.search-actions button.clear-button[data-v-f5c68218]:disabled{opacity:.37}.search-keyboard-shortcuts[data-v-f5c68218]{font-size:.8rem;opacity:75%;display:flex;flex-wrap:wrap;gap:16px;line-height:14px}.search-keyboard-shortcuts span[data-v-f5c68218]{display:flex;align-items:center;gap:4px}@media (max-width: 767px){.search-keyboard-shortcuts[data-v-f5c68218]{display:none}}.search-keyboard-shortcuts kbd[data-v-f5c68218]{background:#8080801a;border-radius:4px;padding:3px 6px;min-width:24px;display:inline-block;text-align:center;vertical-align:middle;border:1px solid rgba(128,128,128,.15);box-shadow:0 2px 2px #0000001a}.results[data-v-f5c68218]{display:flex;flex-direction:column;gap:6px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}.result[data-v-f5c68218]{display:flex;align-items:center;gap:8px;border-radius:4px;transition:none;line-height:1rem;border:solid 2px var(--vp-local-search-result-border);outline:none}.result>div[data-v-f5c68218]{margin:12px;width:100%;overflow:hidden}@media (max-width: 767px){.result>div[data-v-f5c68218]{margin:8px}}.titles[data-v-f5c68218]{display:flex;flex-wrap:wrap;gap:4px;position:relative;z-index:1001;padding:2px 0}.title[data-v-f5c68218]{display:flex;align-items:center;gap:4px}.title.main[data-v-f5c68218]{font-weight:500}.title-icon[data-v-f5c68218]{opacity:.5;font-weight:500;color:var(--vp-c-brand-1)}.title svg[data-v-f5c68218]{opacity:.5}.result.selected[data-v-f5c68218]{--vp-local-search-result-bg: var(--vp-local-search-result-selected-bg);border-color:var(--vp-local-search-result-selected-border)}.excerpt-wrapper[data-v-f5c68218]{position:relative}.excerpt[data-v-f5c68218]{opacity:75%;pointer-events:none;max-height:140px;overflow:hidden;position:relative;opacity:.5;margin-top:4px}.result.selected .excerpt[data-v-f5c68218]{opacity:1}.excerpt[data-v-f5c68218] *{font-size:.8rem!important;line-height:130%!important}.titles[data-v-f5c68218] mark,.excerpt[data-v-f5c68218] mark{background-color:var(--vp-local-search-highlight-bg);color:var(--vp-local-search-highlight-text);border-radius:2px;padding:0 2px}.excerpt[data-v-f5c68218] .vp-code-group .tabs{display:none}.excerpt[data-v-f5c68218] .vp-code-group div[class*=language-]{border-radius:8px!important}.excerpt-gradient-bottom[data-v-f5c68218]{position:absolute;bottom:-1px;left:0;width:100%;height:8px;background:linear-gradient(transparent,var(--vp-local-search-result-bg));z-index:1000}.excerpt-gradient-top[data-v-f5c68218]{position:absolute;top:-1px;left:0;width:100%;height:8px;background:linear-gradient(var(--vp-local-search-result-bg),transparent);z-index:1000}.result.selected .titles[data-v-f5c68218],.result.selected .title-icon[data-v-f5c68218]{color:var(--vp-c-brand-1)!important}.no-results[data-v-f5c68218]{font-size:.9rem;text-align:center;padding:12px}svg[data-v-f5c68218]{flex:none} diff --git a/dev/constraints/comparison_constraints.html b/dev/constraints/comparison_constraints.html deleted file mode 100644 index 321090d..0000000 --- a/dev/constraints/comparison_constraints.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - Constraints.jl: Streamlining Constraint Definition and Integration in Julia | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Comparison-based Constraints

# Constraints.xcsp_all_differentFunction.
julia
xcsp_all_different(list::Vector{Int})

Return true if all the values of list are different, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

Variants

  • :all_different: Global constraint ensuring that all the values of x are all different.
julia
concept(:all_different, x; vals)
-concept(:all_different)(x; vals)

Examples

julia
c = concept(:all_different)
-
-c([1, 2, 3, 4])
-c([1, 2, 3, 1])
-c([1, 0, 0, 4]; vals=[0])
-c([1, 0, 0, 1]; vals=[0])

source


# Constraints.xcsp_all_equalFunction.
julia
xcsp_all_equal(list::Vector{Int}, val::Int)

Return true if all the values of list are equal to val, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • val::Int: value to compare to.

Variants

  • :all_equal: Global constraint ensuring that all the values of x are all equal.
julia
concept(:all_equal, x; val=nothing, pair_vars=zeros(x), op=+)
-concept(:all_equal)(x; val=nothing, pair_vars=zeros(x), op=+)

Examples

julia
c = concept(:all_equal)
-
-c([0, 0, 0, 0])
-c([1, 2, 3, 4])
-c([3, 2, 1, 0]; pair_vars=[0, 1, 2, 3])
-c([0, 1, 2, 3]; pair_vars=[0, 1, 2, 3])
-c([1, 2, 3, 4]; op=/, val=1, pair_vars=[1, 2, 3, 4])
-c([1, 2, 3, 4]; op=*, val=1, pair_vars=[1, 2, 3, 4])

source


# Constraints.xcsp_orderedFunction.
julia
xcsp_ordered(list::Vector{Int}, operator, lengths)

Return true if all the values of list are in an increasing order, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • operator: comparison operator to use.

  • lengths: list of lengths to use. Defaults to nothing.

Variants

  • :ordered: Global constraint ensuring that all the values of x are in an increasing order.
julia
concept(:ordered, x; op=≤, pair_vars=nothing)
-concept(:ordered)(x; op=≤, pair_vars=nothing)
  • :increasing: Global constraint ensuring that all the values of x are in an increasing order.
julia
concept(:increasing, x; op=≤, pair_vars=nothing)
-concept(:increasing)(x; op=≤, pair_vars=nothing)
  • :decreasing: Global constraint ensuring that all the values of x are in a decreasing order.
julia
concept(:decreasing, x; op=≥, pair_vars=nothing)
-concept(:decreasing)(x; op=≥, pair_vars=nothing)
  • :strictly_increasing: Global constraint ensuring that all the values of x are in a strictly increasing order.
julia
concept(:strictly_increasing, x; op=<, pair_vars=nothing)
-concept(:strictly_increasing)(x; op=<, pair_vars=nothing)
  • :strictly_decreasing: Global constraint ensuring that all the values of x are in a strictly decreasing order.
julia
concept(:strictly_decreasing, x; op=>, pair_vars=nothing)
-concept(:strictly_decreasing)(x; op=>, pair_vars=nothing)

Examples

julia
c = concept(:ordered)
-
-c([1, 2, 3, 4, 4]; op=≤)
-c([1, 2, 3, 4, 5]; op=<)
-!c([1, 2, 3, 4, 3]; op=≤)
-!c([1, 2, 3, 4, 3]; op=<)

source


- - - - \ No newline at end of file diff --git a/dev/constraints/connection_constraints.html b/dev/constraints/connection_constraints.html deleted file mode 100644 index d8958a9..0000000 --- a/dev/constraints/connection_constraints.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - Constraints.jl: Streamlining Constraint Definition and Integration in Julia | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Connection Constraints

# Constraints.xcsp_maximumFunction.
julia
xcsp_maximum(; list, condition)

Return true if the maximum constraint is satisfied, false otherwise. The maximum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the maximum value in a list of variables.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

  • condition::Tuple: condition to check.

Variants

  • :maximum: The maximum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the maximum value in a list of variables.
julia
concept(:maximum, x; op, val)
-concept(:maximum)(x; op, val)

Examples

julia
c = concept(:maximum)
-
-c([1, 2, 3, 4, 5]; op = ==, val = 5)
-c([1, 2, 3, 4, 5]; op = ==, val = 6)

source


# Constraints.xcsp_minimumFunction.
julia
xcsp_minimum(; list, condition)

Return true if the minimum constraint is satisfied, false otherwise. The minimum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the minimum value in a list of variables.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

  • condition::Tuple: condition to check.

Variants

  • :minimum: The minimum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the minimum value in a list of variables.
julia
concept(:minimum, x; op, val)
-concept(:minimum)(x; op, val)

Examples

julia
c = concept(:minimum)
-
-c([1, 2, 3, 4, 5]; op = ==, val = 1)
-c([1, 2, 3, 4, 5]; op = ==, val = 0)

source


# Constraints.xcsp_elementFunction.
julia
xcsp_element(; list, index, condition)

Return true if the element constraint is satisfied, false otherwise. The element constraint is a global constraint used in constraint programming that specifies that the value of a variable should be equal to the value of another variable indexed by a third variable.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

  • index::Int: index of the value to check.

  • condition::Tuple: condition to check.

Variants

  • :element: The element constraint is a global constraint used in constraint programming that specifies that the value of a variable should be equal to the value of another variable indexed by a third variable.
julia
concept(:element, x; id=nothing, op===, val=nothing)
-concept(:element)(x; id=nothing, op===, val=nothing)

Examples

julia
c = concept(:element)
-
-c([1, 2, 3, 4, 5]; id=1, val=1)
-c([1, 2, 3, 4, 5]; id=1, val=2)
-c([1, 2, 3, 4, 2])
-c([1, 2, 3, 4, 1])

source


# Constraints.xcsp_channelFunction.
julia
xcsp_channel(; list)

Return true if the channel constraint is satisfied, false otherwise. The channel constraint establishes a bijective correspondence between two sets of variables. This means that each value in the first set of variables corresponds to a unique value in the second set, and vice versa.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

Variants

  • :channel: The channel constraint establishes a bijective correspondence between two sets of variables. This means that each value in the first set of variables corresponds to a unique value in the second set, and vice versa.
julia
concept(:channel, x; dim=1, id=nothing)
-concept(:channel)(x; dim=1, id=nothing)

Examples

julia
c = concept(:channel)
-
-c([2, 1, 4, 3])
-c([1, 2, 3, 4])
-c([2, 3, 1, 4])
-c([2, 1, 5, 3, 4, 2, 1, 4, 5, 3]; dim=2)
-c([2, 1, 4, 3, 5, 2, 1, 4, 5, 3]; dim=2)
-c([false, false, true, false]; id=3)
-c([false, false, true, false]; id=1)

source


- - - - \ No newline at end of file diff --git a/dev/constraints/constraint_commons.html b/dev/constraints/constraint_commons.html deleted file mode 100644 index 6905bf8..0000000 --- a/dev/constraints/constraint_commons.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - ConstraintCommons.jl | Julia Constraints - - - - - - - - - - - - - -
Skip to content

ConstraintCommons.jl

ConstraintCommons.jl is an essential package within the Julia Constraints ecosystem designed to facilitate the development and interoperability of constraint programming solutions in Julia. It serves as a foundational layer that provides shared structures, abstract types, functions, and generic methods utilized by both basic feature packages and learning-oriented packages.

Key Features and Functionalities

  • Shared Structures and Abstract Types: ConstraintCommons.jl offers a collection of shared data structures and abstract types. This standardization is crucial for ensuring that packages such as ConstraintDomains, Constraints, ConstraintLearning, etc. can seamlessly interact and integrate, fostering a cohesive development environment.

  • Generic Functions and Methods: The package includes a set of generic functions and methods that are common across the JuliaConstraints ecosystem. This approach minimizes duplication and facilitates the extension of functionalities across different packages without requiring redundant code.

  • Interface for Learning and Application Transition: One of the pivotal roles of ConstraintCommons.jl is to provide a shared interface that bridges the gap between learning packages (e.g., CompositionalNetworks, QUBOConstraints, and ConstraintTranslator) and basic functionality packages. This interface ensures that once a learning process is complete, the resulting models or solutions can be directly utilized with the basic packages, eliminating the need for users to manage multiple package dependencies actively.

  • Simplifying the User Experience: By ensuring that learning outcomes are compatible with the fundamental packages for constraint programming, ConstraintCommons.jl simplifies the workflow for end-users. Once the learning aspect of problem modeling is completed, users can proceed with their projects relying solely on the basic packages, streamlining the development process and enhancing usability.

  • Impact on the JuliaConstraints Ecosystem: ConstraintCommons.jl plays a critical role in the JuliaConstraints ecosystem by providing the foundational elements that enable package interoperability and efficient development workflows. Its design emphasizes ease of use and seamless transition between the learning phase of constraint programming and practical application, thereby enhancing productivity and reducing the complexity of developing constraint-based solutions.

Parameters

This section of the package list or extract parameters based on the XCSP3-core specifications. Note that, for the forseeable future, the default constraints specification will follow the XCSP3 format.

# ConstraintCommons.USUAL_CONSTRAINT_PARAMETERSConstant.
julia
const USUAL_CONSTRAINT_PARAMETERS

List of usual constraints parameters (based on XCSP3-core constraints).

julia
const USUAL_CONSTRAINT_PARAMETERS = [
-    :bool,
-    :dim,
-    :id,
-    :language,
-    :op,
-    :pair_vars,
-    :val,
-    :vals,
-]

source


# ConstraintCommons.extract_parametersFunction.
julia
extract_parameters(m::Union{Method, Function}; parameters)

Extracts the intersection between the kargs of m and parameters (defaults to USUAL_CONSTRAINT_PARAMETERS).

source

julia
extract_parameters(s::Symbol, constraints_dict=USUAL_CONSTRAINTS; parameters=ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS)

Return the parameters of the constraint s in constraints_dict.

Arguments

  • s::Symbol: the constraint name.

  • constraints_dict::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

  • parameters::Vector{Symbol}: vector of parameters. Default is ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS.

Example

julia
extract_parameters(:all_different)

source


Performances – TODO

Languages

XCSP3 considers two kinds of structure to recognize languages as core constraints: Automata, Multivalued Decision Diagrams (MMDs).

# ConstraintCommons.AbstractMultivaluedDecisionDiagramType.
julia
AbstractMultivaluedDecisionDiagram

An abstract interface for Multivalued Decision Diagrams (MDD) used in Julia Constraints packages. Requirements:

  • accept(a<:AbstractMultivaluedDecisionDiagram, word): return true if a accepts word.

source


# ConstraintCommons.MDDType.
julia
MDD{S,T} <: AbstractMultivaluedDecisionDiagram

A minimal implementation of a multivalued decision diagram structure.

source


# ConstraintCommons.AbstractAutomatonType.
julia
AbstractAutomaton

An abstract interface for automata used in Julia Constraints packages. Requirements:

  • accept(a<:AbstractAutomaton, word): return true if a accepts word.

source


# ConstraintCommons.AutomatonType.
julia
Automaton{S, T, F <: Union{S, Vector{S}, Set{S}}} <: AbstractAutomaton

A minimal implementation of a deterministic automaton structure.

source


Missing docstring.

Missing docstring for Automaton(a::MDD). Check Documenter's build log for details.

# ConstraintCommons.acceptFunction.
julia
accept(a::Union{Automaton, MDD}, w)

Return true if a accepts the word w and false otherwise.

source

julia
ConstraintCommons.accept(fa::FakeAutomaton, word)

Implement the accept methods for FakeAutomaton.

source


# ConstraintCommons.at_endFunction.
julia
at_end(a::Automaton, s)

Internal method used by accept with Automaton.

source


Performances – TODO

Extensions

We extended some operations for Nothing and Symbol.

Missing docstring.

Missing docstring for Base.:*. Check Documenter's build log for details.

Missing docstring.

Missing docstring for Base.in(::Any, ::Nothing). Check Documenter's build log for details.

Missing docstring.

Missing docstring for Base.isempty(::Nothing). Check Documenter's build log for details.

Performances – TODO

Sampling

During our constraint learning processes, we use sampling to efficiently make partial exploration of search spaces. Follows some sampling utilities.

# ConstraintCommons.oversampleFunction.
julia
oversample(X, f)

Oversample elements of X until the boolean function f has as many true and false configurations.

source


Performances – TODO

Extrema

We need to compute the difference between extrema of various kind of collections in several situations.

# ConstraintCommons.δ_extremaFunction.
julia
δ_extrema(X...)

Compute both the difference between the maximum and the minimum of over all the collections of X.

source


Performances – TODO

Dictionaries

We provide the everuseful incsert! function for dictionaries.

# ConstraintCommons.incsert!Function.
julia
incsert!(d::Union{AbstractDict, AbstractDictionary}, ind, val = 1)

Increase or insert a counter in a dictionary-based collection. The counter insertion defaults to val = 1.

source


Performances – TODO

- - - - \ No newline at end of file diff --git a/dev/constraints/constraint_domains.html b/dev/constraints/constraint_domains.html deleted file mode 100644 index 2aaf396..0000000 --- a/dev/constraints/constraint_domains.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints | Julia Constraints - - - - - - - - - - - - - -
Skip to content

ConstraintDomains.jl: Defining and Exploring Variable Domains within JuliaConstraints

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.

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.

Commons

# ConstraintDomains.AbstractDomainType.
julia
AbstractDomain

An abstract super type for any domain type. A domain type D <: AbstractDomain must implement the following methods to properly interface AbstractDomain.

  • Base.∈(val, ::D)

  • Base.rand(::D)

  • Base.length(::D) that is the number of elements in a discrete domain, and the distance between bounds or similar for a continuous domain

Additionally, if the domain is used in a dynamic context, it can extend

  • add!(::D, args)

  • delete!(::D, args)

where args depends on D's structure

source


# ConstraintDomains.EmptyDomainType.
julia
EmptyDomain

A struct to handle yet to be defined domains.

source


# ConstraintDomains.domainFunction.
julia
domain()

Construct an EmptyDomain.

source

julia
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
-domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}

Construct a domain of continuous interval(s).

source

julia
domain(values)
-domain(range::R) where {T <: Real, R <: AbstractRange{T}}

Construct either a SetDomain or a `RangeDomain``.

julia
d1 = domain(1:5)
-d2 = domain([53.69, 89.2, 0.12])
-d3 = domain([2//3, 89//123])
-d4 = domain(4.3)
-d5 = domain(1,42,86.9)

source


# ConstraintDomains.domain_sizeFunction.
julia
domain_size(d <: AbstractDomain)

Fallback method for domain_size(d) that return length(d).

source

julia
domain_size(itv::Intervals)

Return the difference between the highest and lowest values in itv.

source

julia
domain_size(d::D) where D <: DiscreteDomain

Return the maximum distance between two points in d.

source


# ConstraintDomains.get_domainFunction.
julia
get_domain(::AbstractDomain)

Access the internal structure of any domain type.

source


# ConstraintDomains.to_domainsFunction.
julia
to_domains(args...)

Convert various arguments into valid domains format.

source


Extension to Base module

# Base.inFunction.
julia
x::Variable constraint
-value  x::Variable

Check if a variable x is restricted by a constraint::Int, or if a value belongs to the domain of x.

source

julia
var::Int c::Constraint

source

julia
Base.in(value, d <: AbstractDomain)

Fallback method for value ∈ d that returns false.

source

julia
Base.in(x, itv::Intervals)

Return true if x ∈ I for any 'I ∈ itv, false otherwise.x ∈ I` is equivalent to

  • a < x < b if I = (a, b)

  • a < x ≤ b if I = (a, b]

  • a ≤ x < b if I = [a, b)

  • a ≤ x ≤ b if I = [a, b]

source

julia
Base.in(value, d::D) where D <: DiscreteDomain

Return true if value is a point of d.

source


# Base.randFunction.
julia
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}

Extends Base.rand to (a collection of) domains.

source

julia
Base.rand(itv::Intervals)
-Base.rand(itv::Intervals, i)

Return a random value from itv, specifically from the ith interval if i is specified.

source

julia
Base.rand(d::D) where D <: DiscreteDomain

Draw randomly a point in d.

source

julia
Base.rand(fa::FakeAutomaton)

Extends Base.rand. Currently simply returns fa.

source


# Base.isemptyFunction.
julia
Base.isempty(d <: AbstractDomain)

Fallback method for isempty(d) that return length(d) == 0 which default to 0.

source


# Base.randFunction.
julia
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}

Extends Base.rand to (a collection of) domains.

source

julia
Base.rand(itv::Intervals)
-Base.rand(itv::Intervals, i)

Return a random value from itv, specifically from the ith interval if i is specified.

source

julia
Base.rand(d::D) where D <: DiscreteDomain

Draw randomly a point in d.

source

julia
Base.rand(fa::FakeAutomaton)

Extends Base.rand. Currently simply returns fa.

source


# Base.stringFunction.
julia
Base.string(D::Vector{<:AbstractDomain})
-Base.string(d<:AbstractDomain)

Extends the string method to (a vector of) domains.

source


Performances

Continuous

# ConstraintDomains.ContinuousDomainType.
julia
ContinuousDomain{T <: Real} <: AbstractDomain

An abstract supertype for all continuous domains.

source


# ConstraintDomains.IntervalsType.
julia
Intervals{T <: Real} <: ContinuousDomain{T}

An encapsuler to store a vector of PatternFolds.Interval. Dynamic changes to Intervals are not handled yet.

source


# ConstraintDomains.domainFunction.
julia
domain()

Construct an EmptyDomain.

source

julia
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
-domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}

Construct a domain of continuous interval(s).

source

julia
domain(values)
-domain(range::R) where {T <: Real, R <: AbstractRange{T}}

Construct either a SetDomain or a `RangeDomain``.

julia
d1 = domain(1:5)
-d2 = domain([53.69, 89.2, 0.12])
-d3 = domain([2//3, 89//123])
-d4 = domain(4.3)
-d5 = domain(1,42,86.9)

source


# ConstraintDomains.domain_sizeFunction.
julia
domain_size(d <: AbstractDomain)

Fallback method for domain_size(d) that return length(d).

source

julia
domain_size(itv::Intervals)

Return the difference between the highest and lowest values in itv.

source

julia
domain_size(d::D) where D <: DiscreteDomain

Return the maximum distance between two points in d.

source


# ConstraintDomains.merge_domainsFunction.
julia
merge_domains(d₁::AbstractDomain, d₂::AbstractDomain)

Merge two domains of same nature (discrete/contiuous).

source


# ConstraintDomains.intersect_domainsFunction.
julia
intersect_domains(d₁, d₂)

Compute the intersections of two domains.

source


# ConstraintDomains.intersect_domains!Function.
julia
intersect_domains!(is, i, new_itvls)

Compute the intersections of a domain with an interval and store the results in new_itvls.

Arguments

  • is::IS: a collection of intervals.

  • i::I: an interval.

  • new_itvls::Vector{I}: a vector to store the results.

source


# ConstraintDomains.sizeFunction.
julia
Base.size(i::I) where {I <: Interval}

Defines the size of an interval as its span.

source


Extension to Base module

# Base.lengthFunction.
julia
length(layer)

Return the number of operations in a layer.

source

julia
Base.length(icn)

Return the total number of operations of an ICN.

source

julia
Base.rand(d <: AbstractDomain)

Fallback method for length(d) that return 0.

source

julia
Base.length(itv::Intervals)

Return the sum of the length of each interval in itv.

source

julia
Base.length(d::D) where D <: DiscreteDomain

Return the number of points in d.

source


# Base.randFunction.
julia
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}

Extends Base.rand to (a collection of) domains.

source

julia
Base.rand(itv::Intervals)
-Base.rand(itv::Intervals, i)

Return a random value from itv, specifically from the ith interval if i is specified.

source

julia
Base.rand(d::D) where D <: DiscreteDomain

Draw randomly a point in d.

source

julia
Base.rand(fa::FakeAutomaton)

Extends Base.rand. Currently simply returns fa.

source


# Base.inFunction.
julia
x::Variable constraint
-value  x::Variable

Check if a variable x is restricted by a constraint::Int, or if a value belongs to the domain of x.

source

julia
var::Int c::Constraint

source

julia
Base.in(value, d <: AbstractDomain)

Fallback method for value ∈ d that returns false.

source

julia
Base.in(x, itv::Intervals)

Return true if x ∈ I for any 'I ∈ itv, false otherwise.x ∈ I` is equivalent to

  • a < x < b if I = (a, b)

  • a < x ≤ b if I = (a, b]

  • a ≤ x < b if I = [a, b)

  • a ≤ x ≤ b if I = [a, b]

source

julia
Base.in(value, d::D) where D <: DiscreteDomain

Return true if value is a point of d.

source


# Base.stringFunction.
julia
Base.string(D::Vector{<:AbstractDomain})
-Base.string(d<:AbstractDomain)

Extends the string method to (a vector of) domains.

source


Discrete

# ConstraintDomains.DiscreteDomainType.
julia
DiscreteDomain{T <: Number} <: AbstractDomain

An abstract supertype for discrete domains (set, range).

source


# ConstraintDomains.SetDomainType.
julia
SetDomain{T <: Number} <: DiscreteDomain{T}

Domain that stores discrete values as a set of (unordered) points.

source


# ConstraintDomains.RangeDomainType.
julia
RangeDomain

A discrete domain defined by a range <: AbstractRange{Real}. As ranges are immutable in Julia, changes in RangeDomain must use set_domain!.

source


# ConstraintDomains.ArbitraryDomainFunction.
julia
ArbitraryDomain{T} <: DiscreteDomain{T}

A domain type that stores arbitrary values, possibly non numeric, of type T.

source


# ConstraintDomains.domainFunction.
julia
domain()

Construct an EmptyDomain.

source

julia
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
-domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}

Construct a domain of continuous interval(s).

source

julia
domain(values)
-domain(range::R) where {T <: Real, R <: AbstractRange{T}}

Construct either a SetDomain or a `RangeDomain``.

julia
d1 = domain(1:5)
-d2 = domain([53.69, 89.2, 0.12])
-d3 = domain([2//3, 89//123])
-d4 = domain(4.3)
-d5 = domain(1,42,86.9)

source


# ConstraintDomains.domain_sizeFunction.
julia
domain_size(d <: AbstractDomain)

Fallback method for domain_size(d) that return length(d).

source

julia
domain_size(itv::Intervals)

Return the difference between the highest and lowest values in itv.

source

julia
domain_size(d::D) where D <: DiscreteDomain

Return the maximum distance between two points in d.

source


# ConstraintDomains.add!Function.
julia
add!(d::SetDomain, value)

Add value to the list of points in d.

source


# ConstraintDomains.merge_domainsFunction.
julia
merge_domains(d₁::AbstractDomain, d₂::AbstractDomain)

Merge two domains of same nature (discrete/contiuous).

source


# ConstraintDomains.intersect_domainsFunction.
julia
intersect_domains(d₁, d₂)

Compute the intersections of two domains.

source


# ConstraintDomains.sizeFunction.
julia
Base.size(i::I) where {I <: Interval}

Defines the size of an interval as its span.

source


Extension to Base module

# Base.delete!Function.
julia
Base.delete!(d::SetDomain, value)(d::SetDomain, value)

Delete value from the list of points in d.

source


# Base.lengthFunction.
julia
length(layer)

Return the number of operations in a layer.

source

julia
Base.length(icn)

Return the total number of operations of an ICN.

source

julia
Base.rand(d <: AbstractDomain)

Fallback method for length(d) that return 0.

source

julia
Base.length(itv::Intervals)

Return the sum of the length of each interval in itv.

source

julia
Base.length(d::D) where D <: DiscreteDomain

Return the number of points in d.

source


# Base.randFunction.
julia
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}

Extends Base.rand to (a collection of) domains.

source

julia
Base.rand(itv::Intervals)
-Base.rand(itv::Intervals, i)

Return a random value from itv, specifically from the ith interval if i is specified.

source

julia
Base.rand(d::D) where D <: DiscreteDomain

Draw randomly a point in d.

source

julia
Base.rand(fa::FakeAutomaton)

Extends Base.rand. Currently simply returns fa.

source


# Base.inFunction.
julia
x::Variable constraint
-value  x::Variable

Check if a variable x is restricted by a constraint::Int, or if a value belongs to the domain of x.

source

julia
var::Int c::Constraint

source

julia
Base.in(value, d <: AbstractDomain)

Fallback method for value ∈ d that returns false.

source

julia
Base.in(x, itv::Intervals)

Return true if x ∈ I for any 'I ∈ itv, false otherwise.x ∈ I` is equivalent to

  • a < x < b if I = (a, b)

  • a < x ≤ b if I = (a, b]

  • a ≤ x < b if I = [a, b)

  • a ≤ x ≤ b if I = [a, b]

source

julia
Base.in(value, d::D) where D <: DiscreteDomain

Return true if value is a point of d.

source


# Base.stringFunction.
julia
Base.string(D::Vector{<:AbstractDomain})
-Base.string(d<:AbstractDomain)

Extends the string method to (a vector of) domains.

source


General

# Base.eltypeFunction.
julia
Base.eltype(::AbstractDomain)

Extend eltype for domains.

source


# Base.convertFunction.
julia
Base.convert(::Type{Union{Intervals, RangeDomain}}, d::Union{Intervals, RangeDomain})

Extends Base.convert for domains.

source


Exploration

# ConstraintDomains.ExploreSettingsType.
julia
ExploreSettings(
-    domains;
-    complete_search_limit = 10^6,
-    max_samplings = sum(domain_size, domains),
-    search = :flexible,
-    solutions_limit = floor(Int, sqrt(max_samplings)),
-)

Settings for the exploration of a search space composed by a collection of domains.

source


# ConstraintDomains._exploreFunction.
julia
_explore(args...)

Internals of the explore function. Behavior is automatically adjusted on the kind of exploration: :flexible, :complete, :partial.

source


# ConstraintDomains.exploreFunction.
julia
explore(domains, concept, param = nothing; search_limit = 1000, solutions_limit = 100)

Search (a part of) a search space and returns a pair of vector of configurations: (solutions, non_solutions). If the search space size is over search_limit, then both solutions and non_solutions are limited to solutions_limit.

Beware that if the density of the solutions in the search space is low, solutions_limit needs to be reduced. This process will be automatic in the future (simple reinforcement learning).

Arguments:

  • domains: a collection of domains

  • concept: the concept of the targeted constraint

  • param: an optional parameter of the constraint

  • sol_number: the required number of solutions (half of the number of configurations), default to 100

source


Parameters

# ConstraintDomains.BoolParameterDomainType.
julia
BoolParameterDomain <: AbstractDomain

A domain to store boolean values. It is used to generate random parameters.

source


# ConstraintDomains.DimParameterDomainType.
julia
DimParameterDomain <: AbstractDomain

A domain to store dimensions. It is used to generate random parameters.

source


# ConstraintDomains.IdParameterDomainType.
julia
IdParameterDomain <: AbstractDomain

A domain to store ids. It is used to generate random parameters.

source


# ConstraintDomains.FakeAutomatonType.
julia
FakeAutomaton{T} <: ConstraintCommons.AbstractAutomaton

A structure to generate pseudo automaton enough for parameter exploration.

source


# ConstraintCommons.acceptFunction.
julia
accept(a::Union{Automaton, MDD}, w)

Return true if a accepts the word w and false otherwise.

source

julia
ConstraintCommons.accept(fa::FakeAutomaton, word)

Implement the accept methods for FakeAutomaton.

source


# ConstraintDomains.fake_automatonFunction.
julia
fake_automaton(d)

Construct a FakeAutomaton.

source


# ConstraintDomains.LanguageParameterDomainType.
julia
LanguageParameterDomain <: AbstractDomain

A domain to store languages. It is used to generate random parameters.

source


# ConstraintDomains.OpParameterDomainType.
julia
OpParameterDomain{T} <: AbstractDomain

A domain to store operators. It is used to generate random parameters.

source


# ConstraintDomains.PairVarsParameterDomainType.
julia
PairVarsParameterDomain{T} <: AbstractDomain

A domain to store values paired with variables. It is used to generate random parameters.

source


# ConstraintDomains.ValParameterDomainType.
julia
ValParameterDomain{T} <: AbstractDomain

A domain to store one value. It is used to generate random parameters.

source


# ConstraintDomains.ValsParameterDomainType.
julia
ValsParameterDomain{T} <: AbstractDomain

A domain to store values. It is used to generate random parameters.

source


# Base.randFunction.
julia
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}

Extends Base.rand to (a collection of) domains.

source

julia
Base.rand(itv::Intervals)
-Base.rand(itv::Intervals, i)

Return a random value from itv, specifically from the ith interval if i is specified.

source

julia
Base.rand(d::D) where D <: DiscreteDomain

Draw randomly a point in d.

source

julia
Base.rand(fa::FakeAutomaton)

Extends Base.rand. Currently simply returns fa.

source


# ConstraintDomains.generate_parametersFunction.
julia
generate_parameters(d<:AbstractDomain, param)

Generates random parameters based on the domain d and the kind of parameters param.

source


- - - - \ No newline at end of file diff --git a/dev/constraints/constraint_models.html b/dev/constraints/constraint_models.html deleted file mode 100644 index 89e0deb..0000000 --- a/dev/constraints/constraint_models.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - ConstraintModels.jl | Julia Constraints - - - - - - - - - - - - - -
Skip to content

ConstraintModels.jl

Documentation for ConstraintModels.jl.

# ConstraintModels.SudokuInstanceType.
julia
mutable struct SudokuInstance{T <: Integer} <: AbstractMatrix{T}

A struct for SudokuInstances, which is a subtype of AbstractMatrix.

julia
SudokuInstance(A::AbstractMatrix{T})
-SudokuInstance(::Type{T}, n::Int) # fill in blank sudoku of type T
-SudokuInstance(n::Int) # fill in blank sudoku of type Int
-SudokuInstance(::Type{T}) # fill in "standard" 9×9 sudoku of type T
-SudokuInstance() # fill in "standard" 9×9 sudoku of type Int
-SudokuInstance(n::Int, P::Pair{Tuple{Int, Int}, T}...) where {T <: Integer} # construct a sudoku given pairs of coordinates and values
-SudokuInstance(P::Pair{Tuple{Int, Int}, T}...) # again, default to 9×9 sudoku, constructing given pairs

Constructor functions for the SudokuInstance struct.

source


# ConstraintModels.SudokuInstanceMethod.
julia
SudokuInstance(X::Dictionary)

Construct a SudokuInstance with the values X of a solver as input.

source


# Base.Multimedia.displayMethod.
julia
display(io::IO, S::SudokuInstance)
-display(S::SudokuInstance) # default to stdout

Displays an n×n SudokuInstance.

source


# Base.Multimedia.displayMethod.
julia
Base.display(X, Val(:sudoku))

Extends Base.display to a sudoku configuration.

source


# Base.Multimedia.displayMethod.
julia
Base.display(S::SudokuInstance)

Extends Base.display to SudokuInstance.

source


# Base.Multimedia.displayMethod.
julia
Base.display(X::Dictionary)

Extends Base.display to a sudoku configuration.

source


# Base.sizeMethod.
julia
Base.size(S::SudokuInstance)

Extends Base.size for SudokuInstance.

source


# ConstraintModels._format_lineMethod.
julia
_format_line(r, M)

Format line of a sudoku grid.

source


# ConstraintModels._format_line_segmentMethod.
julia
_format_line_segment(r, col_pos, M)

Format line segment of a sudoku grid.

source


# ConstraintModels._format_valMethod.
julia
_format_val(a)

Format an integer a into a string for SudokuInstance.

source


# ConstraintModels._get_sep_lineMethod.
julia
_get_sep_line(s, pos_row, M)

Return a line separator.

source


# ConstraintModels.chemical_equilibriumMethod.
julia
chemical_equilibrium(atoms_compounds, elements_weights, standard_free_energy; modeler = :JuMP)

Warning

Even the structure to model problems with continuous domains is available, the default solver is not yet equiped to solve such problems efficiently.

From Wikipedia

In a chemical reaction, chemical equilibrium is the state in which both the reactants and products are present in concentrations which have no further tendency to change with time, so that there is no observable change in the properties of the system. This state results when the forward reaction proceeds at the same rate as the reverse reaction. The reaction rates of the forward and backward reactions are generally not zero, but they are equal. Thus, there are no net changes in the concentrations of the reactants and products. Such a state is known as dynamic equilibrium.

source


# ConstraintModels.golombFunction.
julia
golomb(n, L=n²)

Model the Golomb problem of n marks on the ruler 0:L. The modeler argument accepts :raw, and :JuMP (default), which refer respectively to the solver internal model, the MathOptInterface model, and the JuMP model.

source


# ConstraintModels.magic_squareMethod.
julia
magic_square(n; modeler = :JuMP)

Create a model for the magic square problem of order n. The modeler argument accepts :JuMP (default), which refer to the solver the JuMP model.

source


# ConstraintModels.mincutMethod.
julia
mincut(graph; source, sink, interdiction =0, modeler = :JuMP)

Compute the minimum cut of a graph.

Arguments:

  • graph: Any matrix <: AbstractMatrix that describes the capacities of the graph

  • source: Id of the source node; must be set

  • sink: Id of the sink node; must be set

  • interdiction: indicates the number of forbidden links

  • modeler: Default to :JuMP.

source


# ConstraintModels.n_queensMethod.
julia
n_queens(n; modeler = :JuMP)

Create a model for the n-queens problem with n queens. The modeler argument accepts :JuMP (default), which refer to the JuMP model.

source


# ConstraintModels.qapMethod.
julia
qap(n, weigths, distances; modeler = :JuMP)

Modelize an instance of the Quadractic Assignment Problem with

  • n: number of both facilities and locations

  • weights: Matrix of the weights of each pair of facilities

  • distances: Matrix of distances between locations

  • modeler: Default to :JuMP. No other modeler available for now.

From Wikipedia

There are a set of n facilities and a set of n locations. For each pair of locations, a distance is specified and for each pair of facilities a weight or flow is specified (e.g., the amount of supplies transported between the two facilities). The problem is to assign all facilities to different locations with the goal of minimizing the sum of the distances multiplied by the corresponding flows.

source


# ConstraintModels.schedulingMethod.
julia
scheduling(processing_time, due_date; modeler=:JuMP)

Create a model for the n-queens problem with n queens. The modeler argument accepts :JuMP (default), which refer to the JuMP model.

Warning

The model seems to have a flaw. Needs to be investigated.

source


# ConstraintModels.sudokuMethod.
julia
sudoku(n; start= Dictionary{Int, Int}(), modeler = :JuMP)

Create a model for the sudoku problem of domain 1:n² with optional starting values. The modeler argument accepts :raw, :MOI, and :JuMP (default), which refer respectively to the solver internal model, the MathOptInterface model, and the JuMP model.

julia
# Construct a JuMP model `m` and its associated matrix `grid` for sudoku 9×9
-m, grid = sudoku(3)
-
-# Same with a starting instance
-instance = [
-    9  3  0  0  0  0  0  4  0
-    0  0  0  0  4  2  0  9  0
-    8  0  0  1  9  6  7  0  0
-    0  0  0  4  7  0  0  0  0
-    0  2  0  0  0  0  0  6  0
-    0  0  0  0  2  3  0  0  0
-    0  0  8  5  3  1  0  0  2
-    0  9  0  2  8  0  0  0  0
-    0  7  0  0  0  0  0  5  3
-]
-m, grid = sudoku(3, start = instance)
-
-# Run the solver
-optimize!(m)
-
-# Retrieve and display the values
-solution = value.(grid)
-display(solution, Val(:sudoku))

source


- - - - \ No newline at end of file diff --git a/dev/constraints/constraints.html b/dev/constraints/constraints.html deleted file mode 100644 index 0796258..0000000 --- a/dev/constraints/constraints.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - Constraints.jl: Streamlining Constraint Definition and Integration in Julia | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Constraints.jl is a pivotal package within the JuliaConstraints ecosystem, designed to facilitate the definition, manipulation, and application of constraints in constraint programming (CP). This package is central to handling both standard and complex constraints, making it an indispensable tool for developers and researchers working in CP.

Key Features and Functionalities

  • Integration of XCSP3-core Constraints: One of the standout features of Constraints.jl is its incorporation of the XCSP3-core constraints as usual constraints within Julia. This integration ensures that users can define and work with a wide range of standard constraints, following the specifications outlined in the XCSP3-core, directly in Julia. The use of USUAL_CONSTRAINTS dictionary allows for straightforward addition and manipulation of these constraints, enhancing the package's utility and flexibility.

  • Learning Package Integration: Constraints.jl goes beyond traditional constraint handling by offering the capability to include results from various learning packages within the JuliaConstraints organization. This feature allows for the enhancement of usual constraints and those from the Global Constraints Catalog with learned parameters and behaviors, significantly improving constraint applicability and performance in complex CP problems.

  • Constraint Definition and Symmetry Handling: The package provides a simple yet powerful syntax for defining new constraints (@usual) and managing their symmetries through the USUAL_SYMMETRIES dictionary. This approach simplifies the creation of new constraints and the optimization of constraint search spaces by avoiding redundant explorations.

  • Advanced Constraint Functionalities: At the core of Constraints.jl is the Constraint type, encapsulating the essential elements of a constraint, including its concept (a Boolean function determining satisfaction) and an error function (providing a preference measure over invalid assignments). These components are crucial for defining how constraints behave and are evaluated within a CP model.

  • Flexible Constraint Application: The package supports a range of methods for interacting with constraints, such as args, concept, error_f, params_length, symmetries, and xcsp_intension. These methods offer users the ability to examine constraint properties, apply constraints to variable assignments, and work with intensional constraints defined by predicates. Such flexibility is vital for tailoring constraint behavior to specific problems and contexts.

Enabling Advanced Modeling in Constraint Programming

Constraints.jl embodies the JuliaConstraints ecosystem's commitment to providing robust, flexible tools for constraint programming. By integrating standard constraints, facilitating the incorporation of learned behaviors, and offering comprehensive tools for constraint definition and application, Constraints.jl significantly enhances the modeling capabilities available to CP practitioners. Whether for educational purposes, research, or solving practical CP problems, Constraints.jl offers a sophisticated, user-friendly platform for working with constraints in Julia.

Basic tools

# Constraints.USUAL_SYMMETRIESConstant.
julia
USUAL_SYMMETRIES

A Dictionary that contains the function to apply for each symmetry to avoid searching a whole space.

source


# Constraints.ConstraintType.
julia
Constraint

Parametric structure with the following fields.

  • concept: a Boolean function that, given an assignment x, outputs true if x satisfies the constraint, and false otherwise.

  • error: a positive function that works as preferences over invalid assignments. Return 0.0 if the constraint is satisfied, and a strictly positive real otherwise.

source


# Constraints.conceptFunction.
julia
concept(c::Constraint)

Return the concept (function) of constraint c. concept(c::Constraint, x...; param = nothing) Apply the concept of c to values x and optionally param.

source

julia
concept(s::Symbol, args...; kargs...)

Return the concept of the constraint s applied to args and kargs. This is a shortcut for concept(USUAL_CONSTRAINTS[s])(args...; kargs...).

Arguments

  • s::Symbol: the constraint name.

  • args...: the arguments to apply the concept to.

  • kargs...: the keyword arguments to apply the concept to.

Example

julia
concept(:all_different, [1, 2, 3])

source


# Constraints.error_fFunction.
julia
error_f(c::Constraint)

Return the error function of constraint c. error_f(c::Constraint, x; param = nothing) Apply the error function of c to values x and optionally param.

source


# Constraints.argsFunction.
julia
args(c::Constraint)

Return the expected length restriction of the arguments in a constraint c. The value nothing indicates that any strictly positive number of value is accepted.

source


# Constraints.params_lengthFunction.
julia
params_length(c::Constraint)

Return the expected length restriction of the arguments in a constraint c. The value nothing indicates that any strictly positive number of parameters is accepted.

source


# Constraints.symmetriesFunction.
julia
symmetries(c::Constraint)

Return the list of symmetries of c.

source


# Constraints.make_errorFunction.
julia
make_error(symb::Symbol)

Create a function that returns an error based on the predicate of the constraint identified by the symbol provided.

Arguments

  • symb::Symbol: The symbol used to determine the error function to be returned. The function first checks if a predicate with the prefix "icn_" exists in the Constraints module. If it does, it returns that function. If it doesn't, it checks for a predicate with the prefix "error_". If that exists, it returns that function. If neither exists, it returns a function that evaluates the predicate with the prefix "concept_" and returns the negation of its result cast to Float64.

Returns

  • Function: A function that takes in a variable x and an arbitrary number of parameters params. The function returns a Float64.

Examples

julia
e = make_error(:all_different)
-e([1, 2, 3]) # Returns 0.0
-e([1, 1, 3]) # Returns 1.0

source


# Constraints.shrink_conceptFunction.
julia
shrink_concept(s)

Simply delete the concept_ part of symbol or string starting with it. TODO: add a check with a warning if s starts with something different.

source


# Constraints.concept_vs_errorFunction.
julia
concept_vs_error(c, e, args...; kargs...)

Compare the results of a concept function and an error function for the same inputs. It is mainly used for testing purposes.

Arguments

  • c: The concept function.

  • e: The error function.

  • args...: Positional arguments to be passed to both the concept and error functions.

  • kargs...: Keyword arguments to be passed to both the concept and error functions.

Returns

  • Boolean: Returns true if the result of the concept function is not equal to whether the result of the error function is greater than 0.0. Otherwise, it returns false.

Examples

julia
concept_vs_error(all_different, make_error(:all_different), [1, 2, 3]) # Returns false

source


Usual constraints (based on and including XCSP3-core categories)

# Constraints.USUAL_CONSTRAINTSConstant.
julia
USUAL_CONSTRAINTS::Dict

Dictionary that contains all the usual constraints defined in Constraint.jl. It is based on XCSP3-core specifications available at https://arxiv.org/abs/2009.00514

Adding a new constraint is as simple as defining a new function with the same name as the constraint and using the @usual macro to define it. The macro will take care of adding the new constraint to the USUAL_CONSTRAINTS dictionary.

Example

julia
@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals)

source


# Constraints.describeFunction.
julia
describe(constraints::Dict{Symbol,Constraint}=USUAL_CONSTRAINTS; width=150)

Return a pretty table with the description of the constraints in constraints.

Arguments

  • constraints::Dict{Symbol,Constraint}: dictionary of constraints to describe. Default is USUAL_CONSTRAINTS.

  • width::Int: width of the table.

Example

julia
describe()

source


# ConstraintCommons.extract_parametersFunction.
julia
extract_parameters(m::Union{Method, Function}; parameters)

Extracts the intersection between the kargs of m and parameters (defaults to USUAL_CONSTRAINT_PARAMETERS).

source

julia
extract_parameters(s::Symbol, constraints_dict=USUAL_CONSTRAINTS; parameters=ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS)

Return the parameters of the constraint s in constraints_dict.

Arguments

  • s::Symbol: the constraint name.

  • constraints_dict::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

  • parameters::Vector{Symbol}: vector of parameters. Default is ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS.

Example

julia
extract_parameters(:all_different)

source


# Constraints.@usualMacro.
julia
usual(ex::Expr)

This macro is used to define a new constraint or update an existing one in the USUAL_CONSTRAINTS dictionary. It takes an expression ex as input, which represents the definition of a constraint.

Here's a step-by-step explanation of what the macro does:

  1. It first extracts the symbol of the concept from the input expression. This symbol is expected to be the first argument of the first argument of the expression. For example, if the expression is @usual all_different(x; y=1), the symbol would be :all_different.

  2. It then calls the shrink_concept function on the symbol to get a simplified version of the concept symbol.

  3. It initializes a dictionary defaults to store whether each keyword argument of the concept has a default value or not.

  4. It checks if the expression has more than two arguments. If it does, it means that there are keyword arguments present. It then loops over these keyword arguments. If a keyword argument is a symbol, it means it doesn't have a default value, so it adds an entry to the defaults dictionary with the keyword argument as the key and false as the value. If a keyword argument is not a symbol, it means it has a default value, so it adds an entry to the defaults dictionary with the keyword argument as the key and true as the value.

  5. It calls the make_error function on the simplified concept symbol to generate an error function for the constraint.

  6. It evaluates the input expression to get the concept function.

  7. It checks if the USUAL_CONSTRAINTS dictionary already contains an entry for the simplified concept symbol. If it does, it adds the defaults dictionary to the parameters of the existing constraint. If it doesn't, it creates a new constraint with the concept function, a description, the error function, and the defaults dictionary as the parameters, and adds it to the USUAL_CONSTRAINTS dictionary.

This macro is used to make it easier to define and update constraints in a consistent and possibly automated way.

Arguments

  • ex::Expr: expression to parse.

Example

julia
@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals)

source


# Constraints.constraints_parametersFunction.
julia
constraints_parameters(C=USUAL_CONSTRAINTS)

Return a pretty table with the parameters of the constraints in C.

Arguments

  • C::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

Example

julia
constraints_parameters()

source


# Constraints.constraints_descriptionsFunction.
julia
constraints_descriptions(C=USUAL_CONSTRAINTS)

Return a pretty table with the descriptions of the constraints in C.

Arguments

  • C::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

Example

julia
constraints_descriptions()

source


# Constraints.conceptFunction.
julia
concept(c::Constraint)

Return the concept (function) of constraint c. concept(c::Constraint, x...; param = nothing) Apply the concept of c to values x and optionally param.

source

julia
concept(s::Symbol, args...; kargs...)

Return the concept of the constraint s applied to args and kargs. This is a shortcut for concept(USUAL_CONSTRAINTS[s])(args...; kargs...).

Arguments

  • s::Symbol: the constraint name.

  • args...: the arguments to apply the concept to.

  • kargs...: the keyword arguments to apply the concept to.

Example

julia
concept(:all_different, [1, 2, 3])

source


- - - - \ No newline at end of file diff --git a/dev/constraints/counting_summing_constraints.html b/dev/constraints/counting_summing_constraints.html deleted file mode 100644 index 3ced709..0000000 --- a/dev/constraints/counting_summing_constraints.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - Constraints.jl: Streamlining Constraint Definition and Integration in Julia | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Counting and Summing Constraints

# Constraints.xcsp_sumFunction.
julia
xcsp_sum(list, coeffs, condition)

Return true if the sum of the variables in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • coeffs::Vector{Int}: list of coefficients to use.

  • condition: condition to satisfy.

Variants

  • :sum: Global constraint ensuring that the sum of the variables in x satisfies a given condition.
julia
concept(:sum, x; op===, pair_vars=ones(x), val)
-concept(:sum)(x; op===, pair_vars=ones(x), val)

Examples

julia
c = concept(:sum)
-
-c([1, 2, 3, 4, 5]; op===, val=15)
-c([1, 2, 3, 4, 5]; op===, val=2)
-c([1, 2, 3, 4, 3]; op=≤, val=15)
-c([1, 2, 3, 4, 3]; op=≤, val=3)

source


# Constraints.xcsp_countFunction.
julia
xcsp_count(list, values, condition)

Return true if the number of occurrences of the values in values in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • values::Vector{Int}: list of values to check.

  • condition: condition to satisfy.

Variants

  • :count: Constraint ensuring that the number of occurrences of the values in vals in x satisfies the given condition.
julia
concept(:count, x; vals, op, val)
-concept(:count)(x; vals, op, val)
  • :at_least: Constraint ensuring that the number of occurrences of the values in vals in x is at least val.
julia
concept(:at_least, x; vals, val)
-concept(:at_least)(x; vals, val)
  • :at_most: Constraint ensuring that the number of occurrences of the values in vals in x is at most val.
julia
concept(:at_most, x; vals, val)
-concept(:at_most)(x; vals, val)
  • :exactly: Constraint ensuring that the number of occurrences of the values in vals in x is exactly val.
julia
concept(:exactly, x; vals, val)
-concept(:exactly)(x; vals, val)

Examples

julia
c = concept(:count)
-
-c([2, 1, 4, 3]; vals=[1, 2, 3, 4], op=≥, val=2)
-c([1, 2, 3, 4]; vals=[1, 2], op==, val=2)
-c([2, 1, 4, 3]; vals=[1, 2], op=≤, val=1)

source


# Constraints.xcsp_nvaluesFunction.
julia
xcsp_nvalues(list, condition, except)

Return true if the number of distinct values in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • condition: condition to satisfy.

  • except::Union{Nothing, Vector{Int}}: list of values to exclude. Default is nothing.

Variants

  • :nvalues: The nValues constraint specifies that the number of distinct values in the list of variables x is equal to a given value. The constraint is defined by the following expression: nValues(x, op, val) where x is a list of variables, op is a comparison operator, and val is an integer value.
julia
concept(:nvalues, x; op, val)
-concept(:nvalues)(x; op, val)

Examples

julia
c = concept(:nvalues)
-
-c([1, 2, 3, 4, 5]; op = ==, val = 5)
-c([1, 2, 3, 4, 5]; op = ==, val = 2)
-c([1, 2, 3, 4, 3]; op = <=, val = 5)
-c([1, 2, 3, 4, 3]; op = <=, val = 3)

source


# Constraints.xcsp_cardinalityFunction.
julia
xcsp_cardinality(list, values, occurs, closed)

Return true if the number of occurrences of the values in values in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • values::Vector{Int}: list of values to check.

  • occurs::Vector{Int}: list of occurrences to check.

  • closed::Bool: whether the constraint is closed or not.

Variants

  • :cardinality: The cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables.
julia
concept(:cardinality, x; bool=false, vals)
-concept(:cardinality)(x; bool=false, vals)
  • :cardinality_closed: The closed cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. It is closed, meaning that all values in the domain of the variables must be considered.
julia
concept(:cardinality_closed, x; vals)
-concept(:cardinality_closed)(x; vals)
  • :cardinality_open: The open cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. It is open, meaning that only the values in the list of values must be considered.
julia
concept(:cardinality_open, x; vals)
-concept(:cardinality_open)(x; vals)

Examples

julia
c = concept(:cardinality)
-
-c([2, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3])
-c([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=false)
-c([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=true)
-c([2, 5, 10, 10]; vals=[2 1; 5 1; 10 2])
-c([2, 5, 10, 10]; vals=[2 0 1 42; 5 1 3 7; 10 2 3 -4])
-c([2, 5, 5, 10]; vals=[2 0 1; 5 1 3; 10 2 3])
-c([2, 5, 10, 8]; vals=[2 1; 5 1; 10 2])
-c([5, 5, 5, 10]; vals=[2 0 1 42; 5 1 3 7; 10 2 3 -4])
-
-cc = concept(:cardinality_closed)
-cc([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3])
-
-co = concept(:cardinality_open)
-co([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3])

source


- - - - \ No newline at end of file diff --git a/dev/constraints/elementary_constraints.html b/dev/constraints/elementary_constraints.html deleted file mode 100644 index 50d72ee..0000000 --- a/dev/constraints/elementary_constraints.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - Constraints.jl: Streamlining Constraint Definition and Integration in Julia | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Elementary Constraints

# Constraints.xcsp_instantiationFunction.
julia
xcsp_instantiation(; list, values)

Return true if the instantiation constraint is satisfied, false otherwise. The instantiation constraint is a global constraint used in constraint programming that ensures that a list of variables takes on a specific set of values in a specific order.

Arguments

  • list::AbstractVector: list of values to check.

  • values::AbstractVector: list of values to check against.

Variants

  • :instantiation: The instantiation constraint is a global constraint used in constraint programming that ensures that a list of variables takes on a specific set of values in a specific order.
julia
concept(:instantiation, x; pair_vars)
-concept(:instantiation)(x; pair_vars)

Examples

julia
c = concept(:instantiation)
-
-c([1, 2, 3, 4, 5]; pair_vars=[1, 2, 3, 4, 5])
-c([1, 2, 3, 4, 5]; pair_vars=[1, 2, 3, 4, 6])

source


- - - - \ No newline at end of file diff --git a/dev/constraints/generic_constraints.html b/dev/constraints/generic_constraints.html deleted file mode 100644 index 8e907c9..0000000 --- a/dev/constraints/generic_constraints.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - Generic Constraints | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Generic Constraints

In the XCSP³-core standard, generic constraints are categorized into two main types: intention and extension constraints.

Intention Constraints

These are constraints that are defined by a logical expression or a function. They are called intentional because they are defined by the property they satisfy. For example, a constraint that specifies that a variable x must be less than a variable y could be defined intentionally as x<y.

Note that the intention constraint is not directly available through the JC-API in Constraints.jl. It is designed as such since defining a constraint through a predicate is the natural way.

We provide a straightforward example through the :dist_different constraint on how to define and add such a constraint in the USUAL_CONSTRAINTS collection.

Higher level modeling language such as JuMP should provide a Intention interface.

Defining an intention constraint in JC-API

We use the dist_different constraint to illustrate how to define an intention constraint in Constraints.jl. The dist_different constraint ensures that the distances between marks x on a ruler are unique.

|x[1]x[2]||x[3]x[4]|

The constraint is then added to the usual constraints collection.

julia
const description_dist_different = """
-Ensures that the distances between marks on the ruler are unique.
-"""
-
-# Define the predicate
-predicate_dist_different(x) = abs(x[1] - x[2])  abs(x[3] - x[4])
-
-# Add it to usual constraints
-@usual concept_dist_different(x) = xcsp_intension(
-    list = x,
-    predicate = predicate_dist_different
-)

Please check the section dedicated to the Golomb Ruler problem to see a use for this constraint. <!– TODO: Golomb Ruler –>

APIs

Note that the intension constraint is not directly available through the JC-API in Constraints.jl. It is designed as such since defining a constraint through a predicate is the natural way.

We provide here a usage example for the :dist_different constraint, previously added to the USUAL_CONSTRAINTS collection.

Higher level modeling language such as JuMP should provide an Intension interface.

julia
concept(:dist_different, x)
-concept(:dist_different)(x)
julia
# Defines the DistDifferent constraint
-c = x -> xcsp_intension(
-    list = x,
-    predicate = y -> abs(y[1] - y[2])  abs(y[3] - y[4])
-)
-
-c([1, 2, 3, 3]) # true
-c([1, 2, 3, 4]) # false
julia
# TODO: How to handle intention in JuMP/MOI
julia
# TODO: How to handle intention in JuMP/MOI

Test for DocumenterVitePress Issue

julia
c = concept(:dist_different)
-c([1, 2, 3, 3]) && !c([1, 2, 3, 4])
true
julia
c = concept(:dist_different)
-c([1, 2, 3, 3]) && !c([1, 2, 3, 4])
true

Specific documentation

# Constraints.xcsp_intensionFunction.
julia
xcsp_intension(list, predicate)

An intensional constraint is usually defined from a predicate over list. As such it encompass any generic constraint.

Arguments

  • list::Vector{Int}: A list of variables

  • predicate::Function: A predicate over list

Variants

  • :dist_different: A constraint ensuring that the distances between marks on the ruler are unique. Specifically, it checks that the distance between x[1] and x[2], and the distance between x[3] and x[4], are different. This constraint is fundamental in ensuring the validity of a Golomb ruler, where no two pairs of marks should have the same distance between them.
julia
concept(:dist_different, x)
-concept(:dist_different)(x)

Examples

@example
2 + 2
@example
2 + 2
@example
using Constraints # hide
-c = concept(:dist_different)
-c([1, 2, 3, 3]) && !c([1, 2, 3, 4])
@example
using Constraints # hide
-c = concept(:dist_different)
-c([1, 2, 3, 3]) && !c([1, 2, 3, 4])

source


Extension Constraints

These are constraints that are defined by explicitly listing all the tuples of values that satisfy the constraint. They are called extensional because they are defined by the set of values they allow. For example, a binary constraint that specifies that a variable X must be either 1 or 2 and a variable Y must be either 3 or 4 could be defined extensionally by the set of tuples {(1,3), (1,4), (2,3), (2,4)}.

These two types of constraints provide a flexible way to define complex relationships between variables in constraint programming.

XCSP in Constraints.jl {#XCSP-in-Constraints.jl}

# Constraints.xcsp_extensionFunction.
julia
xcsp_extension(; list, supports=nothing, conflicts=nothing)

Global constraint enforcing that the tuple x matches a configuration within the supports set pair_vars[1] or does not match any configuration within the conflicts set pair_vars[2]. It embodies the logic: x ∈ pair_vars[1] || x ∉ pair_vars[2], providing a comprehensive way to define valid (supported) and invalid (conflicted) tuples for constraint satisfaction problems. This constraint is versatile, allowing for the explicit delineation of both acceptable and unacceptable configurations.

Arguments

  • list::Vector{Int}: A list of variables

  • supports::Vector{Vector{Int}}: A set of supported tuples. Default to nothing.

  • conflicts::Vector{Vector{Int}}: A set of conflicted tuples. Default to nothing.

Variants

  • :extension: Global constraint enforcing that the tuple x matches a configuration within the supports set pair_vars[1] or does not match any configuration within the conflicts set pair_vars[2]. It embodies the logic: x ∈ pair_vars[1] || x ∉ pair_vars[2], providing a comprehensive way to define valid (supported) and invalid (conflicted) tuples for constraint satisfaction problems. This constraint is versatile, allowing for the explicit delineation of both acceptable and unacceptable configurations.
julia
concept(:extension, x; pair_vars)
-concept(:extension)(x; pair_vars)
  • :supports: Global constraint ensuring that the tuple x matches a configuration listed within the support set pair_vars. This constraint is derived from the extension model, specifying that x must be one of the explicitly defined supported configurations: x ∈ pair_vars. It is utilized to directly declare the tuples that are valid and should be included in the solution space.
julia
concept(:supports, x; pair_vars)
-concept(:supports)(x; pair_vars)
  • :conflicts: Global constraint ensuring that the tuple x does not match any configuration listed within the conflict set pair_vars. This constraint, originating from the extension model, stipulates that x must avoid all configurations defined as conflicts: x ∉ pair_vars. It is useful for specifying tuples that are explicitly forbidden and should be excluded from the solution space.
julia
concept(:conflicts, x; pair_vars)
-concept(:conflicts)(x; pair_vars)

Examples

julia
c = concept(:extension)
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 3, 4, 5]])
-c([1, 2, 3, 4, 5]; pair_vars=([[1, 2, 3, 4, 5]], [[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]]))
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]])
-
-c = concept(:supports)
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 3, 4, 5]])
-
-c = concept(:conflicts)
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]])

source


- - - - \ No newline at end of file diff --git a/dev/constraints/graph_constraints.html b/dev/constraints/graph_constraints.html deleted file mode 100644 index a700b09..0000000 --- a/dev/constraints/graph_constraints.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - Constraints.jl: Streamlining Constraint Definition and Integration in Julia | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Constraints on Graphs

# Constraints.xcsp_circuitFunction.
julia
xcsp_circuit(; list, size)

Return true if the circuit constraint is satisfied, false otherwise. The circuit constraint is a global constraint used in constraint programming, often in routing problems. It ensures that the values of a list of variables form a circuit, i.e., a sequence where each value is the index of the next value in the sequence, and the sequence eventually loops back to the start.

Arguments

  • list::AbstractVector: list of values to check.

  • size::Int: size of the circuit.

Variants

  • :circuit: The circuit constraint is a global constraint used in constraint programming, often in routing problems. It ensures that the values of a list of variables form a circuit, i.e., a sequence where each value is the index of the next value in the sequence, and the sequence eventually loops back to the start.
julia
concept(:circuit, x; op, val)
-concept(:circuit)(x; op, val)

Examples

julia
c = concept(:circuit)
-
-c([1, 2, 3, 4])
-c([2, 3, 4, 1])
-c([2, 3, 1, 4]; op = ==, val = 3)
-c([4, 3, 1, 3]; op = >, val = 0)

source


- - - - \ No newline at end of file diff --git a/dev/constraints/intro.html b/dev/constraints/intro.html deleted file mode 100644 index ee20bec..0000000 --- a/dev/constraints/intro.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Introduction to basics cosntraints related tools | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Introduction to basics cosntraints related tools

About constraints.

- - - - \ No newline at end of file diff --git a/dev/constraints/language_constraints.html b/dev/constraints/language_constraints.html deleted file mode 100644 index 31d7067..0000000 --- a/dev/constraints/language_constraints.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - Constraints.jl: Streamlining Constraint Definition and Integration in Julia | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Constraints defined from Languages

# Constraints.xcsp_regularFunction.
julia
xcsp_regular(; list, automaton)
-
-Ensures that a sequence `x` (interpreted as a word) is accepted by the regular language represented by a given automaton. This constraint verifies the compliance of `x` with the language rules encoded within the `automaton` parameter, which must be an instance of `<:AbstractAutomaton`.

Arguments

  • list::Vector{Int}: A list of variables

  • automaton<:AbstractAutomaton: An automaton representing the regular language

Variants

  • :regular: Ensures that a sequence x (interpreted as a word) is accepted by the regular language represented by a given automaton. This constraint verifies the compliance of x with the language rules encoded within the automaton parameter, which must be an instance of <:AbstractAutomaton.
julia
concept(:regular, x; language)
-concept(:regular)(x; language)

Examples

julia
c = concept(:regular)
-
-states = Dict(
-    (:a, 0) => :a,
-    (:a, 1) => :b,
-    (:b, 1) => :c,
-    (:c, 0) => :d,
-    (:d, 0) => :d,
-    (:d, 1) => :e,
-    (:e, 0) => :e,
-)
-start = :a
-finish = :e
-
-a = Automaton(states, start, finish)
-
-c([0,0,1,1,0,0,1,0,0]; language = a)
-c([1,1,1,0,1]; language = a)

source


# Constraints.xcsp_mddFunction.
julia
xcsp_mdd(; list, diagram)

Return a function that checks if the list of values list satisfies the MDD diagram.

Arguments

  • list::Vector{Int}: list of values to check.

  • diagram::MDD: MDD to check.

Variants

  • :mdd: Multi-valued Decision Diagram (MDD) constraint. The MDD constraint is a constraint that can be used to model a wide range of problems. It is a directed graph where each node is labeled with a value and each edge is labeled with a value. The constraint is satisfied if there is a path from the first node to the last node such that the sequence of edge labels is a valid sequence of the value labels.
julia
concept(:mdd, x; language)
-concept(:mdd)(x; language)

Examples

julia
c = concept(:mdd)
-
-states = [
-    Dict( # level x1
-        (:r, 0) => :n1,
-        (:r, 1) => :n2,
-        (:r, 2) => :n3,
-    ),
-    Dict( # level x2
-        (:n1, 2) => :n4,
-        (:n2, 2) => :n4,
-        (:n3, 0) => :n5,
-    ),
-    Dict( # level x3
-        (:n4, 0) => :t,
-        (:n5, 0) => :t,
-    ),
-]
-
-a = MDD(states)
-
-c([0,2,0]; language = a)
-c([1,2,0]; language = a)
-c([2,0,0]; language = a)
-c([2,1,2]; language = a)
-c([1,0,2]; language = a)
-c([0,1,2]; language = a)

source


- - - - \ No newline at end of file diff --git a/dev/constraints/packing_scheduling_constraints.html b/dev/constraints/packing_scheduling_constraints.html deleted file mode 100644 index 2986fa3..0000000 --- a/dev/constraints/packing_scheduling_constraints.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - Constraints.jl: Streamlining Constraint Definition and Integration in Julia | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

Packing and Scheduling Constraints

# Constraints.xcsp_cumulativeFunction.
julia
xcsp_cumulative(; origins, lengths, heights, condition)

Return true if the cumulative constraint is satisfied, false otherwise. The cumulative constraint is a global constraint used in constraint programming that is often used in scheduling problems. It ensures that for any point in time, the sum of the "heights" of tasks that are ongoing at that time does not exceed a certain limit.

Arguments

  • origins::AbstractVector: list of origins of the tasks.

  • lengths::AbstractVector: list of lengths of the tasks.

  • heights::AbstractVector: list of heights of the tasks.

  • condition::Tuple: condition to check.

Variants

  • :cumulative: The cumulative constraint is a global constraint used in constraint programming that is often used in scheduling problems. It ensures that for any point in time, the sum of the "heights" of tasks that are ongoing at that time does not exceed a certain limit.
julia
concept(:cumulative, x; pair_vars, op, val)
-concept(:cumulative)(x; pair_vars, op, val)

Examples

julia
c = concept(:cumulative)
-
-c([1, 2, 3, 4, 5]; val = 1)
-c([1, 2, 2, 4, 5]; val = 1)
-c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op =, val = 5)
-c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5)

source


# Constraints.xcsp_no_overlapFunction.
julia
xcsp_no_overlap(; origins, lengths, zero_ignored)

Return true if the no_overlap constraint is satisfied, false otherwise. The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts.

Arguments

  • origins::AbstractVector: list of origins of the tasks.

  • lengths::AbstractVector: list of lengths of the tasks.

  • zero_ignored::Bool: whether to ignore zero-length tasks.

Variants

  • :no_overlap: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts.
julia
concept(:no_overlap, x; pair_vars, bool)
-concept(:no_overlap)(x; pair_vars, bool)
  • :no_overlap_no_zero: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant ignores zero-length tasks.
julia
concept(:no_overlap_no_zero, x; pair_vars)
-concept(:no_overlap_no_zero)(x; pair_vars)
  • :no_overlap_with_zero: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant includes zero-length tasks.
julia
concept(:no_overlap_with_zero, x; pair_vars)
-concept(:no_overlap_with_zero)(x; pair_vars)

Examples

julia
c = concept(:no_overlap)
-
-c([1, 2, 3, 4, 5])
-c([1, 2, 3, 4, 1])
-c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 1, 1])
-c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 3, 1])
-c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 3, 1, 1])
-c([1, 1, 1, 3, 5, 2, 7, 7, 5, 12, 8, 7]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3)
-c([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3)

source


- - - - \ No newline at end of file diff --git a/dev/cp/advanced.html b/dev/cp/advanced.html deleted file mode 100644 index 27993c2..0000000 --- a/dev/cp/advanced.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Advanced Constraint Programming Techniques | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Advanced Constraint Programming Techniques

Global Constraints and Their Uses

  • Dive deeper into global constraints and how they simplify complex problems.

Search Strategies and Optimization

  • Discuss various search strategies and their impact on solving CP problems.
- - - - \ No newline at end of file diff --git a/dev/cp/applications.html b/dev/cp/applications.html deleted file mode 100644 index 16b82b5..0000000 --- a/dev/cp/applications.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Applying Optimization Methods | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Applying Optimization Methods

Case Studies and Real-World Applications

  • Showcase studies where CP and optimization have been successfully applied.

From Theory to Practice

  • Guide readers through the process of formulating and solving an optimization problem from a real-world scenario.
- - - - \ No newline at end of file diff --git a/dev/cp/contribution.html b/dev/cp/contribution.html deleted file mode 100644 index 8c1f86b..0000000 --- a/dev/cp/contribution.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Community and Contribution | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Community and Contribution

Joining the JuliaConstraint Community

  • Encourage readers to join the community, highlighting how they can contribute and collaborate.

Future Directions

  • Share the vision for JuliaConstraint and upcoming projects or areas of research.
- - - - \ No newline at end of file diff --git a/dev/cp/cp101.html b/dev/cp/cp101.html deleted file mode 100644 index eb8afb5..0000000 --- a/dev/cp/cp101.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Constraint Programming 101 | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Constraint Programming 101

What is Constraint Programming?

  • Define CP and its significance in solving combinatorial problems.

Basic Concepts and Terminology

  • Introduce key concepts such as constraints, domains, and variables.

How CP differs from other optimization techniques

  • Contrast with other methods like linear programming and metaheuristics.
- - - - \ No newline at end of file diff --git a/dev/cp/ecosystem.html b/dev/cp/ecosystem.html deleted file mode 100644 index e18ccd5..0000000 --- a/dev/cp/ecosystem.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Exploring JuliaConstraint Packages | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Exploring JuliaConstraint Packages

Package Overviews

  • Introduce each package within the JuliaConstraint organization, its purpose, and primary features.

Installation and Getting Started Guides

  • Provide step-by-step instructions for installing and getting started with each package.
- - - - \ No newline at end of file diff --git a/dev/cp/getting_started.html b/dev/cp/getting_started.html deleted file mode 100644 index c8b14a8..0000000 --- a/dev/cp/getting_started.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - Getting Started with Julia for CP and Optimization | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Getting Started with Julia for CP and Optimization

Why Julia?

  • Discuss the advantages of Julia for computational science and optimization, highlighting its performance and ease of use.

Setting Up Your Julia Environment

We encourage users to install Julia through juliaup, a version manager for the Julia language. Please look at the official Julia language download page for further information. Once installed, Julia can be used through various editors (Visual Studio Code), notebooks (Pluto.jl), or command-line (REPL).

Although a part of the CP solvers available within the Julia ecosystem have their own interface, we encourage users to use the JuMP modeling language if possible.

Julia Constraints host several solvers(' interfaces). Due to its flexibility in modeling and solving, we will use LocalSearchSolvers.jl through its JuMP interface CBLS.jl as the basic example. Note that depending on the targeted instances, available hardware, and expectations, it is not necessarily the best choice.

All along the documentation, we will try to provide syntax examples for different setup.

julia
using LocalSearchSolvers
julia
using JuMP, CBLS
julia
# TODO: Add other solvers

Your First Julia CP Model

We will start with a classic puzzle game and some of its not that simple variants: the Sudoku.

(From Wikipedia) In classic Sudoku, the objective is to fill a 9 × 9 grid with digits so that each column, each row, and each of the nine 3 × 3 subgrids that compose the grid (also called "boxes", "blocks", or "regions") contains all of the digits from 1 to 9. The puzzle setter provides a partially completed grid, which for a well-posed puzzle has a single solution.

Constraint Programming follows the model-and-solve approach. We first need to model our Sudoku problem.

julia
m = JuMP.Model(CBLS.Optimizer)
julia
# TODO: Add other solvers

But what are the basis of CP models? It is quite simple:

  1. A collection X=X1,,Xn of variables with each an associated domain.
julia
@variable(m, 1 X[1:9, 1:9]  9, Int)
julia
# TODO: Add other solvers
  1. A collection of predicates (called constraints) C=C1,,Cn over (subsets of) X.

When modeling problems as CP, one might define and use their own predicates. However, a large collection of already defined constraints exists. One, if not the most, iconic global constraint is called AllDifferent. It ensures that all variables take distinct values.

Sudoku puzzles can be defined using only this one constraint applied to different subsets of variables.

julia
for i in 1:9
-        @constraint(m, X[i,:] in AllDifferent()) # rows
-        @constraint(m, X[:,i] in AllDifferent()) # columns
-end
julia
# TODO: Add other solvers

The last series of AllDifferent constraint is less straight forward. We need to ensure that each 3 × 3 subgrid (block) is filled with distinct values.

julia
for i in 0:2, j in 0:2 # blocks
-    @constraint(
-        m,
-        vec(X[(3i+1):(3(i+1)), (3j+1):(3(j+1))]) in AllDifferent(),
-    )
-end
julia
# TODO: Add other solvers

We can now simply run our solver to look for a feasible solution.

julia
optimize!(m)

Note that this is heuristic solver, we might not get a feasible solution! Let's check it out. The value function print the value of a JuMP variable. We can cast it over a collection with the value. syntax.

julia
value.(X)
- - - - \ No newline at end of file diff --git a/dev/cp/intro.html b/dev/cp/intro.html deleted file mode 100644 index 9f82d04..0000000 --- a/dev/cp/intro.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Welcome to Julia Constraints | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Welcome to Julia Constraints

An introductory post/chapter that provides an overview of the JuliaConstraint organization, its mission, and what readers can expect to learn from the content. Highlight the importance of Constraint Programming (CP) and optimization in solving real-world problems.

- - - - \ No newline at end of file diff --git a/dev/cp/models.html b/dev/cp/models.html deleted file mode 100644 index 99058ce..0000000 --- a/dev/cp/models.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Building and Analyzing Models | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Building and Analyzing Models

Modeling Best Practices

  • Share best practices and tips for building efficient CP and optimization models.

Performance Analysis and Improvement

  • Teach how to analyze and improve the performance of models.
- - - - \ No newline at end of file diff --git a/dev/cp/opt.html b/dev/cp/opt.html deleted file mode 100644 index afceb21..0000000 --- a/dev/cp/opt.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Dive into Optimization | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Dive into Optimization

Understanding Optimization

  • Explanation of optimization, types of optimization problems (e.g., linear, nonlinear, integer programming).

Metaheuristics Overview

  • Introduce concepts like Genetic Algorithms, Simulated Annealing, and Tabu Search.

Mathematical Programming Basics

  • Cover the fundamentals of mathematical programming and its role in optimization.
- - - - \ No newline at end of file diff --git a/dev/cp/tuto_xp.html b/dev/cp/tuto_xp.html deleted file mode 100644 index 9eb30ab..0000000 --- a/dev/cp/tuto_xp.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Tutorials and Experiments | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Tutorials and Experiments

Hands-On Tutorials

  • Provide step-by-step tutorials covering various topics and complexity levels.

Experimental Analysis

  • Discuss the importance of experimental analysis in CP and how to conduct meaningful experiments.
- - - - \ No newline at end of file diff --git a/dev/full_api.html b/dev/full_api.html deleted file mode 100644 index 0cd5c61..0000000 --- a/dev/full_api.html +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - Full API | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Full API

# ConstraintCommons.USUAL_CONSTRAINT_PARAMETERSConstant.
julia
const USUAL_CONSTRAINT_PARAMETERS

List of usual constraints parameters (based on XCSP3-core constraints).

julia
const USUAL_CONSTRAINT_PARAMETERS = [
-    :bool,
-    :dim,
-    :id,
-    :language,
-    :op,
-    :pair_vars,
-    :val,
-    :vals,
-]

source


# ConstraintCommons.AbstractAutomatonType.
julia
AbstractAutomaton

An abstract interface for automata used in Julia Constraints packages. Requirements:

  • accept(a<:AbstractAutomaton, word): return true if a accepts word.

source


# ConstraintCommons.AbstractMultivaluedDecisionDiagramType.
julia
AbstractMultivaluedDecisionDiagram

An abstract interface for Multivalued Decision Diagrams (MDD) used in Julia Constraints packages. Requirements:

  • accept(a<:AbstractMultivaluedDecisionDiagram, word): return true if a accepts word.

source


# ConstraintCommons.AutomatonType.
julia
Automaton{S, T, F <: Union{S, Vector{S}, Set{S}}} <: AbstractAutomaton

A minimal implementation of a deterministic automaton structure.

source


# ConstraintCommons.MDDType.
julia
MDD{S,T} <: AbstractMultivaluedDecisionDiagram

A minimal implementation of a multivalued decision diagram structure.

source


# ConstraintCommons.acceptMethod.
julia
accept(a::Union{Automaton, MDD}, w)

Return true if a accepts the word w and false otherwise.

source


# ConstraintCommons.at_endMethod.
julia
at_end(a::Automaton, s)

Internal method used by accept with Automaton.

source


# ConstraintCommons.extract_parametersMethod.
julia
extract_parameters(m::Union{Method, Function}; parameters)

Extracts the intersection between the kargs of m and parameters (defaults to USUAL_CONSTRAINT_PARAMETERS).

source


# ConstraintCommons.incsert!Function.
julia
incsert!(d::Union{AbstractDict, AbstractDictionary}, ind, val = 1)

Increase or insert a counter in a dictionary-based collection. The counter insertion defaults to val = 1.

source


# ConstraintCommons.oversampleMethod.
julia
oversample(X, f)

Oversample elements of X until the boolean function f has as many true and false configurations.

source


# ConstraintCommons.symconFunction.
julia
Base.:*(s1::Symbol, s2::Symbol, connector::AbstractString="_")

Extends * to Symbols multiplication by connecting the symbols by an _.

source


# ConstraintCommons.δ_extremaMethod.
julia
δ_extrema(X...)

Compute both the difference between the maximum and the minimum of over all the collections of X.

source


# ConstraintDomains.AbstractDomainType.
julia
AbstractDomain

An abstract super type for any domain type. A domain type D <: AbstractDomain must implement the following methods to properly interface AbstractDomain.

  • Base.∈(val, ::D)

  • Base.rand(::D)

  • Base.length(::D) that is the number of elements in a discrete domain, and the distance between bounds or similar for a continuous domain

Additionally, if the domain is used in a dynamic context, it can extend

  • add!(::D, args)

  • delete!(::D, args)

where args depends on D's structure

source


# ConstraintDomains.BoolParameterDomainType.
julia
BoolParameterDomain <: AbstractDomain

A domain to store boolean values. It is used to generate random parameters.

source


# ConstraintDomains.ContinuousDomainType.
julia
ContinuousDomain{T <: Real} <: AbstractDomain

An abstract supertype for all continuous domains.

source


# ConstraintDomains.DimParameterDomainType.
julia
DimParameterDomain <: AbstractDomain

A domain to store dimensions. It is used to generate random parameters.

source


# ConstraintDomains.DiscreteDomainType.
julia
DiscreteDomain{T <: Number} <: AbstractDomain

An abstract supertype for discrete domains (set, range).

source


# ConstraintDomains.EmptyDomainType.
julia
EmptyDomain

A struct to handle yet to be defined domains.

source


# ConstraintDomains.ExploreSettingsMethod.
julia
ExploreSettings(
-    domains;
-    complete_search_limit = 10^6,
-    max_samplings = sum(domain_size, domains),
-    search = :flexible,
-    solutions_limit = floor(Int, sqrt(max_samplings)),
-)

Settings for the exploration of a search space composed by a collection of domains.

source


# ConstraintDomains.FakeAutomatonType.
julia
FakeAutomaton{T} <: ConstraintCommons.AbstractAutomaton

A structure to generate pseudo automaton enough for parameter exploration.

source


# ConstraintDomains.IdParameterDomainType.
julia
IdParameterDomain <: AbstractDomain

A domain to store ids. It is used to generate random parameters.

source


# ConstraintDomains.IntervalsType.
julia
Intervals{T <: Real} <: ContinuousDomain{T}

An encapsuler to store a vector of PatternFolds.Interval. Dynamic changes to Intervals are not handled yet.

source


# ConstraintDomains.LanguageParameterDomainType.
julia
LanguageParameterDomain <: AbstractDomain

A domain to store languages. It is used to generate random parameters.

source


# ConstraintDomains.OpParameterDomainType.
julia
OpParameterDomain{T} <: AbstractDomain

A domain to store operators. It is used to generate random parameters.

source


# ConstraintDomains.PairVarsParameterDomainType.
julia
PairVarsParameterDomain{T} <: AbstractDomain

A domain to store values paired with variables. It is used to generate random parameters.

source


# ConstraintDomains.RangeDomainType.
julia
RangeDomain

A discrete domain defined by a range <: AbstractRange{Real}. As ranges are immutable in Julia, changes in RangeDomain must use set_domain!.

source


# ConstraintDomains.SetDomainType.
julia
SetDomain{T <: Number} <: DiscreteDomain{T}

Domain that stores discrete values as a set of (unordered) points.

source


# ConstraintDomains.ValParameterDomainType.
julia
ValParameterDomain{T} <: AbstractDomain

A domain to store one value. It is used to generate random parameters.

source


# ConstraintDomains.ValsParameterDomainType.
julia
ValsParameterDomain{T} <: AbstractDomain

A domain to store values. It is used to generate random parameters.

source


# Base.convertMethod.
julia
Base.convert(::Type{Union{Intervals, RangeDomain}}, d::Union{Intervals, RangeDomain})

Extends Base.convert for domains.

source


# Base.delete!Method.
julia
Base.delete!(d::SetDomain, value)(d::SetDomain, value)

Delete value from the list of points in d.

source


# Base.eltypeMethod.
julia
Base.eltype(::AbstractDomain)

Extend eltype for domains.

source


# Base.inMethod.
julia
Base.in(x, itv::Intervals)

Return true if x ∈ I for any 'I ∈ itv, false otherwise.x ∈ I` is equivalent to

  • a < x < b if I = (a, b)

  • a < x ≤ b if I = (a, b]

  • a ≤ x < b if I = [a, b)

  • a ≤ x ≤ b if I = [a, b]

source


# Base.inMethod.
julia
Base.in(value, d <: AbstractDomain)

Fallback method for value ∈ d that returns false.

source


# Base.inMethod.
julia
Base.in(value, d::D) where D <: DiscreteDomain

Return true if value is a point of d.

source


# Base.isemptyMethod.
julia
Base.isempty(d <: AbstractDomain)

Fallback method for isempty(d) that return length(d) == 0 which default to 0.

source


# Base.lengthMethod.
julia
Base.length(itv::Intervals)

Return the sum of the length of each interval in itv.

source


# Base.lengthMethod.
julia
Base.rand(d <: AbstractDomain)

Fallback method for length(d) that return 0.

source


# Base.lengthMethod.
julia
Base.length(d::D) where D <: DiscreteDomain

Return the number of points in d.

source


# Base.randMethod.
julia
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}

Extends Base.rand to (a collection of) domains.

source


# Base.randMethod.
julia
Base.rand(fa::FakeAutomaton)

Extends Base.rand. Currently simply returns fa.

source


# Base.randMethod.
julia
Base.rand(itv::Intervals)
-Base.rand(itv::Intervals, i)

Return a random value from itv, specifically from the ith interval if i is specified.

source


# Base.randMethod.
julia
Base.rand(d::D) where D <: DiscreteDomain

Draw randomly a point in d.

source


# Base.stringMethod.
julia
Base.string(D::Vector{<:AbstractDomain})
-Base.string(d<:AbstractDomain)

Extends the string method to (a vector of) domains.

source


# ConstraintCommons.acceptMethod.
julia
ConstraintCommons.accept(fa::FakeAutomaton, word)

Implement the accept methods for FakeAutomaton.

source


# ConstraintDomains.ArbitraryDomainMethod.
julia
ArbitraryDomain{T} <: DiscreteDomain{T}

A domain type that stores arbitrary values, possibly non numeric, of type T.

source


# ConstraintDomains._exploreMethod.
julia
_explore(args...)

Internals of the explore function. Behavior is automatically adjusted on the kind of exploration: :flexible, :complete, :partial.

source


# ConstraintDomains.add!Method.
julia
add!(d::SetDomain, value)

Add value to the list of points in d.

source


# ConstraintDomains.domainMethod.
julia
domain(values)
-domain(range::R) where {T <: Real, R <: AbstractRange{T}}

Construct either a SetDomain or a `RangeDomain``.

julia
d1 = domain(1:5)
-d2 = domain([53.69, 89.2, 0.12])
-d3 = domain([2//3, 89//123])
-d4 = domain(4.3)
-d5 = domain(1,42,86.9)

source


# ConstraintDomains.domainMethod.
julia
domain()

Construct an EmptyDomain.

source


# ConstraintDomains.domainMethod.
julia
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
-domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}

Construct a domain of continuous interval(s).

source


# ConstraintDomains.domain_sizeMethod.
julia
domain_size(itv::Intervals)

Return the difference between the highest and lowest values in itv.

source


# ConstraintDomains.domain_sizeMethod.
julia
domain_size(d <: AbstractDomain)

Fallback method for domain_size(d) that return length(d).

source


# ConstraintDomains.domain_sizeMethod.
julia
domain_size(d::D) where D <: DiscreteDomain

Return the maximum distance between two points in d.

source


# ConstraintDomains.exploreMethod.
julia
explore(domains, concept, param = nothing; search_limit = 1000, solutions_limit = 100)

Search (a part of) a search space and returns a pair of vector of configurations: (solutions, non_solutions). If the search space size is over search_limit, then both solutions and non_solutions are limited to solutions_limit.

Beware that if the density of the solutions in the search space is low, solutions_limit needs to be reduced. This process will be automatic in the future (simple reinforcement learning).

Arguments:

  • domains: a collection of domains

  • concept: the concept of the targeted constraint

  • param: an optional parameter of the constraint

  • sol_number: the required number of solutions (half of the number of configurations), default to 100

source


# ConstraintDomains.fake_automatonMethod.
julia
fake_automaton(d)

Construct a FakeAutomaton.

source


# ConstraintDomains.generate_parametersMethod.
julia
generate_parameters(d<:AbstractDomain, param)

Generates random parameters based on the domain d and the kind of parameters param.

source


# ConstraintDomains.get_domainMethod.
julia
get_domain(::AbstractDomain)

Access the internal structure of any domain type.

source


# ConstraintDomains.intersect_domains!Method.
julia
intersect_domains!(is, i, new_itvls)

Compute the intersections of a domain with an interval and store the results in new_itvls.

Arguments

  • is::IS: a collection of intervals.

  • i::I: an interval.

  • new_itvls::Vector{I}: a vector to store the results.

source


# ConstraintDomains.intersect_domainsMethod.
julia
intersect_domains(d₁, d₂)

Compute the intersections of two domains.

source


# ConstraintDomains.merge_domainsMethod.
julia
merge_domains(d₁::AbstractDomain, d₂::AbstractDomain)

Merge two domains of same nature (discrete/contiuous).

source


# ConstraintDomains.sizeMethod.
julia
Base.size(i::I) where {I <: Interval}

Defines the size of an interval as its span.

source


# ConstraintDomains.to_domainsMethod.
julia
to_domains(args...)

Convert various arguments into valid domains format.

source


# Constraints.USUAL_CONSTRAINTSConstant.
julia
USUAL_CONSTRAINTS::Dict

Dictionary that contains all the usual constraints defined in Constraint.jl. It is based on XCSP3-core specifications available at https://arxiv.org/abs/2009.00514

Adding a new constraint is as simple as defining a new function with the same name as the constraint and using the @usual macro to define it. The macro will take care of adding the new constraint to the USUAL_CONSTRAINTS dictionary.

Example

julia
@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals)

source


# Constraints.USUAL_SYMMETRIESConstant.
julia
USUAL_SYMMETRIES

A Dictionary that contains the function to apply for each symmetry to avoid searching a whole space.

source


# Constraints.ConstraintType.
julia
Constraint

Parametric structure with the following fields.

  • concept: a Boolean function that, given an assignment x, outputs true if x satisfies the constraint, and false otherwise.

  • error: a positive function that works as preferences over invalid assignments. Return 0.0 if the constraint is satisfied, and a strictly positive real otherwise.

source


# ConstraintCommons.extract_parametersFunction.
julia
extract_parameters(s::Symbol, constraints_dict=USUAL_CONSTRAINTS; parameters=ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS)

Return the parameters of the constraint s in constraints_dict.

Arguments

  • s::Symbol: the constraint name.

  • constraints_dict::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

  • parameters::Vector{Symbol}: vector of parameters. Default is ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS.

Example

julia
extract_parameters(:all_different)

source


# Constraints.argsMethod.
julia
args(c::Constraint)

Return the expected length restriction of the arguments in a constraint c. The value nothing indicates that any strictly positive number of value is accepted.

source


# Constraints.conceptMethod.
julia
concept(c::Constraint)

Return the concept (function) of constraint c. concept(c::Constraint, x...; param = nothing) Apply the concept of c to values x and optionally param.

source


# Constraints.conceptMethod.
julia
concept(s::Symbol, args...; kargs...)

Return the concept of the constraint s applied to args and kargs. This is a shortcut for concept(USUAL_CONSTRAINTS[s])(args...; kargs...).

Arguments

  • s::Symbol: the constraint name.

  • args...: the arguments to apply the concept to.

  • kargs...: the keyword arguments to apply the concept to.

Example

julia
concept(:all_different, [1, 2, 3])

source


# Constraints.concept_vs_errorMethod.
julia
concept_vs_error(c, e, args...; kargs...)

Compare the results of a concept function and an error function for the same inputs. It is mainly used for testing purposes.

Arguments

  • c: The concept function.

  • e: The error function.

  • args...: Positional arguments to be passed to both the concept and error functions.

  • kargs...: Keyword arguments to be passed to both the concept and error functions.

Returns

  • Boolean: Returns true if the result of the concept function is not equal to whether the result of the error function is greater than 0.0. Otherwise, it returns false.

Examples

julia
concept_vs_error(all_different, make_error(:all_different), [1, 2, 3]) # Returns false

source


# Constraints.constraints_descriptionsFunction.
julia
constraints_descriptions(C=USUAL_CONSTRAINTS)

Return a pretty table with the descriptions of the constraints in C.

Arguments

  • C::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

Example

julia
constraints_descriptions()

source


# Constraints.constraints_parametersFunction.
julia
constraints_parameters(C=USUAL_CONSTRAINTS)

Return a pretty table with the parameters of the constraints in C.

Arguments

  • C::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

Example

julia
constraints_parameters()

source


# Constraints.describeFunction.
julia
describe(constraints::Dict{Symbol,Constraint}=USUAL_CONSTRAINTS; width=150)

Return a pretty table with the description of the constraints in constraints.

Arguments

  • constraints::Dict{Symbol,Constraint}: dictionary of constraints to describe. Default is USUAL_CONSTRAINTS.

  • width::Int: width of the table.

Example

julia
describe()

source


# Constraints.error_fMethod.
julia
error_f(c::Constraint)

Return the error function of constraint c. error_f(c::Constraint, x; param = nothing) Apply the error function of c to values x and optionally param.

source


# Constraints.make_errorMethod.
julia
make_error(symb::Symbol)

Create a function that returns an error based on the predicate of the constraint identified by the symbol provided.

Arguments

  • symb::Symbol: The symbol used to determine the error function to be returned. The function first checks if a predicate with the prefix "icn_" exists in the Constraints module. If it does, it returns that function. If it doesn't, it checks for a predicate with the prefix "error_". If that exists, it returns that function. If neither exists, it returns a function that evaluates the predicate with the prefix "concept_" and returns the negation of its result cast to Float64.

Returns

  • Function: A function that takes in a variable x and an arbitrary number of parameters params. The function returns a Float64.

Examples

julia
e = make_error(:all_different)
-e([1, 2, 3]) # Returns 0.0
-e([1, 1, 3]) # Returns 1.0

source


# Constraints.params_lengthMethod.
julia
params_length(c::Constraint)

Return the expected length restriction of the arguments in a constraint c. The value nothing indicates that any strictly positive number of parameters is accepted.

source


# Constraints.shrink_conceptMethod.
julia
shrink_concept(s)

Simply delete the concept_ part of symbol or string starting with it. TODO: add a check with a warning if s starts with something different.

source


# Constraints.symmetriesMethod.
julia
symmetries(c::Constraint)

Return the list of symmetries of c.

source


# Constraints.xcsp_all_differentMethod.
julia
xcsp_all_different(list::Vector{Int})

Return true if all the values of list are different, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

Variants

  • :all_different: Global constraint ensuring that all the values of x are all different.
julia
concept(:all_different, x; vals)
-concept(:all_different)(x; vals)

Examples

julia
c = concept(:all_different)
-
-c([1, 2, 3, 4])
-c([1, 2, 3, 1])
-c([1, 0, 0, 4]; vals=[0])
-c([1, 0, 0, 1]; vals=[0])

source


# Constraints.xcsp_all_equalMethod.
julia
xcsp_all_equal(list::Vector{Int}, val::Int)

Return true if all the values of list are equal to val, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • val::Int: value to compare to.

Variants

  • :all_equal: Global constraint ensuring that all the values of x are all equal.
julia
concept(:all_equal, x; val=nothing, pair_vars=zeros(x), op=+)
-concept(:all_equal)(x; val=nothing, pair_vars=zeros(x), op=+)

Examples

julia
c = concept(:all_equal)
-
-c([0, 0, 0, 0])
-c([1, 2, 3, 4])
-c([3, 2, 1, 0]; pair_vars=[0, 1, 2, 3])
-c([0, 1, 2, 3]; pair_vars=[0, 1, 2, 3])
-c([1, 2, 3, 4]; op=/, val=1, pair_vars=[1, 2, 3, 4])
-c([1, 2, 3, 4]; op=*, val=1, pair_vars=[1, 2, 3, 4])

source


# Constraints.xcsp_cardinalityMethod.
julia
xcsp_cardinality(list, values, occurs, closed)

Return true if the number of occurrences of the values in values in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • values::Vector{Int}: list of values to check.

  • occurs::Vector{Int}: list of occurrences to check.

  • closed::Bool: whether the constraint is closed or not.

Variants

  • :cardinality: The cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables.
julia
concept(:cardinality, x; bool=false, vals)
-concept(:cardinality)(x; bool=false, vals)
  • :cardinality_closed: The closed cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. It is closed, meaning that all values in the domain of the variables must be considered.
julia
concept(:cardinality_closed, x; vals)
-concept(:cardinality_closed)(x; vals)
  • :cardinality_open: The open cardinality constraint, also known as the global cardinality constraint (GCC), is a constraint in constraint programming that restricts the number of times a value can appear in a set of variables. It is open, meaning that only the values in the list of values must be considered.
julia
concept(:cardinality_open, x; vals)
-concept(:cardinality_open)(x; vals)

Examples

julia
c = concept(:cardinality)
-
-c([2, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3])
-c([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=false)
-c([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3], bool=true)
-c([2, 5, 10, 10]; vals=[2 1; 5 1; 10 2])
-c([2, 5, 10, 10]; vals=[2 0 1 42; 5 1 3 7; 10 2 3 -4])
-c([2, 5, 5, 10]; vals=[2 0 1; 5 1 3; 10 2 3])
-c([2, 5, 10, 8]; vals=[2 1; 5 1; 10 2])
-c([5, 5, 5, 10]; vals=[2 0 1 42; 5 1 3 7; 10 2 3 -4])
-
-cc = concept(:cardinality_closed)
-cc([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3])
-
-co = concept(:cardinality_open)
-co([8, 5, 10, 10]; vals=[2 0 1; 5 1 3; 10 2 3])

source


# Constraints.xcsp_channelMethod.
julia
xcsp_channel(; list)

Return true if the channel constraint is satisfied, false otherwise. The channel constraint establishes a bijective correspondence between two sets of variables. This means that each value in the first set of variables corresponds to a unique value in the second set, and vice versa.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

Variants

  • :channel: The channel constraint establishes a bijective correspondence between two sets of variables. This means that each value in the first set of variables corresponds to a unique value in the second set, and vice versa.
julia
concept(:channel, x; dim=1, id=nothing)
-concept(:channel)(x; dim=1, id=nothing)

Examples

julia
c = concept(:channel)
-
-c([2, 1, 4, 3])
-c([1, 2, 3, 4])
-c([2, 3, 1, 4])
-c([2, 1, 5, 3, 4, 2, 1, 4, 5, 3]; dim=2)
-c([2, 1, 4, 3, 5, 2, 1, 4, 5, 3]; dim=2)
-c([false, false, true, false]; id=3)
-c([false, false, true, false]; id=1)

source


# Constraints.xcsp_circuitMethod.
julia
xcsp_circuit(; list, size)

Return true if the circuit constraint is satisfied, false otherwise. The circuit constraint is a global constraint used in constraint programming, often in routing problems. It ensures that the values of a list of variables form a circuit, i.e., a sequence where each value is the index of the next value in the sequence, and the sequence eventually loops back to the start.

Arguments

  • list::AbstractVector: list of values to check.

  • size::Int: size of the circuit.

Variants

  • :circuit: The circuit constraint is a global constraint used in constraint programming, often in routing problems. It ensures that the values of a list of variables form a circuit, i.e., a sequence where each value is the index of the next value in the sequence, and the sequence eventually loops back to the start.
julia
concept(:circuit, x; op, val)
-concept(:circuit)(x; op, val)

Examples

julia
c = concept(:circuit)
-
-c([1, 2, 3, 4])
-c([2, 3, 4, 1])
-c([2, 3, 1, 4]; op = ==, val = 3)
-c([4, 3, 1, 3]; op = >, val = 0)

source


# Constraints.xcsp_countMethod.
julia
xcsp_count(list, values, condition)

Return true if the number of occurrences of the values in values in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • values::Vector{Int}: list of values to check.

  • condition: condition to satisfy.

Variants

  • :count: Constraint ensuring that the number of occurrences of the values in vals in x satisfies the given condition.
julia
concept(:count, x; vals, op, val)
-concept(:count)(x; vals, op, val)
  • :at_least: Constraint ensuring that the number of occurrences of the values in vals in x is at least val.
julia
concept(:at_least, x; vals, val)
-concept(:at_least)(x; vals, val)
  • :at_most: Constraint ensuring that the number of occurrences of the values in vals in x is at most val.
julia
concept(:at_most, x; vals, val)
-concept(:at_most)(x; vals, val)
  • :exactly: Constraint ensuring that the number of occurrences of the values in vals in x is exactly val.
julia
concept(:exactly, x; vals, val)
-concept(:exactly)(x; vals, val)

Examples

julia
c = concept(:count)
-
-c([2, 1, 4, 3]; vals=[1, 2, 3, 4], op=≥, val=2)
-c([1, 2, 3, 4]; vals=[1, 2], op==, val=2)
-c([2, 1, 4, 3]; vals=[1, 2], op=≤, val=1)

source


# Constraints.xcsp_cumulativeMethod.
julia
xcsp_cumulative(; origins, lengths, heights, condition)

Return true if the cumulative constraint is satisfied, false otherwise. The cumulative constraint is a global constraint used in constraint programming that is often used in scheduling problems. It ensures that for any point in time, the sum of the "heights" of tasks that are ongoing at that time does not exceed a certain limit.

Arguments

  • origins::AbstractVector: list of origins of the tasks.

  • lengths::AbstractVector: list of lengths of the tasks.

  • heights::AbstractVector: list of heights of the tasks.

  • condition::Tuple: condition to check.

Variants

  • :cumulative: The cumulative constraint is a global constraint used in constraint programming that is often used in scheduling problems. It ensures that for any point in time, the sum of the "heights" of tasks that are ongoing at that time does not exceed a certain limit.
julia
concept(:cumulative, x; pair_vars, op, val)
-concept(:cumulative)(x; pair_vars, op, val)

Examples

julia
c = concept(:cumulative)
-
-c([1, 2, 3, 4, 5]; val = 1)
-c([1, 2, 2, 4, 5]; val = 1)
-c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op =, val = 5)
-c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5)

source


# Constraints.xcsp_elementMethod.
julia
xcsp_element(; list, index, condition)

Return true if the element constraint is satisfied, false otherwise. The element constraint is a global constraint used in constraint programming that specifies that the value of a variable should be equal to the value of another variable indexed by a third variable.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

  • index::Int: index of the value to check.

  • condition::Tuple: condition to check.

Variants

  • :element: The element constraint is a global constraint used in constraint programming that specifies that the value of a variable should be equal to the value of another variable indexed by a third variable.
julia
concept(:element, x; id=nothing, op===, val=nothing)
-concept(:element)(x; id=nothing, op===, val=nothing)

Examples

julia
c = concept(:element)
-
-c([1, 2, 3, 4, 5]; id=1, val=1)
-c([1, 2, 3, 4, 5]; id=1, val=2)
-c([1, 2, 3, 4, 2])
-c([1, 2, 3, 4, 1])

source


# Constraints.xcsp_extensionMethod.
julia
xcsp_extension(; list, supports=nothing, conflicts=nothing)

Global constraint enforcing that the tuple x matches a configuration within the supports set pair_vars[1] or does not match any configuration within the conflicts set pair_vars[2]. It embodies the logic: x ∈ pair_vars[1] || x ∉ pair_vars[2], providing a comprehensive way to define valid (supported) and invalid (conflicted) tuples for constraint satisfaction problems. This constraint is versatile, allowing for the explicit delineation of both acceptable and unacceptable configurations.

Arguments

  • list::Vector{Int}: A list of variables

  • supports::Vector{Vector{Int}}: A set of supported tuples. Default to nothing.

  • conflicts::Vector{Vector{Int}}: A set of conflicted tuples. Default to nothing.

Variants

  • :extension: Global constraint enforcing that the tuple x matches a configuration within the supports set pair_vars[1] or does not match any configuration within the conflicts set pair_vars[2]. It embodies the logic: x ∈ pair_vars[1] || x ∉ pair_vars[2], providing a comprehensive way to define valid (supported) and invalid (conflicted) tuples for constraint satisfaction problems. This constraint is versatile, allowing for the explicit delineation of both acceptable and unacceptable configurations.
julia
concept(:extension, x; pair_vars)
-concept(:extension)(x; pair_vars)
  • :supports: Global constraint ensuring that the tuple x matches a configuration listed within the support set pair_vars. This constraint is derived from the extension model, specifying that x must be one of the explicitly defined supported configurations: x ∈ pair_vars. It is utilized to directly declare the tuples that are valid and should be included in the solution space.
julia
concept(:supports, x; pair_vars)
-concept(:supports)(x; pair_vars)
  • :conflicts: Global constraint ensuring that the tuple x does not match any configuration listed within the conflict set pair_vars. This constraint, originating from the extension model, stipulates that x must avoid all configurations defined as conflicts: x ∉ pair_vars. It is useful for specifying tuples that are explicitly forbidden and should be excluded from the solution space.
julia
concept(:conflicts, x; pair_vars)
-concept(:conflicts)(x; pair_vars)

Examples

julia
c = concept(:extension)
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 3, 4, 5]])
-c([1, 2, 3, 4, 5]; pair_vars=([[1, 2, 3, 4, 5]], [[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]]))
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]])
-
-c = concept(:supports)
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 3, 4, 5]])
-
-c = concept(:conflicts)
-c([1, 2, 3, 4, 5]; pair_vars=[[1, 2, 1, 4, 5], [1, 2, 3, 5, 5]])

source


# Constraints.xcsp_instantiationMethod.
julia
xcsp_instantiation(; list, values)

Return true if the instantiation constraint is satisfied, false otherwise. The instantiation constraint is a global constraint used in constraint programming that ensures that a list of variables takes on a specific set of values in a specific order.

Arguments

  • list::AbstractVector: list of values to check.

  • values::AbstractVector: list of values to check against.

Variants

  • :instantiation: The instantiation constraint is a global constraint used in constraint programming that ensures that a list of variables takes on a specific set of values in a specific order.
julia
concept(:instantiation, x; pair_vars)
-concept(:instantiation)(x; pair_vars)

Examples

julia
c = concept(:instantiation)
-
-c([1, 2, 3, 4, 5]; pair_vars=[1, 2, 3, 4, 5])
-c([1, 2, 3, 4, 5]; pair_vars=[1, 2, 3, 4, 6])

source


# Constraints.xcsp_intensionMethod.
julia
xcsp_intension(list, predicate)

An intensional constraint is usually defined from a predicate over list. As such it encompass any generic constraint.

Arguments

  • list::Vector{Int}: A list of variables

  • predicate::Function: A predicate over list

Variants

  • :dist_different: A constraint ensuring that the distances between marks on the ruler are unique. Specifically, it checks that the distance between x[1] and x[2], and the distance between x[3] and x[4], are different. This constraint is fundamental in ensuring the validity of a Golomb ruler, where no two pairs of marks should have the same distance between them.
julia
concept(:dist_different, x)
-concept(:dist_different)(x)

Examples

@example
2 + 2
@example
2 + 2
@example
using Constraints # hide
-c = concept(:dist_different)
-c([1, 2, 3, 3]) && !c([1, 2, 3, 4])
@example
using Constraints # hide
-c = concept(:dist_different)
-c([1, 2, 3, 3]) && !c([1, 2, 3, 4])

source


# Constraints.xcsp_maximumMethod.
julia
xcsp_maximum(; list, condition)

Return true if the maximum constraint is satisfied, false otherwise. The maximum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the maximum value in a list of variables.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

  • condition::Tuple: condition to check.

Variants

  • :maximum: The maximum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the maximum value in a list of variables.
julia
concept(:maximum, x; op, val)
-concept(:maximum)(x; op, val)

Examples

julia
c = concept(:maximum)
-
-c([1, 2, 3, 4, 5]; op = ==, val = 5)
-c([1, 2, 3, 4, 5]; op = ==, val = 6)

source


# Constraints.xcsp_mddMethod.
julia
xcsp_mdd(; list, diagram)

Return a function that checks if the list of values list satisfies the MDD diagram.

Arguments

  • list::Vector{Int}: list of values to check.

  • diagram::MDD: MDD to check.

Variants

  • :mdd: Multi-valued Decision Diagram (MDD) constraint. The MDD constraint is a constraint that can be used to model a wide range of problems. It is a directed graph where each node is labeled with a value and each edge is labeled with a value. The constraint is satisfied if there is a path from the first node to the last node such that the sequence of edge labels is a valid sequence of the value labels.
julia
concept(:mdd, x; language)
-concept(:mdd)(x; language)

Examples

julia
c = concept(:mdd)
-
-states = [
-    Dict( # level x1
-        (:r, 0) => :n1,
-        (:r, 1) => :n2,
-        (:r, 2) => :n3,
-    ),
-    Dict( # level x2
-        (:n1, 2) => :n4,
-        (:n2, 2) => :n4,
-        (:n3, 0) => :n5,
-    ),
-    Dict( # level x3
-        (:n4, 0) => :t,
-        (:n5, 0) => :t,
-    ),
-]
-
-a = MDD(states)
-
-c([0,2,0]; language = a)
-c([1,2,0]; language = a)
-c([2,0,0]; language = a)
-c([2,1,2]; language = a)
-c([1,0,2]; language = a)
-c([0,1,2]; language = a)

source


# Constraints.xcsp_minimumMethod.
julia
xcsp_minimum(; list, condition)

Return true if the minimum constraint is satisfied, false otherwise. The minimum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the minimum value in a list of variables.

Arguments

  • list::Union{AbstractVector, Tuple}: list of values to check.

  • condition::Tuple: condition to check.

Variants

  • :minimum: The minimum constraint is a global constraint used in constraint programming that specifies that a certain condition should hold for the minimum value in a list of variables.
julia
concept(:minimum, x; op, val)
-concept(:minimum)(x; op, val)

Examples

julia
c = concept(:minimum)
-
-c([1, 2, 3, 4, 5]; op = ==, val = 1)
-c([1, 2, 3, 4, 5]; op = ==, val = 0)

source


# Constraints.xcsp_no_overlapMethod.
julia
xcsp_no_overlap(; origins, lengths, zero_ignored)

Return true if the no_overlap constraint is satisfied, false otherwise. The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts.

Arguments

  • origins::AbstractVector: list of origins of the tasks.

  • lengths::AbstractVector: list of lengths of the tasks.

  • zero_ignored::Bool: whether to ignore zero-length tasks.

Variants

  • :no_overlap: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts.
julia
concept(:no_overlap, x; pair_vars, bool)
-concept(:no_overlap)(x; pair_vars, bool)
  • :no_overlap_no_zero: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant ignores zero-length tasks.
julia
concept(:no_overlap_no_zero, x; pair_vars)
-concept(:no_overlap_no_zero)(x; pair_vars)
  • :no_overlap_with_zero: The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant includes zero-length tasks.
julia
concept(:no_overlap_with_zero, x; pair_vars)
-concept(:no_overlap_with_zero)(x; pair_vars)

Examples

julia
c = concept(:no_overlap)
-
-c([1, 2, 3, 4, 5])
-c([1, 2, 3, 4, 1])
-c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 1, 1])
-c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 3, 1])
-c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 3, 1, 1])
-c([1, 1, 1, 3, 5, 2, 7, 7, 5, 12, 8, 7]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3)
-c([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3)

source


# Constraints.xcsp_nvaluesMethod.
julia
xcsp_nvalues(list, condition, except)

Return true if the number of distinct values in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • condition: condition to satisfy.

  • except::Union{Nothing, Vector{Int}}: list of values to exclude. Default is nothing.

Variants

  • :nvalues: The nValues constraint specifies that the number of distinct values in the list of variables x is equal to a given value. The constraint is defined by the following expression: nValues(x, op, val) where x is a list of variables, op is a comparison operator, and val is an integer value.
julia
concept(:nvalues, x; op, val)
-concept(:nvalues)(x; op, val)

Examples

julia
c = concept(:nvalues)
-
-c([1, 2, 3, 4, 5]; op = ==, val = 5)
-c([1, 2, 3, 4, 5]; op = ==, val = 2)
-c([1, 2, 3, 4, 3]; op = <=, val = 5)
-c([1, 2, 3, 4, 3]; op = <=, val = 3)

source


# Constraints.xcsp_orderedMethod.
julia
xcsp_ordered(list::Vector{Int}, operator, lengths)

Return true if all the values of list are in an increasing order, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • operator: comparison operator to use.

  • lengths: list of lengths to use. Defaults to nothing.

Variants

  • :ordered: Global constraint ensuring that all the values of x are in an increasing order.
julia
concept(:ordered, x; op=≤, pair_vars=nothing)
-concept(:ordered)(x; op=≤, pair_vars=nothing)
  • :increasing: Global constraint ensuring that all the values of x are in an increasing order.
julia
concept(:increasing, x; op=≤, pair_vars=nothing)
-concept(:increasing)(x; op=≤, pair_vars=nothing)
  • :decreasing: Global constraint ensuring that all the values of x are in a decreasing order.
julia
concept(:decreasing, x; op=≥, pair_vars=nothing)
-concept(:decreasing)(x; op=≥, pair_vars=nothing)
  • :strictly_increasing: Global constraint ensuring that all the values of x are in a strictly increasing order.
julia
concept(:strictly_increasing, x; op=<, pair_vars=nothing)
-concept(:strictly_increasing)(x; op=<, pair_vars=nothing)
  • :strictly_decreasing: Global constraint ensuring that all the values of x are in a strictly decreasing order.
julia
concept(:strictly_decreasing, x; op=>, pair_vars=nothing)
-concept(:strictly_decreasing)(x; op=>, pair_vars=nothing)

Examples

julia
c = concept(:ordered)
-
-c([1, 2, 3, 4, 4]; op=≤)
-c([1, 2, 3, 4, 5]; op=<)
-!c([1, 2, 3, 4, 3]; op=≤)
-!c([1, 2, 3, 4, 3]; op=<)

source


# Constraints.xcsp_regularMethod.
julia
xcsp_regular(; list, automaton)
-
-Ensures that a sequence `x` (interpreted as a word) is accepted by the regular language represented by a given automaton. This constraint verifies the compliance of `x` with the language rules encoded within the `automaton` parameter, which must be an instance of `<:AbstractAutomaton`.

Arguments

  • list::Vector{Int}: A list of variables

  • automaton<:AbstractAutomaton: An automaton representing the regular language

Variants

  • :regular: Ensures that a sequence x (interpreted as a word) is accepted by the regular language represented by a given automaton. This constraint verifies the compliance of x with the language rules encoded within the automaton parameter, which must be an instance of <:AbstractAutomaton.
julia
concept(:regular, x; language)
-concept(:regular)(x; language)

Examples

julia
c = concept(:regular)
-
-states = Dict(
-    (:a, 0) => :a,
-    (:a, 1) => :b,
-    (:b, 1) => :c,
-    (:c, 0) => :d,
-    (:d, 0) => :d,
-    (:d, 1) => :e,
-    (:e, 0) => :e,
-)
-start = :a
-finish = :e
-
-a = Automaton(states, start, finish)
-
-c([0,0,1,1,0,0,1,0,0]; language = a)
-c([1,1,1,0,1]; language = a)

source


# Constraints.xcsp_sumMethod.
julia
xcsp_sum(list, coeffs, condition)

Return true if the sum of the variables in list satisfies the given condition, false otherwise.

Arguments

  • list::Vector{Int}: list of values to check.

  • coeffs::Vector{Int}: list of coefficients to use.

  • condition: condition to satisfy.

Variants

  • :sum: Global constraint ensuring that the sum of the variables in x satisfies a given condition.
julia
concept(:sum, x; op===, pair_vars=ones(x), val)
-concept(:sum)(x; op===, pair_vars=ones(x), val)

Examples

julia
c = concept(:sum)
-
-c([1, 2, 3, 4, 5]; op===, val=15)
-c([1, 2, 3, 4, 5]; op===, val=2)
-c([1, 2, 3, 4, 3]; op=≤, val=15)
-c([1, 2, 3, 4, 3]; op=≤, val=3)

source


# Constraints.@usualMacro.
julia
usual(ex::Expr)

This macro is used to define a new constraint or update an existing one in the USUAL_CONSTRAINTS dictionary. It takes an expression ex as input, which represents the definition of a constraint.

Here's a step-by-step explanation of what the macro does:

  1. It first extracts the symbol of the concept from the input expression. This symbol is expected to be the first argument of the first argument of the expression. For example, if the expression is @usual all_different(x; y=1), the symbol would be :all_different.

  2. It then calls the shrink_concept function on the symbol to get a simplified version of the concept symbol.

  3. It initializes a dictionary defaults to store whether each keyword argument of the concept has a default value or not.

  4. It checks if the expression has more than two arguments. If it does, it means that there are keyword arguments present. It then loops over these keyword arguments. If a keyword argument is a symbol, it means it doesn't have a default value, so it adds an entry to the defaults dictionary with the keyword argument as the key and false as the value. If a keyword argument is not a symbol, it means it has a default value, so it adds an entry to the defaults dictionary with the keyword argument as the key and true as the value.

  5. It calls the make_error function on the simplified concept symbol to generate an error function for the constraint.

  6. It evaluates the input expression to get the concept function.

  7. It checks if the USUAL_CONSTRAINTS dictionary already contains an entry for the simplified concept symbol. If it does, it adds the defaults dictionary to the parameters of the existing constraint. If it doesn't, it creates a new constraint with the concept function, a description, the error function, and the defaults dictionary as the parameters, and adds it to the USUAL_CONSTRAINTS dictionary.

This macro is used to make it easier to define and update constraints in a consistent and possibly automated way.

Arguments

  • ex::Expr: expression to parse.

Example

julia
@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals)

source


# CompositionalNetworks.CompositionType.
julia
struct Composition{F<:Function}

Store the all the information of a composition learned by an ICN.

source


# CompositionalNetworks.CompositionMethod.
julia
Composition(f::F, symbols) where {F<:Function}

Construct a Composition.

source


# CompositionalNetworks.ICNType.
julia
ICN(; nvars, dom_size, param, transformation, arithmetic, aggregation, comparison)

Construct an Interpretable Compositional Network, with the following arguments:

  • nvars: number of variable in the constraint

  • dom_size: maximum domain size of any variable in the constraint

  • param: optional parameter (default to nothing)

  • transformation: a transformation layer (optional)

  • arithmetic: a arithmetic layer (optional)

  • aggregation: a aggregation layer (optional)

  • comparison: a comparison layer (optional)

source


# CompositionalNetworks.LayerType.
julia
Layer

A structure to store a LittleDict of operations that can be selected during the learning phase of an ICN. If the layer is exclusive, only one operation can be selected at a time.

source


# Base.lengthMethod.
julia
length(layer)

Return the number of operations in a layer.

source


# Base.lengthMethod.
julia
Base.length(icn)

Return the total number of operations of an ICN.

source


# CompositionalNetworks._composeMethod.
julia
_compose(icn)

Internal function called by compose and show_composition.

source


# CompositionalNetworks.ag_count_positiveMethod.
julia
ag_count_positive(x)

Count the number of strictly positive elements of x.

source


# CompositionalNetworks.ag_sumMethod.
julia
ag_sum(x)

Aggregate through + a vector into a single scalar.

source


# CompositionalNetworks.aggregation_layerMethod.
julia
aggregation_layer()

Generate the layer of aggregations of the ICN. The operations are mutually exclusive, that is only one will be selected.

source


# CompositionalNetworks.ar_prodMethod.
julia
ar_prod(x)

Reduce k = length(x) vectors through product to a single vector.

source


# CompositionalNetworks.ar_sumMethod.
julia
ar_sum(x)

Reduce k = length(x) vectors through sum to a single vector.

source


# CompositionalNetworks.arithmetic_layerMethod.
julia
arithmetic_layer()

Generate the layer of arithmetic operations of the ICN. The operations are mutually exclusive, that is only one will be selected.

source


# CompositionalNetworks.as_bitvectorFunction.
julia
as_bitvector(n::Int, max_n::Int = n)

Convert an Int to a BitVector of minimal size (relatively to max_n).

source


# CompositionalNetworks.as_intMethod.
julia
as_int(v::AbstractVector)

Convert a BitVector into an Int.

source


# CompositionalNetworks.co_abs_diff_val_paramMethod.
julia
co_abs_diff_val_param(x; param)

Return the absolute difference between x and param.

source


# CompositionalNetworks.co_abs_diff_val_varsMethod.
julia
co_abs_diff_val_vars(x; nvars)

Return the absolute difference between x and the number of variables nvars.

source


# CompositionalNetworks.co_euclideanMethod.
julia
co_euclidean(x; dom_size)

Compute an euclidean norm with domain size dom_size of a scalar.

source


# CompositionalNetworks.co_euclidean_paramMethod.
julia
co_euclidean_param(x; param, dom_size)

Compute an euclidean norm with domain size dom_size, weighted by param, of a scalar.

source


# CompositionalNetworks.co_identityMethod.
julia
co_identity(x)

Identity function. Already defined in Julia as identity, specialized for scalars in the comparison layer.

source


# CompositionalNetworks.co_param_minus_valMethod.
julia
co_param_minus_val(x; param)

Return the difference param - x if positive, 0.0 otherwise.

source


# CompositionalNetworks.co_val_minus_paramMethod.
julia
co_val_minus_param(x; param)

Return the difference x - param if positive, 0.0 otherwise.

source


# CompositionalNetworks.co_val_minus_varsMethod.
julia
co_val_minus_vars(x; nvars)

Return the difference x - nvars if positive, 0.0 otherwise, where nvars denotes the numbers of variables.

source


# CompositionalNetworks.co_vars_minus_valMethod.
julia
co_vars_minus_val(x; nvars)

Return the difference nvars - x if positive, 0.0 otherwise, where nvars denotes the numbers of variables.

source


# CompositionalNetworks.codeFunction.
julia
code(c::Composition, lang=:maths; name="composition")

Access the code of a composition c in a given language lang. The name of the generated method is optional.

source


# CompositionalNetworks.comparison_layerFunction.
julia
comparison_layer(param = false)

Generate the layer of transformations functions of the ICN. Iff param value is set, also includes all the parametric comparison with that value. The operations are mutually exclusive, that is only one will be selected.

source


# CompositionalNetworks.composeFunction.
julia
compose(icn, weights=nothing)

Return a function composed by some of the operations of a given ICN. Can be applied to any vector of variables. If weights are given, will assign to icn.

source


# CompositionalNetworks.compose_to_file!Method.
julia
compose_to_file!(concept, name, path; domains, param = nothing, language = :Julia, search = :complete, global_iter = 10, local_iter = 100, metric = hamming, popSize = 200)

Explore, learn and compose a function and write it to a file.

Arguments:

  • concept: the concept to learn

  • name: the name to give to the constraint

  • path: path of the output file

Keywords arguments:

  • domains: domains that defines the search space

  • param: an optional parameter of the constraint

  • language: the language to export to, default to :julia

  • search: either :partial or :complete search

  • global_iter: number of learning iteration

  • local_iter: number of generation in the genetic algorithm

  • metric: the metric to measure the distance between a configuration and known solutions

  • popSize: size of the population in the genetic algorithm

source


# CompositionalNetworks.compositionMethod.
julia
composition(c::Composition)

Access the actual method of an ICN composition c.

source


# CompositionalNetworks.composition_to_file!Function.
julia
composition_to_file!(c::Composition, path, name, language=:Julia)

Write the composition code in a given language into a file at path.

source


# CompositionalNetworks.excluMethod.
julia
exclu(layer)

Return true if the layer has mutually exclusive operations.

source


# CompositionalNetworks.explore_learn_composeMethod.
julia
explore_learn_compose(concept; domains, param = nothing, search = :complete, global_iter = 10, local_iter = 100, metric = hamming, popSize = 200, action = :composition)

Explore a search space, learn a composition from an ICN, and compose an error function.

Arguments:

  • concept: the concept of the targeted constraint

  • domains: domains of the variables that define the training space

  • param: an optional parameter of the constraint

  • search: either flexible,:partial or :complete search. Flexible search will use search_limit and solutions_limit to determine if the search space needs to be partially or completely explored

  • global_iter: number of learning iteration

  • local_iter: number of generation in the genetic algorithm

  • metric: the metric to measure the distance between a configuration and known solutions

  • popSize: size of the population in the genetic algorithm

  • action: either :symbols to have a description of the composition or :composition to have the composed function itself

source


# CompositionalNetworks.functionsMethod.
julia
functions(layer)

Access the operations of a layer. The container is ordered.

source


# CompositionalNetworks.generateMethod.
julia
generate(c::Composition, name, lang)

Generates the code of c in a specific language lang.

source


# CompositionalNetworks.generate_exclusive_operationMethod.
julia
generate_exclusive_operation(max_op_number)

Generates the operations (weigths) of a layer with exclusive operations.

source


# CompositionalNetworks.generate_inclusive_operationsMethod.
julia
generate_inclusive_operations(predicate, bits)
-generate_exclusive_operation(max_op_number)

Generates the operations (weights) of a layer with inclusive/exclusive operations.

source


# CompositionalNetworks.generate_weightsMethod.
julia
generate_weights(layers)
-generate_weights(icn)

Generate the weights of a collection of layers or of an ICN.

source


# CompositionalNetworks.hammingMethod.
julia
hamming(x, X)

Compute the hamming distance of x over a collection of solutions X, i.e. the minimal number of variables to switch in xto reach a solution.

source


# CompositionalNetworks.is_viableMethod.
julia
is_viable(layer, w)
-is_viable(icn)
-is_viable(icn, w)

Assert if a pair of layer/icn and weights compose a viable pattern. If no weights are given with an icn, it will check the current internal value.

source


# CompositionalNetworks.layersMethod.
julia
layers(icn)

Return the ordered layers of an ICN.

source


# CompositionalNetworks.lazyMethod.
julia
lazy(funcs::Function...)

Generate methods extended to a vector instead of one of its components. A function f should have the following signature: f(i::Int, x::V).

source


# CompositionalNetworks.lazy_paramMethod.
julia
lazy_param(funcs::Function...)

Generate methods extended to a vector instead of one of its components. A function f should have the following signature: f(i::Int, x::V; param).

source


# CompositionalNetworks.learn_composeMethod.
julia
learn_compose(;
-    nvars, dom_size, param=nothing, icn=ICN(nvars, dom_size, param),
-    X, X_sols, global_iter=100, local_iter=100, metric=hamming, popSize=200
-)

Create an ICN, optimize it, and return its composition.

source


# CompositionalNetworks.make_transformationsMethod.
julia
make_transformations(param::Symbol)

Generates a dictionary of transformation functions based on the specified parameterization. This function facilitates the creation of parametric layers for constraint transformations, allowing for flexible and dynamic constraint manipulation according to the needs of different constraint programming models.

Parameters

  • param::Symbol: Specifies the type of transformations to generate. It can be :none for basic transformations that do not depend on external parameters, or :val for transformations that operate with respect to a specific value parameter.

Returns

  • LittleDict{Symbol, Function}: A dictionary mapping transformation names (Symbol) to their corresponding functions (Function). The functions encapsulate various types of transformations, such as counting, comparison, and contiguous value processing.

Transformation Types

  • When param is :none, the following transformations are available:

    • :identity: No transformation is applied.

    • :count_eq, :count_eq_left, :count_eq_right: Count equalities under different conditions.

    • :count_greater, :count_lesser: Count values greater or lesser than a threshold.

    • :count_g_left, :count_l_left, :count_g_right, :count_l_right: Count values with greater or lesser comparisons from different directions.

    • :contiguous_vals_minus, :contiguous_vals_minus_rev: Process contiguous values with subtraction in normal and reverse order.

  • When param is :val, the transformations relate to operations involving a parameter value:

    • :count_eq_param, :count_l_param, :count_g_param: Count equalities or comparisons against a parameter value.

    • :count_bounding_param: Count values bounding a parameter value.

    • :val_minus_param, :param_minus_val: Subtract a parameter value from values or vice versa.

The function delegates to a version that uses Val(param) for dispatch, ensuring compile-time selection of the appropriate transformation set.

Examples

julia
# Get basic transformations
-basic_transforms = make_transformations(:none)
-
-# Apply an identity transformation
-identity_result = basic_transforms[:identity](data)
-
-# Get value-based transformations
-val_transforms = make_transformations(:val)
-
-# Apply a count equal to parameter transformation
-count_eq_param_result = val_transforms[:count_eq_param](data, param)

source


# CompositionalNetworks.manhattanMethod.
julia
manhattan(x, X)

source


# CompositionalNetworks.map_tr!Method.
julia
map_tr!(f, x, X, param)

Return an anonymous function that applies f to all elements of x and store the result in X, with a parameter param (which is set to nothing for function with no parameter).

source


# CompositionalNetworks.minkowskiMethod.
julia
minkowski(x, X, p)

source


# CompositionalNetworks.nbitsMethod.
julia
nbits(icn)

Return the expected number of bits of a viable weight of an ICN.

source


# CompositionalNetworks.nbits_excluMethod.
julia
nbits_exclu(layer)

Convert the length of an exclusive layer into a number of bits.

source


# CompositionalNetworks.reduce_symbolsFunction.
julia
reduce_symbols(symbols, sep)

Produce a formatted string that separates the symbols by sep. Used internally for show_composition.

source


# CompositionalNetworks.regularizationMethod.
julia
regularization(icn)

Return the regularization value of an ICN weights, which is proportional to the normalized number of operations selected in the icn layers.

source


# CompositionalNetworks.selected_sizeMethod.
julia
selected_size(layer, layer_weights)

Return the number of operations selected by layer_weights in layer.

source


# CompositionalNetworks.show_layerMethod.
julia
show_layer(layer)

Return a string that contains the elements in a layer.

source


# CompositionalNetworks.show_layersMethod.
julia
show_layers(icn)

Return a formatted string with each layers in the icn.

source


# CompositionalNetworks.symbolMethod.
julia
symbol(layer, i)

Return the i-th symbols of the operations in a given layer.

source


# CompositionalNetworks.symbolsMethod.
julia
symbols(c::Composition)

Output the composition as a layered collection of Symbols.

source


# CompositionalNetworks.tr_contiguous_vals_minusMethod.
julia
tr_contiguous_vals_minus(i, x)
-tr_contiguous_vals_minus(x)
-tr_contiguous_vals_minus(x, X::AbstractVector)

Return the difference x[i] - x[i + 1] if positive, 0.0 otherwise. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_contiguous_vals_minus_revMethod.
julia
tr_contiguous_vals_minus_rev(i, x)
-tr_contiguous_vals_minus_rev(x)
-tr_contiguous_vals_minus_rev(x, X::AbstractVector)

Return the difference x[i + 1] - x[i] if positive, 0.0 otherwise. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_bounding_paramMethod.
julia
tr_count_bounding_param(i, x; param)
-tr_count_bounding_param(x; param)
-tr_count_bounding_param(x, X::AbstractVector; param)

Count the number of elements bounded (not strictly) by x[i] and x[i] + param. An extended method to vector with sig (x, param) is generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eqMethod.
julia
tr_count_eq(i, x)
-tr_count_eq(x)
-tr_count_eq(x, X::AbstractVector)

Count the number of elements equal to x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eq_leftMethod.
julia
tr_count_eq_left(i, x)
-tr_count_eq_left(x)
-tr_count_eq_left(x, X::AbstractVector)

Count the number of elements to the left of and equal to x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eq_paramMethod.
julia
tr_count_eq_param(i, x; param)
-tr_count_eq_param(x; param)
-tr_count_eq_param(x, X::AbstractVector; param)

Count the number of elements equal to x[i] + param. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eq_rightMethod.
julia
tr_count_eq_right(i, x)
-tr_count_eq_right(x)
-tr_count_eq_right(x, X::AbstractVector)

Count the number of elements to the right of and equal to x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_g_leftMethod.
julia
tr_count_g_left(i, x)
-tr_count_g_left(x)
-tr_count_g_left(x, X::AbstractVector)

Count the number of elements to the left of and greater than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_g_paramMethod.
julia
tr_count_g_param(i, x; param)
-tr_count_g_param(x; param)
-tr_count_g_param(x, X::AbstractVector; param)

Count the number of elements greater than x[i] + param. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_g_rightMethod.
julia
tr_count_g_right(i, x)
-tr_count_g_right(x)
-tr_count_g_right(x, X::AbstractVector)

Count the number of elements to the right of and greater than x[i]. Extended method to vector with sig (x) are generated.

source


# CompositionalNetworks.tr_count_greaterMethod.
julia
tr_count_greater(i, x)
-tr_count_greater(x)
-tr_count_greater(x, X::AbstractVector)

Count the number of elements greater than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_l_leftMethod.
julia
tr_count_l_left(i, x)
-tr_count_l_left(x)
-tr_count_l_left(x, X::AbstractVector)

Count the number of elements to the left of and lesser than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_l_paramMethod.
julia
tr_count_l_param(i, x; param)
-tr_count_l_param(x; param)
-tr_count_l_param(x, X::AbstractVector; param)

Count the number of elements lesser than x[i] + param. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_l_rightMethod.
julia
tr_count_l_right(i, x)
-tr_count_l_right(x)
-tr_count_l_right(x, X::AbstractVector)

Count the number of elements to the right of and lesser than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_lesserMethod.
julia
tr_count_lesser(i, x)
-tr_count_lesser(x)
-tr_count_lesser(x, X::AbstractVector)

Count the number of elements lesser than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_identityMethod.
julia
tr_identity(i, x)
-tr_identity(x)
-tr_identity(x, X::AbstractVector)

Identity function. Already defined in Julia as identity, specialized for vectors. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_in_unrolled_expansion_##225Method.
julia
tr_in(tr, X, x, param)

Application of an operation from the transformation layer. Used to generate more efficient code for all compositions.

source


# CompositionalNetworks.tr_param_minus_valMethod.
julia
tr_param_minus_val(i, x; param)
-tr_param_minus_val(x; param)
-tr_param_minus_val(x, X::AbstractVector; param)

Return the difference param - x[i] if positive, 0.0 otherwise. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_val_minus_paramMethod.
julia
tr_val_minus_param(i, x; param)
-tr_val_minus_param(x; param)
-tr_val_minus_param(x, X::AbstractVector; param)

Return the difference x[i] - param if positive, 0.0 otherwise. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.transformation_layerFunction.
julia
transformation_layer(param = false)

Generate the layer of transformations functions of the ICN. Iff param value is true, also includes all the parametric transformations.

source


# CompositionalNetworks.weights!Method.
julia
weights!(icn, weights)

Set the weights of an ICN with a BitVector.

source


# CompositionalNetworks.weightsMethod.
julia
weights(icn)

Access the current set of weights of an ICN.

source


# CompositionalNetworks.weights_biasMethod.
julia
weights_bias(x)

A metric that bias x towards operations with a lower bit. Do not affect the main metric.

source


# QUBOConstraints.AbstractOptimizerType.
julia
AbstractOptimizer

An abstract type (interface) used to learn QUBO matrices from constraints. Only a train method is required.

source


# QUBOConstraints.QUBO_baseFunction.
julia
QUBO_base(n, weight = 1)

A basic QUBO matrix to ensure that binarized variables keep a valid encoding.

source


# QUBOConstraints.QUBO_linear_sumMethod.
julia
QUBO_linear_sum(n, σ)

One valid QUBO matrix given n variables and parameter σ for the linear sum constraint.

source


# QUBOConstraints.binarizeMethod.
julia
binarize(x[, domain]; binarization = :one_hot)

Binarize x following the binarization encoding. If x is a vector (instead of a number per say), domain is optional.

source


# QUBOConstraints.debinarizeMethod.
julia
debinarize(x[, domain]; binarization = :one_hot)

Transform a binary vector into a number or a set of number. If domain is not given, it will compute a default value based on binarization and x.

source


# QUBOConstraints.is_validFunction.
julia
is_valid(x, encoding::Symbol = :none)

Check if x has a valid format for encoding.

For instance, if encoding == :one_hot, at most one bit of x can be set to 1.

source


# QUBOConstraints.trainMethod.
julia
train(args...)

Default train method for any AbstractOptimizer.

source


- - - - \ No newline at end of file diff --git a/dev/hashmap.json b/dev/hashmap.json deleted file mode 100644 index 99f1e8c..0000000 --- a/dev/hashmap.json +++ /dev/null @@ -1 +0,0 @@ -{"constraints_comparison_constraints.md":"2Ukc8viw","constraints_connection_constraints.md":"0kSxmxNT","constraints_constraint_commons.md":"PTLdrUW2","cp_cp101.md":"CrtqNaW3","constraints_constraint_domains.md":"Cd0YH57K","constraints_constraints.md":"ijIsQmJK","constraints_counting_summing_constraints.md":"BIdrSepq","cp_advanced.md":"Dsfkdtcs","cp_applications.md":"-HdwrgYe","cp_contribution.md":"CvjPxUVA","constraints_constraint_models.md":"DjPMcFlD","cp_intro.md":"qCFhsnKE","cp_models.md":"DjhzTYet","cp_ecosystem.md":"BROmdRLS","cp_getting_started.md":"CgxLSopb","cp_opt.md":"oWksNiMs","index.md":"BcgCFTkL","learning_aggregation.md":"5RLMQ4Bd","index-old.md":"BzPVACYs","cp_tuto_xp.md":"CLy9H2hK","learning_arithmetic.md":"DW5u7RMW","learning_comparison.md":"BsnqPWC-","constraints_graph_constraints.md":"CTf_lkG3","learning_qubo_constraints.md":"DpCFckdQ","learning_qubo_encoding.md":"CDyoKOWI","learning_layers.md":"DuFC9ol_","meta_meta_strategist.md":"CuHkGJNL","learning_qubo_learning.md":"CLlNBMzd","perf_benchmark_ext.md":"CVYCQYDt","learning_transformation.md":"BtKPMNbs","constraints_elementary_constraints.md":"BbiPuUtE","constraints_intro.md":"SiDBJ4N_","perf_perf_checker.md":"C3kXwfzJ","constraints_language_constraints.md":"CE20vPnP","constraints_packing_scheduling_constraints.md":"CSsKQ9F3","learning_intro.md":"497AVcuz","learning_compositional_networks.md":"BZgNyUW3","learning_constraint_learning.md":"DAfFojnp","perf_perf_interface.md":"DaCOMv6z","solvers_intro.md":"BOddHRCt","constraints_generic_constraints.md":"WUfYZUE9","public_api.md":"ByXB8t1V","solvers_cbls.md":"BxYapv-Y","solvers_local_search_solvers.md":"BuFLqJZe","full_api.md":"BiWge5EP"} diff --git a/dev/index-old.html b/dev/index-old.html deleted file mode 100644 index a0dd0c4..0000000 --- a/dev/index-old.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Julia Constraints - - - - - - - - - - - - - -
Skip to content

JuliaConstraints

JuliaConstraints is a collection of packages that help you solve constraint programming problems in Julia. Constraint programming involves modeling problems with constraints, such as "x > 5" or "x + y = 10", and finding solutions that satisfy all of the constraints. It is a part of the JuMP ecosystem that focuses on constraint programming in Julia.

The goal of packages in JuliaConstraints are two-fold: some of them provide a generic interface, others are solvers for CP models (either purely in Julia or wrapping). They make it easy to solve constraint-satisfaction problems (CSPs) and constraint-optimisation problems (COPs) in Julia using industry-standard solvers and mixed-integer solvers.

Other packages for CP in Julia include:

Operational Research vs Constraint Programming

Operational research (OR) is a problem-solving approach that uses mathematical models, statistical analysis, and optimization techniques to help organizations make better decisions. OR is concerned with understanding and optimizing complex systems, such as supply chains, transportation networks, and manufacturing processes, to improve efficiency and reduce costs.

On the other hand, constraint programming (CP) is a programming paradigm that focuses on solving problems with constraints. Constraints are conditions that must be satisfied for a solution to be valid. CP is often used to solve combinatorial problems, such as scheduling, routing, and allocation, where the search space of possible solutions is very large.

So, while both OR and CP are concerned with solving complex problems, they approach the problem-solving process from different angles. OR typically uses mathematical models and optimization techniques to analyze and optimize existing systems, while CP focuses on finding valid solutions that satisfy a set of constraints.

Constraint-based local search (CBLS) is a type of constraint programming solver that uses a heuristic search algorithm to find solutions to problems. It starts with an initial solution and tries to improve it by making small changes that satisfy the constraints. CBLS is especially useful for large and complex problems where finding an exact solution may take too much time or be impossible.

In contrast, other constraint programming solvers use a variety of algorithms and techniques to find exact solutions to problems. These solvers try to find a solution that satisfies all of the constraints in the problem. They can be useful for smaller problems where finding an exact solution is feasible, or for problems that have a clear mathematical structure.

In summary, CBLS is a type of constraint programming solver that uses a heuristic search algorithm to find good solutions, while other constraint programming solvers use various techniques to find exact solutions to problems.

- - - - \ No newline at end of file diff --git a/dev/index.html b/dev/index.html deleted file mode 100644 index 16600fc..0000000 --- a/dev/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Julia Constraints - - - - - - - - - - - - - -
Skip to content

Julia Constraints

Model Smoothly Decide Wisely

A Toolkit for Constraint Programming

JuliaConstraints

<p style="margin-bottom:2cm"></p>

<div class="vp-doc" style="width:80%; margin:auto">

<h1>What is Julia Constraints? (chatGPTed atm)</h1>

<p>The Julia Constraints organization is dedicated to advancing Constraint Programming within the Julia ecosystem, serving as a hub for resources that facilitate the creation, understanding, and solution of constraint programming problems. Our goal is to make Constraint Programming accessible and efficient for users at all levels of expertise, by providing a comprehensive suite of tools that integrate seamlessly with JuMP.jl, a popular Julia package for mathematical optimization.</p>

<h2>Our offerings include:</h2>

<h3>Core Packages:</h3> <p>A foundation of common packages (ConstraintCommons, ConstraintDomains, Constraints, ConstraintModels) that supply essential features for constraint programming, ensuring users have the basic tools necessary for their projects.</p>

<h3>Learning and Translation Tools:</h3> <p>Advanced packages like CompositionalNetworks, QUBOConstraints, and ConstraintsTranslator bridge the gap between ease of modeling and computational efficiency. These tools learn from constraints and convert natural language problems into constraint programming solutions, requiring minimal input from the user beyond the model itself.</p>

<h3>Solvers:</h3> <p>We provide a range of solvers, from native Julia solvers (LocalSearchSolvers) to interfaces with JuMP for external CP solvers, catering to various problem-solving needs.</p>

<h3>MetaStrategist (Emerging Technology):</h3> <p>In its formative stages, MetaStrategist embodies our pioneering spirit. As a burgeoning meta-solving package, it aims to harness the strengths of CP and JuMP. Its vision is to formulate tailored strategies that consider the unique hardware and software resources at hand, offering a new horizon in problem-solving efficiency and adaptability.</p>

<h3>Performance Checker (Community Resource):</h3> <p>PerfChecker.jl transcends its role within Julia Constraints, offering its capabilities to the broader Julia package ecosystem. This indispensable tool for cross-version performance checking not only safeguards the high efficiency and reliability of our packages but also serves the wider community. By facilitating clear and simple performance evaluations, PerfChecker.jl enhances both development and maintenance, contributing to the overall health and progress of Julia's growing library of resources.</p>

<p>At Julia Constraints, our mission is to democratize Constraint Programming by providing robust, user-friendly tools that simplify the modeling process, enhance efficiency, and empower users to solve complex problems with ease.</p>

</div>

- - - - \ No newline at end of file diff --git a/dev/learning/aggregation.html b/dev/learning/aggregation.html deleted file mode 100644 index 8ecce7a..0000000 --- a/dev/learning/aggregation.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Aggregation Layer | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Aggregation Layer

Some text to describe the aggragation layer within usual ICNs.

List of aggregations

# CompositionalNetworks.ag_sumFunction.
julia
ag_sum(x)

Aggregate through + a vector into a single scalar.

source


# CompositionalNetworks.ag_count_positiveFunction.
julia
ag_count_positive(x)

Count the number of strictly positive elements of x.

source


Layer generation

# CompositionalNetworks.aggregation_layerFunction.
julia
aggregation_layer()

Generate the layer of aggregations of the ICN. The operations are mutually exclusive, that is only one will be selected.

source


- - - - \ No newline at end of file diff --git a/dev/learning/arithmetic.html b/dev/learning/arithmetic.html deleted file mode 100644 index 0d93440..0000000 --- a/dev/learning/arithmetic.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Arithmetic Layer | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Arithmetic Layer

Some text to describe the arithmetic layer within usual ICNs.

List of arithmetic operations

# CompositionalNetworks.ar_sumFunction.
julia
ar_sum(x)

Reduce k = length(x) vectors through sum to a single vector.

source


# CompositionalNetworks.ar_prodFunction.
julia
ar_prod(x)

Reduce k = length(x) vectors through product to a single vector.

source


Layer generation

# CompositionalNetworks.arithmetic_layerFunction.
julia
arithmetic_layer()

Generate the layer of arithmetic operations of the ICN. The operations are mutually exclusive, that is only one will be selected.

source


- - - - \ No newline at end of file diff --git a/dev/learning/comparison.html b/dev/learning/comparison.html deleted file mode 100644 index c7d649b..0000000 --- a/dev/learning/comparison.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Comparison Layer | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Comparison Layer

Some text to describe the comparison layer within usual ICNs.

List of comparisons

List the possible parameters and how it affects the comparison.

Non-parametric

# CompositionalNetworks.co_identityFunction.
julia
co_identity(x)

Identity function. Already defined in Julia as identity, specialized for scalars in the comparison layer.

source


Missing docstring.

Missing docstring for co_euclidian. Check Documenter's build log for details.

# CompositionalNetworks.co_abs_diff_val_varsFunction.
julia
co_abs_diff_val_vars(x; nvars)

Return the absolute difference between x and the number of variables nvars.

source


# CompositionalNetworks.co_val_minus_varsFunction.
julia
co_val_minus_vars(x; nvars)

Return the difference x - nvars if positive, 0.0 otherwise, where nvars denotes the numbers of variables.

source


# CompositionalNetworks.co_vars_minus_valFunction.
julia
co_vars_minus_val(x; nvars)

Return the difference nvars - x if positive, 0.0 otherwise, where nvars denotes the numbers of variables.

source


Param: :val

# CompositionalNetworks.co_abs_diff_val_paramFunction.
julia
co_abs_diff_val_param(x; param)

Return the absolute difference between x and param.

source


# CompositionalNetworks.co_val_minus_paramFunction.
julia
co_val_minus_param(x; param)

Return the difference x - param if positive, 0.0 otherwise.

source


# CompositionalNetworks.co_param_minus_valFunction.
julia
co_param_minus_val(x; param)

Return the difference param - x if positive, 0.0 otherwise.

source


Missing docstring.

Missing docstring for co_euclidian_param. Check Documenter's build log for details.

Layer generation

Missing docstring.

Missing docstring for make_comparisons. Check Documenter's build log for details.

# CompositionalNetworks.comparison_layerFunction.
julia
comparison_layer(param = false)

Generate the layer of transformations functions of the ICN. Iff param value is set, also includes all the parametric comparison with that value. The operations are mutually exclusive, that is only one will be selected.

source


- - - - \ No newline at end of file diff --git a/dev/learning/compositional_networks.html b/dev/learning/compositional_networks.html deleted file mode 100644 index 991bcd6..0000000 --- a/dev/learning/compositional_networks.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - CompositionalNetworks.jl | Julia Constraints - - - - - - - - - - - - - -
Skip to content

CompositionalNetworks.jl

Documentation for CompositionalNetworks.jl.

Utilities

# CompositionalNetworks.map_tr!Function.
julia
map_tr!(f, x, X, param)

Return an anonymous function that applies f to all elements of x and store the result in X, with a parameter param (which is set to nothing for function with no parameter).

source


# CompositionalNetworks.lazyFunction.
julia
lazy(funcs::Function...)

Generate methods extended to a vector instead of one of its components. A function f should have the following signature: f(i::Int, x::V).

source


# CompositionalNetworks.lazy_paramFunction.
julia
lazy_param(funcs::Function...)

Generate methods extended to a vector instead of one of its components. A function f should have the following signature: f(i::Int, x::V; param).

source


# CompositionalNetworks.as_bitvectorFunction.
julia
as_bitvector(n::Int, max_n::Int = n)

Convert an Int to a BitVector of minimal size (relatively to max_n).

source


# CompositionalNetworks.as_intFunction.
julia
as_int(v::AbstractVector)

Convert a BitVector into an Int.

source


# CompositionalNetworks.reduce_symbolsFunction.
julia
reduce_symbols(symbols, sep)

Produce a formatted string that separates the symbols by sep. Used internally for show_composition.

source


Missing docstring.

Missing docstring for CompositionalNeworks.tr_in. Check Documenter's build log for details.

Metrics

# CompositionalNetworks.hammingFunction.
julia
hamming(x, X)

Compute the hamming distance of x over a collection of solutions X, i.e. the minimal number of variables to switch in xto reach a solution.

source


# CompositionalNetworks.minkowskiFunction.
julia
minkowski(x, X, p)

source


# CompositionalNetworks.manhattanFunction.
julia
manhattan(x, X)

source


Missing docstring.

Missing docstring for weigths_bias. Check Documenter's build log for details.

- - - - \ No newline at end of file diff --git a/dev/learning/constraint_learning.html b/dev/learning/constraint_learning.html deleted file mode 100644 index 6e83abc..0000000 --- a/dev/learning/constraint_learning.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - ConstraintLearning.jl | Julia Constraints - - - - - - - - - - - - - -
Skip to content

ConstraintLearning.jl

Documentation for ConstraintLearning.jl.

# ConstraintLearning.ICNConfigType.
julia
struct ICNConfig{O <: ICNOptimizer}

A structure to hold the metric and optimizer configurations used in learning the weights of an ICN.

source


# ConstraintLearning.ICNConfigMethod.
julia
ICNConfig(; metric = :hamming, optimizer = ICNGeneticOptimizer())

Constructor for ICNConfig. Defaults to hamming metric using a genetic algorithm.

source


# ConstraintLearning.ICNGeneticOptimizerMethod.
julia
ICNGeneticOptimizer(; kargs...)

Default constructor to learn an ICN through a Genetic Algorithm. Default kargs TBW.

source


# ConstraintLearning.ICNLocalSearchOptimizerType.
julia
ICNLocalSearchOptimizer(options = LocalSearchSolvers.Options())

Default constructor to learn an ICN through a CBLS solver.

source


# ConstraintLearning.ICNOptimizerType.
julia
const ICNOptimizer = CompositionalNetworks.AbstractOptimizer

An abstract type for optmizers defined to learn ICNs.

source


# ConstraintLearning.QUBOGradientOptimizerMethod.
julia
QUBOGradientOptimizer(; kargs...)

A QUBO optimizer based on gradient descent. Defaults TBW

source


# ConstraintLearning.QUBOOptimizerType.
julia
const QUBOOptimizer = QUBOConstraints.AbstractOptimizer

An abstract type for optimizers used to learn QUBO matrices from constraints.

source


# CompositionalNetworks.optimize!Method.
julia
CompositionalNetworks.optimize!(icn, solutions, non_sltns, dom_size, metric, optimizer::ICNGeneticOptimizer; parameters...)

Extends the optimize! method to ICNGeneticOptimizer.

source


# CompositionalNetworks.optimize!Method.
julia
CompositionalNetworks.optimize!(icn, solutions, non_sltns, dom_size, metric, optimizer::ICNLocalSearchOptimizer; parameters...)

Extends the optimize! method to ICNLocalSearchOptimizer.

source


# ConstraintLearning._optimize!Method.
julia
_optimize!(icn, X, X_sols; metric = hamming, pop_size = 200)

Optimize and set the weights of an ICN with a given set of configuration X and solutions X_sols.

source


# ConstraintLearning.domain_sizeMethod.
julia
domain_size(ds::Number)

Extends the domain_size function when ds is number (for dispatch purposes).

source


# ConstraintLearning.generate_populationMethod.
julia
generate_population(icn, pop_size

Generate a pôpulation of weights (individuals) for the genetic algorithm weighting icn.

source


# ConstraintLearning.icnMethod.
julia
icn(X,X̅; kargs..., parameters...)

TBW

source


# ConstraintLearning.lossMethod.
julia
loss(x, y, Q)

Loss of the prediction given by Q, a training set y, and a given configuration x.

source


# ConstraintLearning.make_dfMethod.
julia
make_df(X, Q, penalty, binarization, domains)

DataFrame arrangement to output some basic evaluation of a matrix Q.

source


# ConstraintLearning.make_set_penaltyMethod.
julia
make_set_penalty(X, X̅, args...; kargs)

Return a penalty function when the training set is already split into a pair of solutions X and non solutions .

source


# ConstraintLearning.make_training_setsMethod.
julia
make_training_sets(X, penalty, args...)

Return a pair of solutions and non solutions sets based on X and penalty.

source


# ConstraintLearning.mutually_exclusiveMethod.
julia
mutually_exclusive(layer, w)

Constraint ensuring that w encode exclusive operations in layer.

source


# ConstraintLearning.no_empty_layerMethod.
julia
no_empty_layer(x; X = nothing)

Constraint ensuring that at least one operation is selected.

source


# ConstraintLearning.optimize!Method.
julia
optimize!(icn, X, X_sols, global_iter, local_iter; metric=hamming, popSize=100)

Optimize and set the weights of an ICN with a given set of configuration X and solutions X_sols. The best weights among global_iter will be set.

source


# ConstraintLearning.parameter_specific_operationsMethod.
julia
parameter_specific_operations(x; X = nothing)

Constraint ensuring that at least one operation related to parameters is selected if the error function to be learned is parametric.

source


# ConstraintLearning.predictMethod.
julia
predict(x, Q)

Return the predictions given by Q for a given configuration x.

source


# ConstraintLearning.preliminariesMethod.
julia
preliminaries(args)

Preliminaries to the training process in a QUBOGradientOptimizer run.

source


# ConstraintLearning.quboFunction.
julia
qubo(X,X̅; kargs..., parameters...)

TBW

source


# ConstraintLearning.sub_eltypeMethod.
julia
sub_eltype(X)

Return the element type of of the first element of a collection.

source


# ConstraintLearning.train!Method.
julia
train!(Q, X, penalty, η, precision, X_test, oversampling, binarization, domains)

Training inner method.

source


# ConstraintLearning.trainMethod.
julia
train(X, penalty[, d]; optimizer = QUBOGradientOptimizer(), X_test = X)

Learn a QUBO matrix on training set X for a constraint defined by penalty with optional domain information d. By default, it uses a QUBOGradientOptimizer and X as a testing set.

source


# ConstraintLearning.δMethod.
julia
δ(X[, Y]; discrete = true)

Compute the extrema over a collection X``or a pair of collection(X, Y)`.

source


- - - - \ No newline at end of file diff --git a/dev/learning/intro.html b/dev/learning/intro.html deleted file mode 100644 index 4d1f38f..0000000 --- a/dev/learning/intro.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Learning about Constraints | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Learning about Constraints

About learning constraints related matters.

- - - - \ No newline at end of file diff --git a/dev/learning/layers.html b/dev/learning/layers.html deleted file mode 100644 index 18a75af..0000000 --- a/dev/learning/layers.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - A layer structure for any ICN | Julia Constraints - - - - - - - - - - - - - -
Skip to content

A layer structure for any ICN

The layer.jl file defines a Layer structure and several associated functions for manipulating and interacting with this structure in the context of an Interpretable Compositional Network (ICN).

The Layer structure is used to store a LittleDict of operations that can be selected during the learning phase of an ICN. Each layer can be exclusive, meaning only one operation can be selected at a time. This is particularly useful in the context of ICNs, which are used to learn alternative expressions for highly combinatorial functions, such as those found in Constraint-based Local Search solvers.

# CompositionalNetworks.LayerType.
julia
Layer

A structure to store a LittleDict of operations that can be selected during the learning phase of an ICN. If the layer is exclusive, only one operation can be selected at a time.

source


# CompositionalNetworks.functionsFunction.
julia
functions(layer)

Access the operations of a layer. The container is ordered.

source


# Base.lengthMethod.
julia
length(layer)

Return the number of operations in a layer.

source


# CompositionalNetworks.excluFunction.
julia
exclu(layer)

Return true if the layer has mutually exclusive operations.

source


# CompositionalNetworks.symbolFunction.
julia
symbol(layer, i)

Return the i-th symbols of the operations in a given layer.

source


# CompositionalNetworks.nbits_excluFunction.
julia
nbits_exclu(layer)

Convert the length of an exclusive layer into a number of bits.

source


# CompositionalNetworks.show_layerFunction.
julia
show_layer(layer)

Return a string that contains the elements in a layer.

source


# CompositionalNetworks.selected_sizeFunction.
julia
selected_size(layer, layer_weights)

Return the number of operations selected by layer_weights in layer.

source


# CompositionalNetworks.is_viableFunction.
julia
is_viable(layer, w)
-is_viable(icn)
-is_viable(icn, w)

Assert if a pair of layer/icn and weights compose a viable pattern. If no weights are given with an icn, it will check the current internal value.

source


# CompositionalNetworks.generate_inclusive_operationsFunction.
julia
generate_inclusive_operations(predicate, bits)
-generate_exclusive_operation(max_op_number)

Generates the operations (weights) of a layer with inclusive/exclusive operations.

source


# CompositionalNetworks.generate_exclusive_operationFunction.
julia
generate_exclusive_operation(max_op_number)

Generates the operations (weigths) of a layer with exclusive operations.

source


Missing docstring.

Missing docstring for generate_weigths. Check Documenter's build log for details.

- - - - \ No newline at end of file diff --git a/dev/learning/qubo_constraints.html b/dev/learning/qubo_constraints.html deleted file mode 100644 index b59e40d..0000000 --- a/dev/learning/qubo_constraints.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Introduction to QUBOConstraints.jl | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Introduction to QUBOConstraints.jl

Introduction to QUBOConstraints.jl.

Basic features

# QUBOConstraints.QUBO_baseFunction.
julia
QUBO_base(n, weight = 1)

A basic QUBO matrix to ensure that binarized variables keep a valid encoding.

source


# QUBOConstraints.QUBO_linear_sumFunction.
julia
QUBO_linear_sum(n, σ)

One valid QUBO matrix given n variables and parameter σ for the linear sum constraint.

source


- - - - \ No newline at end of file diff --git a/dev/learning/qubo_encoding.html b/dev/learning/qubo_encoding.html deleted file mode 100644 index 57d5254..0000000 --- a/dev/learning/qubo_encoding.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Encoding for QUBO programs | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Encoding for QUBO programs

# QUBOConstraints.is_validFunction.
julia
is_valid(x, encoding::Symbol = :none)

Check if x has a valid format for encoding.

For instance, if encoding == :one_hot, at most one bit of x can be set to 1.

source


# QUBOConstraints.binarizeFunction.
julia
binarize(x[, domain]; binarization = :one_hot)

Binarize x following the binarization encoding. If x is a vector (instead of a number per say), domain is optional.

source


# QUBOConstraints.debinarizeFunction.
julia
debinarize(x[, domain]; binarization = :one_hot)

Transform a binary vector into a number or a set of number. If domain is not given, it will compute a default value based on binarization and x.

source


- - - - \ No newline at end of file diff --git a/dev/learning/qubo_learning.html b/dev/learning/qubo_learning.html deleted file mode 100644 index d7b9ab6..0000000 --- a/dev/learning/qubo_learning.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - Learning QUBO matrices | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Learning QUBO matrices

Interface

# QUBOConstraints.AbstractOptimizerType.
julia
AbstractOptimizer

An abstract type (interface) used to learn QUBO matrices from constraints. Only a train method is required.

source


# QUBOConstraints.trainFunction.
julia
train(args...)

Default train method for any AbstractOptimizer.

source


Examples with various optimizers

Gradient Descent

julia
struct GradientDescentOptimizer <: QUBOConstraints.AbstractOptimizer
-    binarization::Symbol
-    η::Float64
-    precision::Int
-    oversampling::Bool
-end
-
-function GradientDescentOptimizer(;
-    binarization = :one_hot,
-    η = .001,
-    precision = 5,
-    oversampling = false,
-)
-    return GradientDescentOptimizer(binarization, η, precision, oversampling)
-end
-
-
-predict(x, Q) = transpose(x) * Q * x
-
-loss(x, y, Q) = (predict(x, Q) .-y).^2
-
-function make_df(X, Q, penalty, binarization, domains)
-    df = DataFrame()
-    for (i,x) in enumerate(X)
-        if i == 1
-            df = DataFrame(transpose(x), :auto)
-        else
-            push!(df, transpose(x))
-        end
-    end
-
-    dim = length(df[1,:])
-
-    if binarization == :none
-        df[!,:penalty] = map(r -> penalty(Vector(r)), eachrow(df))
-        df[!,:predict] = map(r -> predict(Vector(r), Q), eachrow(df[:, 1:dim]))
-    else
-        df[!,:penalty] = map(
-            r -> penalty(binarize(Vector(r), domains; binarization)),
-            eachrow(df)
-        )
-        df[!,:predict] = map(
-            r -> predict(binarize(Vector(r), domains; binarization), Q),
-            eachrow(df[:, 1:dim])
-        )
-    end
-
-    min_false = minimum(
-        filter(:penalty => >(minimum(df[:,:penalty])), df)[:,:predict];
-        init = typemax(Int)
-    )
-    df[!,:shifted] = df[:,:predict] .- min_false
-    df[!,:accurate] = df[:, :penalty] .* df[:,:shifted] .≥ 0.
-
-    return df
-end
-
-function preliminaries(X, domains, binarization)
-    if binarization==:none
-        n = length(first(X))
-        return X, zeros(n,n)
-    else
-        Y = map(x -> collect(binarize(x, domains; binarization)), X)
-        n = length(first(Y))
-        return Y, zeros(n,n)
-    end
-end
-
-function preliminaries(X, _)
-    n = length(first(X))
-    return X, zeros(n,n)
-end
-
-function train!(Q, X, penalty, η, precision, X_test, oversampling, binarization, domains)
-    θ = params(Q)
-    try
-        penalty(first(X))
-    catch e
-        if isa(e, UndefKeywordError)
-            penalty = (x; dom_size = δ_extrema(Iterators.flatten(X)))-> penalty(x; dom_size)
-        else
-            throw(e)
-        end
-    end
-    for x in (oversampling ? oversample(X, penalty) : X)
-        grads = gradient(() -> loss(x, penalty(x), Q), θ)
-        Q .-= η * grads[Q]
-    end
-
-    Q[:,:] = round.(precision*Q)
-
-    df = make_df(X_test, Q, penalty, binarization, domains)
-    return pretty_table(describe(df[!, [:penalty, :predict, :shifted, :accurate]]))
-end
-
-function train(
-    X,
-    penalty,
-    domains::Vector{D};
-    optimizer = GradientDescentOptimizer(),
-    X_test = X,
-) where {D <: DiscreteDomain}
-    Y, Q = preliminaries(X, domains, optimizer.binarization)
-    train!(
-        Q, Y, penalty, optimizer.η, optimizer.precision, X_test,
-        optimizer.oversampling, optimizer.binarization, domains
-    )
-    return Q
-end
-
-function train(
-    X,
-    penalty,
-    dom_stuff = nothing;
-    optimizer = GradientDescentOptimizer(),
-    X_test = X,
-)
-    return train(X, penalty, to_domains(X, dom_stuff); optimizer, X_test)
-end
- - - - \ No newline at end of file diff --git a/dev/learning/transformation.html b/dev/learning/transformation.html deleted file mode 100644 index b091144..0000000 --- a/dev/learning/transformation.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - Transformations Layer | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Transformations Layer

Some text to describe the transformation layer within usual ICNs.

The implementation of the transformation relies heavily on the use of the lazy function (make a ref, open an issue to make @lazy macro in front of each transformation).

List of transformations

List the possible parameters and how it affects the transformations.

Non-parametric

# CompositionalNetworks.tr_identityFunction.
julia
tr_identity(i, x)
-tr_identity(x)
-tr_identity(x, X::AbstractVector)

Identity function. Already defined in Julia as identity, specialized for vectors. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eqFunction.
julia
tr_count_eq(i, x)
-tr_count_eq(x)
-tr_count_eq(x, X::AbstractVector)

Count the number of elements equal to x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eq_rightFunction.
julia
tr_count_eq_right(i, x)
-tr_count_eq_right(x)
-tr_count_eq_right(x, X::AbstractVector)

Count the number of elements to the right of and equal to x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_eq_leftFunction.
julia
tr_count_eq_left(i, x)
-tr_count_eq_left(x)
-tr_count_eq_left(x, X::AbstractVector)

Count the number of elements to the left of and equal to x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_greaterFunction.
julia
tr_count_greater(i, x)
-tr_count_greater(x)
-tr_count_greater(x, X::AbstractVector)

Count the number of elements greater than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_lesserFunction.
julia
tr_count_lesser(i, x)
-tr_count_lesser(x)
-tr_count_lesser(x, X::AbstractVector)

Count the number of elements lesser than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_g_leftFunction.
julia
tr_count_g_left(i, x)
-tr_count_g_left(x)
-tr_count_g_left(x, X::AbstractVector)

Count the number of elements to the left of and greater than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_g_rightFunction.
julia
tr_count_g_right(i, x)
-tr_count_g_right(x)
-tr_count_g_right(x, X::AbstractVector)

Count the number of elements to the right of and greater than x[i]. Extended method to vector with sig (x) are generated.

source


# CompositionalNetworks.tr_count_l_rightFunction.
julia
tr_count_l_right(i, x)
-tr_count_l_right(x)
-tr_count_l_right(x, X::AbstractVector)

Count the number of elements to the right of and lesser than x[i]. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_contiguous_vals_minusFunction.
julia
tr_contiguous_vals_minus(i, x)
-tr_contiguous_vals_minus(x)
-tr_contiguous_vals_minus(x, X::AbstractVector)

Return the difference x[i] - x[i + 1] if positive, 0.0 otherwise. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_contiguous_vals_minus_revFunction.
julia
tr_contiguous_vals_minus_rev(i, x)
-tr_contiguous_vals_minus_rev(x)
-tr_contiguous_vals_minus_rev(x, X::AbstractVector)

Return the difference x[i + 1] - x[i] if positive, 0.0 otherwise. Extended method to vector with sig (x) are generated. When X is provided, the result is computed without allocations.

source


Param: :val

# CompositionalNetworks.tr_count_eq_paramFunction.
julia
tr_count_eq_param(i, x; param)
-tr_count_eq_param(x; param)
-tr_count_eq_param(x, X::AbstractVector; param)

Count the number of elements equal to x[i] + param. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_l_paramFunction.
julia
tr_count_l_param(i, x; param)
-tr_count_l_param(x; param)
-tr_count_l_param(x, X::AbstractVector; param)

Count the number of elements lesser than x[i] + param. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_g_paramFunction.
julia
tr_count_g_param(i, x; param)
-tr_count_g_param(x; param)
-tr_count_g_param(x, X::AbstractVector; param)

Count the number of elements greater than x[i] + param. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_count_bounding_paramFunction.
julia
tr_count_bounding_param(i, x; param)
-tr_count_bounding_param(x; param)
-tr_count_bounding_param(x, X::AbstractVector; param)

Count the number of elements bounded (not strictly) by x[i] and x[i] + param. An extended method to vector with sig (x, param) is generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_val_minus_paramFunction.
julia
tr_val_minus_param(i, x; param)
-tr_val_minus_param(x; param)
-tr_val_minus_param(x, X::AbstractVector; param)

Return the difference x[i] - param if positive, 0.0 otherwise. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


# CompositionalNetworks.tr_param_minus_valFunction.
julia
tr_param_minus_val(i, x; param)
-tr_param_minus_val(x; param)
-tr_param_minus_val(x, X::AbstractVector; param)

Return the difference param - x[i] if positive, 0.0 otherwise. Extended method to vector with sig (x, param) are generated. When X is provided, the result is computed without allocations.

source


Layer generation

# CompositionalNetworks.make_transformationsFunction.
julia
make_transformations(param::Symbol)

Generates a dictionary of transformation functions based on the specified parameterization. This function facilitates the creation of parametric layers for constraint transformations, allowing for flexible and dynamic constraint manipulation according to the needs of different constraint programming models.

Parameters

  • param::Symbol: Specifies the type of transformations to generate. It can be :none for basic transformations that do not depend on external parameters, or :val for transformations that operate with respect to a specific value parameter.

Returns

  • LittleDict{Symbol, Function}: A dictionary mapping transformation names (Symbol) to their corresponding functions (Function). The functions encapsulate various types of transformations, such as counting, comparison, and contiguous value processing.

Transformation Types

  • When param is :none, the following transformations are available:

    • :identity: No transformation is applied.

    • :count_eq, :count_eq_left, :count_eq_right: Count equalities under different conditions.

    • :count_greater, :count_lesser: Count values greater or lesser than a threshold.

    • :count_g_left, :count_l_left, :count_g_right, :count_l_right: Count values with greater or lesser comparisons from different directions.

    • :contiguous_vals_minus, :contiguous_vals_minus_rev: Process contiguous values with subtraction in normal and reverse order.

  • When param is :val, the transformations relate to operations involving a parameter value:

    • :count_eq_param, :count_l_param, :count_g_param: Count equalities or comparisons against a parameter value.

    • :count_bounding_param: Count values bounding a parameter value.

    • :val_minus_param, :param_minus_val: Subtract a parameter value from values or vice versa.

The function delegates to a version that uses Val(param) for dispatch, ensuring compile-time selection of the appropriate transformation set.

Examples

julia
# Get basic transformations
-basic_transforms = make_transformations(:none)
-
-# Apply an identity transformation
-identity_result = basic_transforms[:identity](data)
-
-# Get value-based transformations
-val_transforms = make_transformations(:val)
-
-# Apply a count equal to parameter transformation
-count_eq_param_result = val_transforms[:count_eq_param](data, param)

source


# CompositionalNetworks.transformation_layerFunction.
julia
transformation_layer(param = false)

Generate the layer of transformations functions of the ICN. Iff param value is true, also includes all the parametric transformations.

source


- - - - \ No newline at end of file diff --git a/dev/meta/meta_strategist.html b/dev/meta/meta_strategist.html deleted file mode 100644 index 2106707..0000000 --- a/dev/meta/meta_strategist.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - MetaStrategist.jl | Julia Constraints - - - - - - - - - - - - - -
Skip to content

MetaStrategist.jl

Documentation for MetaStrategist.jl.

- - - - \ No newline at end of file diff --git a/dev/perf/benchmark_ext.html b/dev/perf/benchmark_ext.html deleted file mode 100644 index 135cc4e..0000000 --- a/dev/perf/benchmark_ext.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - BenchmarkTools Extension | Julia Constraints - - - - - - - - - - - - - -
Skip to content

BenchmarkTools Extension

A benchmarking extension, based on BenchmarkTools.jl, has been interfaced with PerfChecker.jl. This section (will) provides some usage examples, documentation, and links to related notebooks.

- - - - \ No newline at end of file diff --git a/dev/perf/perf_checker.html b/dev/perf/perf_checker.html deleted file mode 100644 index 9958895..0000000 --- a/dev/perf/perf_checker.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - PerfChecker.jl | Julia Constraints - - - - - - - - - - - - - -
Skip to content

PerfChecker.jl

Documentation for PerfChecker.jl.

# PerfChecker.arrange_breakingMethod.

Outputs the last breaking or next breaking version.

source


# PerfChecker.arrange_majorMethod.

Outputs the earlier or next major version.

source


# PerfChecker.arrange_patchesMethod.

Outputs the last patch or first patch of a version.

source


# PerfChecker.get_pkg_versionsFunction.

Finds all versions of a package in all the installed registries and returns it as a vector.

Example:

julia
julia> get_pkg_versions("ConstraintLearning")
-7-element Vector{VersionNumber}:
- v"0.1.4"
- v"0.1.5"
- v"0.1.0"
- v"0.1.6"
- v"0.1.1"
- v"0.1.3"
- v"0.1.2"

source


- - - - \ No newline at end of file diff --git a/dev/perf/perf_interface.html b/dev/perf/perf_interface.html deleted file mode 100644 index f268def..0000000 --- a/dev/perf/perf_interface.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Interfacing PerfChecker | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Interfacing PerfChecker

PerfChecker was build as an easy to extend interface. This section will cover the few method required.

- - - - \ No newline at end of file diff --git a/dev/public_api.html b/dev/public_api.html deleted file mode 100644 index d4f6a22..0000000 --- a/dev/public_api.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - Public API | Julia Constraints - - - - - - - - - - - - - -
Skip to content

Public API

# ConstraintCommons.AutomatonType.
julia
Automaton{S, T, F <: Union{S, Vector{S}, Set{S}}} <: AbstractAutomaton

A minimal implementation of a deterministic automaton structure.

source


# ConstraintCommons.MDDType.
julia
MDD{S,T} <: AbstractMultivaluedDecisionDiagram

A minimal implementation of a multivalued decision diagram structure.

source


# ConstraintCommons.acceptMethod.
julia
accept(a::Union{Automaton, MDD}, w)

Return true if a accepts the word w and false otherwise.

source


# ConstraintCommons.extract_parametersMethod.
julia
extract_parameters(m::Union{Method, Function}; parameters)

Extracts the intersection between the kargs of m and parameters (defaults to USUAL_CONSTRAINT_PARAMETERS).

source


# ConstraintCommons.incsert!Function.
julia
incsert!(d::Union{AbstractDict, AbstractDictionary}, ind, val = 1)

Increase or insert a counter in a dictionary-based collection. The counter insertion defaults to val = 1.

source


# ConstraintCommons.oversampleMethod.
julia
oversample(X, f)

Oversample elements of X until the boolean function f has as many true and false configurations.

source


# ConstraintCommons.symconFunction.
julia
Base.:*(s1::Symbol, s2::Symbol, connector::AbstractString="_")

Extends * to Symbols multiplication by connecting the symbols by an _.

source


# ConstraintCommons.δ_extremaMethod.
julia
δ_extrema(X...)

Compute both the difference between the maximum and the minimum of over all the collections of X.

source


# ConstraintDomains.AbstractDomainType.
julia
AbstractDomain

An abstract super type for any domain type. A domain type D <: AbstractDomain must implement the following methods to properly interface AbstractDomain.

  • Base.∈(val, ::D)

  • Base.rand(::D)

  • Base.length(::D) that is the number of elements in a discrete domain, and the distance between bounds or similar for a continuous domain

Additionally, if the domain is used in a dynamic context, it can extend

  • add!(::D, args)

  • delete!(::D, args)

where args depends on D's structure

source


# ConstraintDomains.ContinuousDomainType.
julia
ContinuousDomain{T <: Real} <: AbstractDomain

An abstract supertype for all continuous domains.

source


# ConstraintDomains.DiscreteDomainType.
julia
DiscreteDomain{T <: Number} <: AbstractDomain

An abstract supertype for discrete domains (set, range).

source


# ConstraintDomains.ExploreSettingsMethod.
julia
ExploreSettings(
-    domains;
-    complete_search_limit = 10^6,
-    max_samplings = sum(domain_size, domains),
-    search = :flexible,
-    solutions_limit = floor(Int, sqrt(max_samplings)),
-)

Settings for the exploration of a search space composed by a collection of domains.

source


# ConstraintDomains.RangeDomainType.
julia
RangeDomain

A discrete domain defined by a range <: AbstractRange{Real}. As ranges are immutable in Julia, changes in RangeDomain must use set_domain!.

source


# Base.delete!Method.
julia
Base.delete!(d::SetDomain, value)(d::SetDomain, value)

Delete value from the list of points in d.

source


# ConstraintDomains.add!Method.
julia
add!(d::SetDomain, value)

Add value to the list of points in d.

source


# ConstraintDomains.domainMethod.
julia
domain(values)
-domain(range::R) where {T <: Real, R <: AbstractRange{T}}

Construct either a SetDomain or a `RangeDomain``.

julia
d1 = domain(1:5)
-d2 = domain([53.69, 89.2, 0.12])
-d3 = domain([2//3, 89//123])
-d4 = domain(4.3)
-d5 = domain(1,42,86.9)

source


# ConstraintDomains.domainMethod.
julia
domain()

Construct an EmptyDomain.

source


# ConstraintDomains.domainMethod.
julia
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
-domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}

Construct a domain of continuous interval(s).

source


# ConstraintDomains.domain_sizeMethod.
julia
domain_size(itv::Intervals)

Return the difference between the highest and lowest values in itv.

source


# ConstraintDomains.domain_sizeMethod.
julia
domain_size(d <: AbstractDomain)

Fallback method for domain_size(d) that return length(d).

source


# ConstraintDomains.domain_sizeMethod.
julia
domain_size(d::D) where D <: DiscreteDomain

Return the maximum distance between two points in d.

source


# ConstraintDomains.exploreMethod.
julia
explore(domains, concept, param = nothing; search_limit = 1000, solutions_limit = 100)

Search (a part of) a search space and returns a pair of vector of configurations: (solutions, non_solutions). If the search space size is over search_limit, then both solutions and non_solutions are limited to solutions_limit.

Beware that if the density of the solutions in the search space is low, solutions_limit needs to be reduced. This process will be automatic in the future (simple reinforcement learning).

Arguments:

  • domains: a collection of domains

  • concept: the concept of the targeted constraint

  • param: an optional parameter of the constraint

  • sol_number: the required number of solutions (half of the number of configurations), default to 100

source


# ConstraintDomains.generate_parametersMethod.
julia
generate_parameters(d<:AbstractDomain, param)

Generates random parameters based on the domain d and the kind of parameters param.

source


# ConstraintDomains.get_domainMethod.
julia
get_domain(::AbstractDomain)

Access the internal structure of any domain type.

source


# ConstraintDomains.intersect_domainsMethod.
julia
intersect_domains(d₁, d₂)

Compute the intersections of two domains.

source


# ConstraintDomains.merge_domainsMethod.
julia
merge_domains(d₁::AbstractDomain, d₂::AbstractDomain)

Merge two domains of same nature (discrete/contiuous).

source


# ConstraintDomains.to_domainsMethod.
julia
to_domains(args...)

Convert various arguments into valid domains format.

source


# Constraints.USUAL_CONSTRAINTSConstant.
julia
USUAL_CONSTRAINTS::Dict

Dictionary that contains all the usual constraints defined in Constraint.jl. It is based on XCSP3-core specifications available at https://arxiv.org/abs/2009.00514

Adding a new constraint is as simple as defining a new function with the same name as the constraint and using the @usual macro to define it. The macro will take care of adding the new constraint to the USUAL_CONSTRAINTS dictionary.

Example

julia
@usual concept_all_different(x; vals=nothing) = xcsp_all_different(list=x, except=vals)

source


# Constraints.USUAL_SYMMETRIESConstant.
julia
USUAL_SYMMETRIES

A Dictionary that contains the function to apply for each symmetry to avoid searching a whole space.

source


# Constraints.ConstraintType.
julia
Constraint

Parametric structure with the following fields.

  • concept: a Boolean function that, given an assignment x, outputs true if x satisfies the constraint, and false otherwise.

  • error: a positive function that works as preferences over invalid assignments. Return 0.0 if the constraint is satisfied, and a strictly positive real otherwise.

source


# ConstraintCommons.extract_parametersFunction.
julia
extract_parameters(s::Symbol, constraints_dict=USUAL_CONSTRAINTS; parameters=ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS)

Return the parameters of the constraint s in constraints_dict.

Arguments

  • s::Symbol: the constraint name.

  • constraints_dict::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

  • parameters::Vector{Symbol}: vector of parameters. Default is ConstraintCommons.USUAL_CONSTRAINT_PARAMETERS.

Example

julia
extract_parameters(:all_different)

source


# Constraints.argsMethod.
julia
args(c::Constraint)

Return the expected length restriction of the arguments in a constraint c. The value nothing indicates that any strictly positive number of value is accepted.

source


# Constraints.conceptMethod.
julia
concept(c::Constraint)

Return the concept (function) of constraint c. concept(c::Constraint, x...; param = nothing) Apply the concept of c to values x and optionally param.

source


# Constraints.conceptMethod.
julia
concept(s::Symbol, args...; kargs...)

Return the concept of the constraint s applied to args and kargs. This is a shortcut for concept(USUAL_CONSTRAINTS[s])(args...; kargs...).

Arguments

  • s::Symbol: the constraint name.

  • args...: the arguments to apply the concept to.

  • kargs...: the keyword arguments to apply the concept to.

Example

julia
concept(:all_different, [1, 2, 3])

source


# Constraints.constraints_descriptionsFunction.
julia
constraints_descriptions(C=USUAL_CONSTRAINTS)

Return a pretty table with the descriptions of the constraints in C.

Arguments

  • C::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

Example

julia
constraints_descriptions()

source


# Constraints.constraints_parametersFunction.
julia
constraints_parameters(C=USUAL_CONSTRAINTS)

Return a pretty table with the parameters of the constraints in C.

Arguments

  • C::Dict{Symbol,Constraint}: dictionary of constraints. Default is USUAL_CONSTRAINTS.

Example

julia
constraints_parameters()

source


# Constraints.describeFunction.
julia
describe(constraints::Dict{Symbol,Constraint}=USUAL_CONSTRAINTS; width=150)

Return a pretty table with the description of the constraints in constraints.

Arguments

  • constraints::Dict{Symbol,Constraint}: dictionary of constraints to describe. Default is USUAL_CONSTRAINTS.

  • width::Int: width of the table.

Example

julia
describe()

source


# Constraints.error_fMethod.
julia
error_f(c::Constraint)

Return the error function of constraint c. error_f(c::Constraint, x; param = nothing) Apply the error function of c to values x and optionally param.

source


# Constraints.params_lengthMethod.
julia
params_length(c::Constraint)

Return the expected length restriction of the arguments in a constraint c. The value nothing indicates that any strictly positive number of parameters is accepted.

source


# Constraints.symmetriesMethod.
julia
symmetries(c::Constraint)

Return the list of symmetries of c.

source


# CompositionalNetworks.CompositionMethod.
julia
Composition(f::F, symbols) where {F<:Function}

Construct a Composition.

source


# CompositionalNetworks.CompositionType.
julia
struct Composition{F<:Function}

Store the all the information of a composition learned by an ICN.

source


# CompositionalNetworks.ICNType.
julia
ICN(; nvars, dom_size, param, transformation, arithmetic, aggregation, comparison)

Construct an Interpretable Compositional Network, with the following arguments:

  • nvars: number of variable in the constraint

  • dom_size: maximum domain size of any variable in the constraint

  • param: optional parameter (default to nothing)

  • transformation: a transformation layer (optional)

  • arithmetic: a arithmetic layer (optional)

  • aggregation: a aggregation layer (optional)

  • comparison: a comparison layer (optional)

source


# CompositionalNetworks.aggregation_layerMethod.
julia
aggregation_layer()

Generate the layer of aggregations of the ICN. The operations are mutually exclusive, that is only one will be selected.

source


# CompositionalNetworks.arithmetic_layerMethod.
julia
arithmetic_layer()

Generate the layer of arithmetic operations of the ICN. The operations are mutually exclusive, that is only one will be selected.

source


# CompositionalNetworks.codeFunction.
julia
code(c::Composition, lang=:maths; name="composition")

Access the code of a composition c in a given language lang. The name of the generated method is optional.

source


# CompositionalNetworks.comparison_layerFunction.
julia
comparison_layer(param = false)

Generate the layer of transformations functions of the ICN. Iff param value is set, also includes all the parametric comparison with that value. The operations are mutually exclusive, that is only one will be selected.

source


# CompositionalNetworks.composeFunction.
julia
compose(icn, weights=nothing)

Return a function composed by some of the operations of a given ICN. Can be applied to any vector of variables. If weights are given, will assign to icn.

source


# CompositionalNetworks.compose_to_file!Method.
julia
compose_to_file!(concept, name, path; domains, param = nothing, language = :Julia, search = :complete, global_iter = 10, local_iter = 100, metric = hamming, popSize = 200)

Explore, learn and compose a function and write it to a file.

Arguments:

  • concept: the concept to learn

  • name: the name to give to the constraint

  • path: path of the output file

Keywords arguments:

  • domains: domains that defines the search space

  • param: an optional parameter of the constraint

  • language: the language to export to, default to :julia

  • search: either :partial or :complete search

  • global_iter: number of learning iteration

  • local_iter: number of generation in the genetic algorithm

  • metric: the metric to measure the distance between a configuration and known solutions

  • popSize: size of the population in the genetic algorithm

source


# CompositionalNetworks.compositionMethod.
julia
composition(c::Composition)

Access the actual method of an ICN composition c.

source


# CompositionalNetworks.composition_to_file!Function.
julia
composition_to_file!(c::Composition, path, name, language=:Julia)

Write the composition code in a given language into a file at path.

source


# CompositionalNetworks.explore_learn_composeMethod.
julia
explore_learn_compose(concept; domains, param = nothing, search = :complete, global_iter = 10, local_iter = 100, metric = hamming, popSize = 200, action = :composition)

Explore a search space, learn a composition from an ICN, and compose an error function.

Arguments:

  • concept: the concept of the targeted constraint

  • domains: domains of the variables that define the training space

  • param: an optional parameter of the constraint

  • search: either flexible,:partial or :complete search. Flexible search will use search_limit and solutions_limit to determine if the search space needs to be partially or completely explored

  • global_iter: number of learning iteration

  • local_iter: number of generation in the genetic algorithm

  • metric: the metric to measure the distance between a configuration and known solutions

  • popSize: size of the population in the genetic algorithm

  • action: either :symbols to have a description of the composition or :composition to have the composed function itself

source


# CompositionalNetworks.hammingMethod.
julia
hamming(x, X)

Compute the hamming distance of x over a collection of solutions X, i.e. the minimal number of variables to switch in xto reach a solution.

source


# CompositionalNetworks.lazyMethod.
julia
lazy(funcs::Function...)

Generate methods extended to a vector instead of one of its components. A function f should have the following signature: f(i::Int, x::V).

source


# CompositionalNetworks.lazy_paramMethod.
julia
lazy_param(funcs::Function...)

Generate methods extended to a vector instead of one of its components. A function f should have the following signature: f(i::Int, x::V; param).

source


# CompositionalNetworks.learn_composeMethod.
julia
learn_compose(;
-    nvars, dom_size, param=nothing, icn=ICN(nvars, dom_size, param),
-    X, X_sols, global_iter=100, local_iter=100, metric=hamming, popSize=200
-)

Create an ICN, optimize it, and return its composition.

source


# CompositionalNetworks.manhattanMethod.
julia
manhattan(x, X)

source


# CompositionalNetworks.minkowskiMethod.
julia
minkowski(x, X, p)

source


# CompositionalNetworks.nbitsMethod.
julia
nbits(icn)

Return the expected number of bits of a viable weight of an ICN.

source


# CompositionalNetworks.regularizationMethod.
julia
regularization(icn)

Return the regularization value of an ICN weights, which is proportional to the normalized number of operations selected in the icn layers.

source


# CompositionalNetworks.show_layersMethod.
julia
show_layers(icn)

Return a formatted string with each layers in the icn.

source


# CompositionalNetworks.symbolsMethod.
julia
symbols(c::Composition)

Output the composition as a layered collection of Symbols.

source


# CompositionalNetworks.transformation_layerFunction.
julia
transformation_layer(param = false)

Generate the layer of transformations functions of the ICN. Iff param value is true, also includes all the parametric transformations.

source


# CompositionalNetworks.weights!Method.
julia
weights!(icn, weights)

Set the weights of an ICN with a BitVector.

source


# CompositionalNetworks.weightsMethod.
julia
weights(icn)

Access the current set of weights of an ICN.

source


# CompositionalNetworks.weights_biasMethod.
julia
weights_bias(x)

A metric that bias x towards operations with a lower bit. Do not affect the main metric.

source


# QUBOConstraints.QUBO_linear_sumMethod.
julia
QUBO_linear_sum(n, σ)

One valid QUBO matrix given n variables and parameter σ for the linear sum constraint.

source


# QUBOConstraints.binarizeMethod.
julia
binarize(x[, domain]; binarization = :one_hot)

Binarize x following the binarization encoding. If x is a vector (instead of a number per say), domain is optional.

source


# QUBOConstraints.debinarizeMethod.
julia
debinarize(x[, domain]; binarization = :one_hot)

Transform a binary vector into a number or a set of number. If domain is not given, it will compute a default value based on binarization and x.

source


# QUBOConstraints.is_validFunction.
julia
is_valid(x, encoding::Symbol = :none)

Check if x has a valid format for encoding.

For instance, if encoding == :one_hot, at most one bit of x can be set to 1.

source


# QUBOConstraints.trainMethod.
julia
train(args...)

Default train method for any AbstractOptimizer.

source


- - - - \ No newline at end of file diff --git a/dev/solvers/cbls.html b/dev/solvers/cbls.html deleted file mode 100644 index 556a008..0000000 --- a/dev/solvers/cbls.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - CBLS.jl | Julia Constraints - - - - - - - - - - - - - -
Skip to content

CBLS.jl

Documentation for CBLS.jl.

# CBLS.AllDifferentType.

Global constraint ensuring that all the values of a given configuration are unique.

julia
@constraint(model, X in AllDifferent())

source


# CBLS.AllEqualType.

Global constraint ensuring that all the values of X are all equal.

julia
@constraint(model, X in AllEqual())

source


# CBLS.AllEqualParamType.

Global constraint ensuring that all the values of X are all equal to a given parameter param.

julia
@constraint(model, X in AllEqualParam(param))

source


# CBLS.AlwaysTrueType.

Always return true. Mainly used for testing purpose.

julia
@constraint(model, X in AlwaysTrue())

source


# CBLS.DiscreteSetType.
julia
DiscreteSet(values)

source


# CBLS.DistDifferentType.

Local constraint ensuring that, given a vector X of size 4, |X[1] - X[2]| ≠ |X[3] - X[4]|).

julia
@constraint(model, X in DistDifferent())

source


# CBLS.EqType.

Equality between two variables.

julia
@constraint(model, X in Eq())

source


# CBLS.ErrorType.
julia
Error{F <: Function} <: JuMP.AbstractVectorSet

The solver will compute a straightforward error function based on the concept. To run the solver efficiently, it is possible to provide an error function err instead of concept. err must return a nonnegative real number.

julia
@constraint(model, X in Error(err))

source


# CBLS.LessThanParamType.

Constraint ensuring that the value of x is less than a given parameter param.

julia
@constraint(model, x in LessThanParam(param))

source


# CBLS.MOIAllDifferentType.
julia
MOIAllDifferent <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOIAllEqualType.
julia
MOIAllEqual <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOIAllEqualParamType.
julia
MOIAllEqualParam{T <: Number} <: MOI.AbstractVectorSet

DOCSTRING

Arguments:

  • param::T: DESCRIPTION

  • dimension::Int: DESCRIPTION

  • MOIAllEqualParam(param, dim = 0) = begin #= none:5 =# new{typeof(param)}(param, dim) end: DESCRIPTION

source


# CBLS.MOIAlwaysTrueType.
julia
MOIAlwaysTrue <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOIDistDifferentType.
julia
MOIDistDifferent <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOIEqType.
julia
MOIEq <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOIErrorType.
julia
MOIError{F <: Function} <: MOI.AbstractVectorSet

DOCSTRING

Arguments:

  • f::F: DESCRIPTION

  • dimension::Int: DESCRIPTION

  • MOIError(f, dim = 0) = begin #= none:5 =# new{typeof(f)}(f, dim) end: DESCRIPTION

source


# CBLS.MOILessThanParamType.
julia
MOILessThanParam{T <: Number} <: MOI.AbstractVectorSet

DOCSTRING

Arguments:

  • param::T: DESCRIPTION

  • dimension::Int: DESCRIPTION

  • MOILessThanParam(param, dim = 0) = begin #= none:5 =# new{typeof(param)}(param, dim) end: DESCRIPTION

source


# CBLS.MOIMinusEqualParamType.
julia
MOIMinusEqualParam{T <: Number} <: MOI.AbstractVectorSet

DOCSTRING

Arguments:

  • param::T: DESCRIPTION

  • dimension::Int: DESCRIPTION

  • MOIMinusEqualParam(param, dim = 0) = begin #= none:5 =# new{typeof(param)}(param, dim) end: DESCRIPTION

source


# CBLS.MOIOrderedType.
julia
MOIOrdered <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOIPredicateType.
julia
MOIPredicate{F <: Function} <: MOI.AbstractVectorSet

DOCSTRING

Arguments:

  • f::F: DESCRIPTION

  • dimension::Int: DESCRIPTION

  • MOIPredicate(f, dim = 0) = begin #= none:5 =# new{typeof(f)}(f, dim) end: DESCRIPTION

source


# CBLS.MOISequentialTasksType.
julia
MOISequentialTasks <: MOI.AbstractVectorSet

DOCSTRING

source


# CBLS.MOISumEqualParamType.
julia
MOISumEqualParam{T <: Number} <: MOI.AbstractVectorSet

DOCSTRING

Arguments:

  • param::T: DESCRIPTION

  • dimension::Int: DESCRIPTION

  • MOISumEqualParam(param, dim = 0) = begin #= none:5 =# new{typeof(param)}(param, dim) end: DESCRIPTION

source


# CBLS.MinusEqualParamType.

Constraint ensuring that the value of x is less than a given parameter param.

julia
@constraint(model, x in MinusEqualParam(param))

source


# CBLS.OptimizerType.
julia
Optimizer(model = Model(); options = Options())

DOCSTRING

source


# CBLS.OptimizerType.
julia
Optimizer <: MOI.AbstractOptimizer

DOCSTRING

Arguments:

  • solver::Solver: DESCRIPTION

  • status::MOI.TerminationStatusCode: DESCRIPTION

  • options::Options: DESCRIPTION

source


# CBLS.OrderedType.

Global constraint ensuring that all the values of x are ordered.

julia
@constraint(model, X in Ordered())

source


# CBLS.PredicateType.
julia
Predicate{F <: Function} <: JuMP.AbstractVectorSet

Assuming X is a (collection of) variables, concept a boolean function over X, and that a model is defined. In JuMP syntax we can create a constraint based on concept as follows.

julia
@constraint(model, X in Predicate(concept))

source


# CBLS.ScalarFunctionType.
julia
ScalarFunction{F <: Function, V <: Union{Nothing, VOV}} <: MOI.AbstractScalarFunction

A container to express any function with real value in JuMP syntax. Used with the @objective macro.

Arguments:

  • f::F: function to be applied to X

  • X::V: a subset of the variables of the model.

Given a model, and some (collection of) variables X to optimize. an objective function f can be added as follows. Note that only Min for minimization us currently defined. Max will come soon.

julia
# Applies to all variables in order of insertion.
-# Recommended only when the function argument order does not matter.
-@objective(model, ScalarFunction(f))
-
-# Generic use
-@objective(model, ScalarFunction(f, X))

source


# CBLS.SequentialTasksType.

Local constraint ensuring that, given a vector X of size 4, |X[1] - X[2]| ≠ |X[3] - X[4]|).

julia
@constraint(model, X in SequentialTasks())

source


# CBLS.SumEqualParamType.

Global constraint ensuring that the sum of the values of X is equal to a given parameter param.

julia
@constraint(model, X in SumEqualParam(param))

source


# Base.copyMethod.
julia
Base.copy(set::MOIError) = begin

DOCSTRING

source


# Base.copyMethod.
julia
Base.copy(set::DiscreteSet) = begin

DOCSTRING

source


# JuMP.build_variableMethod.
julia
JuMP.build_variable(::Function, info::JuMP.VariableInfo, set::T) where T <: MOI.AbstractScalarSet

DOCSTRING

Arguments:

  • ``: DESCRIPTION

  • info: DESCRIPTION

  • set: DESCRIPTION

source


# MathOptInterface.add_constraintMethod.
julia
MOI.add_constraint(optimizer::Optimizer, vars::MOI.VectorOfVariables, set::MOIError)

DOCSTRING

Arguments:

  • optimizer: DESCRIPTION

  • vars: DESCRIPTION

  • set: DESCRIPTION

source


# MathOptInterface.add_constraintMethod.
julia
MOI.add_constraint(optimizer::Optimizer, v::VI, set::DiscreteSet{T}) where T <: Number

DOCSTRING

Arguments:

  • optimizer: DESCRIPTION

  • v: DESCRIPTION

  • set: DESCRIPTION

source


# MathOptInterface.add_variableMethod.
julia
MOI.add_variable(model::Optimizer) = begin

DOCSTRING

source


# MathOptInterface.empty!Method.
julia
MOI.empty!(opt) = begin

DOCSTRING

source


# MathOptInterface.getMethod.
julia
MOI.get(::Optimizer, ::MOI.SolverName) = begin

DOCSTRING

source


# MathOptInterface.is_emptyMethod.
julia
MOI.is_empty(model::Optimizer) = begin

DOCSTRING

source


# MathOptInterface.optimize!Method.
julia
MOI.optimize!(model::Optimizer)

source


# MathOptInterface.setFunction.
julia
MOI.set(::Optimizer, ::MOI.Silent, bool = true) = begin

DOCSTRING

Arguments:

  • ``: DESCRIPTION

  • ``: DESCRIPTION

  • bool: DESCRIPTION

source


# MathOptInterface.setMethod.
julia
MOI.set(model::Optimizer, p::MOI.RawOptimizerAttribute, value)

Set a RawOptimizerAttribute to value

source


# MathOptInterface.setMethod.
julia
MOI.set(model::Optimizer, ::MOI.TimeLimitSec, value::Union{Nothing,Float64})

Set the time limit

source


# MathOptInterface.supports_constraintMethod.
julia
MOI.supports_constraint(::Optimizer, ::Type{VOV}, ::Type{MOIError}) = begin

DOCSTRING

Arguments:

  • ``: DESCRIPTION

  • ``: DESCRIPTION

  • ``: DESCRIPTION

source


# MathOptInterface.supports_incremental_interfaceMethod.

Copy constructor for the optimizer

source


- - - - \ No newline at end of file diff --git a/dev/solvers/intro.html b/dev/solvers/intro.html deleted file mode 100644 index 17b181f..0000000 --- a/dev/solvers/intro.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Solvers | Julia Constraints - - - - - - - - - - - - - -
Skip to content
- - - - \ No newline at end of file diff --git a/dev/solvers/local_search_solvers.html b/dev/solvers/local_search_solvers.html deleted file mode 100644 index d859bce..0000000 --- a/dev/solvers/local_search_solvers.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - LocalSearchSolvers.jl | Julia Constraints - - - - - - - - - - - - - -
Skip to content

LocalSearchSolvers.jl

Documentation for LocalSearchSolvers.jl.

# LocalSearchSolvers.AbstractSolverType.
julia
AbstractSolver

Abstract type to encapsulate the different solver types such as Solver or _SubSolver.

source


# LocalSearchSolvers.ConstraintType.
julia
Constraint{F <: Function}

Structure to store an error function and the variables it constrains.

source


# LocalSearchSolvers.LeadSolverType.
julia
LeadSolver <: MetaSolver

Solver managed remotely by a MainSolver. Can manage its own set of local sub solvers.

source


# LocalSearchSolvers.MainSolverType.
julia
MainSolver <: AbstractSolver

Main solver. Handle the solving of a model, and optional multithreaded and/or distributed subsolvers.

Arguments:

  • model::Model: A formal description of the targeted problem

  • state::_State: An internal state to store the info necessary to a solving run

  • options::Options: User options for this solver

  • subs::Vector{_SubSolver}: Optional subsolvers

source


# LocalSearchSolvers.MetaSolverType.

Abstract type to encapsulate all solver types that manages other solvers.

source


# LocalSearchSolvers.ObjectiveType.
julia
Objective{F <: Function}

A structure to handle objectives in a solver. `struct Objective{F <: Function} name::String f::F end``

source


# LocalSearchSolvers.ObjectiveMethod.
julia
Objective(F, o::Objective{F2}) where {F2 <: Function}

Constructor used in specializing a solver. Should never be called externally.

source


# LocalSearchSolvers.OptionsType.
julia
Options()

Arguments:

  • dynamic::Bool: is the model dynamic?

  • iteration::Union{Int, Float64}: limit on the number of iterations

  • print_level::Symbol: verbosity to choose among :silent, :minimal, :partial, :verbose

  • solutions::Int: number of solutions to return

  • specialize::Bool: should the types of the model be specialized or not. Usually yes for static problems. For dynamic in depends if the user intend to introduce new types. The specialized model is about 10% faster.

  • tabu_time::Int: DESCRIPTION

  • tabu_local::Int: DESCRIPTION

  • tabu_delta::Float64: DESCRIPTION

  • threads::Int: Number of threads to use

  • time_limit::Float64: time limit in seconds

  • `function Options(; dynamic = false, iteration = 10000, print_level = :minimal, solutions = 1, specialize = !dynamic, tabu_time = 0, tabu_local = 0, tabu_delta = 0.0, threads = typemax(0), time_limit = Inf)

julia
# Setting options in JuMP syntax: print_level, time_limit, iteration
-model = Model(CBLS.Optimizer)
-set_optimizer_attribute(model, "iteration", 100)
-set_optimizer_attribute(model, "print_level", :verbose)
-set_time_limit_sec(model, 5.0)

source


# LocalSearchSolvers.VariableType.
julia
Variable{D <: AbstractDomain}

A structure containing the necessary information for a solver's variables: name, domain, and constraints it belongs.

struct Variable{D <: AbstractDomain}
-    domain::D
-    constraints::Indices{Int}
-end

source


# LocalSearchSolvers._ModelType.
julia
_Model{V <: Variable{<:AbstractDomain},C <: Constraint{<:Function},O <: Objective{<:Function}}

A struct to model a problem as a set of variables, domains, constraints, and objectives.

struct _Model{V <: Variable{<:AbstractDomain},C <: Constraint{<:Function},O <: Objective{<:Function}}
-    variables::Dictionary{Int,V}
-    constraints::Dictionary{Int,C}
-    objectives::Dictionary{Int,O}
-
-    # counter to add new variables: vars, cons, objs
-    max_vars::Ref{Int}
-    max_cons::Ref{Int}
-    max_objs::Ref{Int}
-
-    # Bool to indicate if the _Model instance has been specialized (relatively to types)
-    specialized::Ref{Bool}
-
-    # Symbol to indicate the kind of model for specialized methods such as pretty printing
-    kind::Symbol
-end

source


# LocalSearchSolvers._StateType.
julia
GeneralState{T <: Number}

A mutable structure to store the general state of a solver. All methods applied to GeneralState are forwarded to S <: AbstractSolver.

mutable struct GeneralState{T <: Number} <: AbstractState
-    configuration::Configuration{T}
-    cons_costs::Dictionary{Int, Float64}
-    last_improvement::Int
-    tabu::Dictionary{Int, Int}
-    vars_costs::Dictionary{Int, Float64}
-end

source


# LocalSearchSolvers._SubSolverType.
julia
_SubSolver <: AbstractSolver

An internal solver type called by MetaSolver when multithreading is enabled.

Arguments:

  • id::Int: subsolver id for debugging

  • model::Model: a ref to the model of the main solver

  • state::_State: a deepcopy of the main solver that evolves independently

  • options::Options: a ref to the options of the main solver

source


# Base.empty!Method.
julia
empty!(s::Solver)

source


# Base.empty!Method.
julia
empty!(m::Model)

DOCSTRING

source


# Base.inMethod.
julia
var::Int c::Constraint

source


# Base.inMethod.
julia
x::Variable constraint
-value  x::Variable

Check if a variable x is restricted by a constraint::Int, or if a value belongs to the domain of x.

source


# LocalSearchSolvers._add!Method.
julia
_add!(c::Constraint, x)

Add the variable of indice x to c.

source


# LocalSearchSolvers._add_to_constraint!Method.
julia
_add_to_constraint!(x::Variable, id)

Add a constraint id to the list of constraints of x.

source


# LocalSearchSolvers._check_restartMethod.
julia
_check_restart(s)

Check if a restart of s is necessary. If s has subsolvers, this check is independent for all of them.

source


# LocalSearchSolvers._check_subsMethod.
julia
_check_subs(s)

Check if any subsolver of a main solver s, for

  • Satisfaction, has a solution, then return it, resume the run otherwise

  • Optimization, has a better solution, then assign it to its internal state

source


# LocalSearchSolvers._compute!Method.
julia
_compute!(s; o::Int = 1, cons_lst = Indices{Int}())

Compute the objective o's value if s is satisfied and return the current error.

Arguments:

  • s: a solver

  • o: targeted objective

  • cons_lst: list of targeted constraints, if empty compute for the whole set

source


# LocalSearchSolvers._compute_cost!Method.
julia
_compute_cost!(s, ind, c)

Compute the cost of constraint c with index ind.

source


# LocalSearchSolvers._compute_costs!Method.
julia
_compute_costs!(s; cons_lst::Indices{Int} = Indices{Int}())

Compute the cost of constraints c in cons_lst. If cons_lst is empty, compute the cost for all the constraints in s.

source


# LocalSearchSolvers._compute_objective!Method.
julia
_compute_objective!(s, o::Objective)
-_compute_objective!(s, o = 1)

Compute the objective o's value.

source


# LocalSearchSolvers._cons_cost!Method.
julia
_cons_cost!(s::S, c, cost) where S <: Union{_State, AbstractSolver}

Set the cost of constraint c.

source


# LocalSearchSolvers._cons_costMethod.
julia
_cons_cost(s::S, c) where S <: Union{_State, AbstractSolver}

Return the cost of constraint c.

source


# LocalSearchSolvers._cons_costs!Method.
julia
_cons_costs!(s::S, costs) where S <: Union{_State, AbstractSolver}

Set the constraints costs.

source


# LocalSearchSolvers._cons_costsMethod.
julia
_cons_costs(s::S) where S <: Union{_State, AbstractSolver}

Access the constraints costs.

source


# LocalSearchSolvers._constrictionMethod.
julia
_constriction(x::Variable)

Return the cosntriction of x, i.e. the number of constraints restricting x.

source


# LocalSearchSolvers._delete!Method.
julia
_delete!(c::Constraint, x::Int)

Delete x from c.

source


# LocalSearchSolvers._delete_from_constraint!Method.
julia
_delete_from_constraint!(x::Variable, id)

Delete a constraint id from the list of constraints of x.

source


# LocalSearchSolvers._draw!Method.
julia
_draw!(s)

Draw a random (re-)starting configuration.

source


# LocalSearchSolvers._dynamic!Method.
julia
_dynamic!(options, dynamic) = begin

DOCSTRING

source


# LocalSearchSolvers._dynamicMethod.
julia
_dynamic(options) = begin

DOCSTRING

source


# LocalSearchSolvers._find_rand_argmaxMethod.
julia
_find_rand_argmax(d::DictionaryView)

Compute argmax of d and select one element randomly.

source


# LocalSearchSolvers._get_constraintsMethod.
julia
_get_constraints(x::Variable)

Access the list of constraints of x.

source


# LocalSearchSolvers._get_varsMethod.
julia
_get_vars(c::Constraint)

Returns the variables constrained by c.

source


# LocalSearchSolvers._inc_cons!Method.
julia
_inc_vars!(m::M) where M <: Union{Model, AbstractSolver}

Increment the maximum constraint id that has been attributed to m.

source


# LocalSearchSolvers._inc_objs!Method.
julia
_inc_vars!(m::M) where M <: Union{Model, AbstractSolver}

Increment the maximum objective id that has been attributed to m.

source


# LocalSearchSolvers._inc_vars!Method.
julia
_inc_vars!(m::M) where M <: Union{Model, AbstractSolver}

Increment the maximum variable id that has been attributed to m.

source


# LocalSearchSolvers._info_path!Method.
julia
_info_path!(options, iterations) = begin

DOCSTRING

source


# LocalSearchSolvers._info_pathMethod.
julia
_info_path(options, path)

DOCSTRING

source


# LocalSearchSolvers._is_emptyMethod.
julia
_is_empty(m::Model)

DOCSTRING

source


# LocalSearchSolvers._iteration!Method.
julia
_iteration!(options, iterations) = begin

DOCSTRING

source


# LocalSearchSolvers._iterationMethod.
julia
_iteration(options) = begin

DOCSTRING

source


# LocalSearchSolvers._lengthMethod.
julia
_length(c::Constraint)

Return the number of constrained variables by c.

source


# LocalSearchSolvers._max_consMethod.
julia
_max_cons(m::M) where M <: Union{Model, AbstractSolver}

Access the maximum constraint id that has been attributed to m.

source


# LocalSearchSolvers._max_objsMethod.
julia
_max_objs(m::M) where M <: Union{Model, AbstractSolver}

Access the maximum objective id that has been attributed to m.

source


# LocalSearchSolvers._max_varsMethod.
julia
_max_vars(m::M) where M <: Union{Model, AbstractSolver}

Access the maximum variable id that has been attributed to m.

source


# LocalSearchSolvers._move!Function.
julia
_move!(s, x::Int, dim::Int = 0)

Perform an improving move in x neighbourhood if possible.

Arguments:

  • s: a solver of type S <: AbstractSolver

  • x: selected variable id

  • dim: describe the dimension of the considered neighbourhood

source


# LocalSearchSolvers._neighboursFunction.
julia
_neighbours(s, x, dim = 0)

DOCSTRING

Arguments:

  • s: DESCRIPTION

  • x: DESCRIPTION

  • dim: DESCRIPTION

source


# LocalSearchSolvers._optimizing!Method.
julia
_optimizing!(s::S) where S <: Union{_State, AbstractSolver}

Set the solver optimizing status to true.

source


# LocalSearchSolvers._optimizingMethod.
julia
_optimizing(s::S) where S <: Union{_State, AbstractSolver}

Check if s is in an optimizing state.

source


# LocalSearchSolvers._print_level!Method.
julia
_print_level!(options, level) = begin

DOCSTRING

source


# LocalSearchSolvers._print_levelMethod.
julia
_print_level(options) = begin

DOCSTRING

source


# LocalSearchSolvers._restart!Function.
julia
_restart!(s, k = 10)

Restart a solver.

source


# LocalSearchSolvers._satisfying!Method.
julia
_satisfying!(s::S) where S <: Union{_State, AbstractSolver}

Set the solver optimizing status to false.

source


# LocalSearchSolvers._select_worseMethod.
julia
_select_worse(s::S) where S <: Union{_State, AbstractSolver}

Within the non-tabu variables, select the one with the worse error .

source


# LocalSearchSolvers._set!Method.
julia
_set!(s::S, x, val) where S <: Union{_State, AbstractSolver}

Set the value of variable x to val.

source


# LocalSearchSolvers._set_domain!Method.
julia
_set_domain!(m::Model, x, values)

DOCSTRING

Arguments:

  • m: DESCRIPTION

  • x: DESCRIPTION

  • values: DESCRIPTION

source


# LocalSearchSolvers._solutions!Method.
julia
_solutions!(options, solutions) = begin

DOCSTRING

source


# LocalSearchSolvers._solutionsMethod.
julia
_solutions(options) = begin

DOCSTRING

source


# LocalSearchSolvers._specialize!Method.
julia
_specialize!(options, specialize) = begin

DOCSTRING

source


# LocalSearchSolvers._specializeMethod.
julia
_specialize(options) = begin

DOCSTRING

source


# LocalSearchSolvers._step!Method.
julia
_step!(s)

Iterate a step of the solver run.

source


# LocalSearchSolvers._swap_value!Method.
julia
_set!(s::S, x, y) where S <: Union{_State, AbstractSolver}

Swap the values of variables x and y.

source


# LocalSearchSolvers._tabu_delta!Method.
julia
_tabu_delta!(options, time) = begin

DOCSTRING

source


# LocalSearchSolvers._tabu_deltaMethod.
julia
_tabu_delta(options) = begin

DOCSTRING

source


# LocalSearchSolvers._tabu_local!Method.
julia
_tabu_local!(options, time) = begin

DOCSTRING

source


# LocalSearchSolvers._tabu_localMethod.
julia
_tabu_local(options) = begin

DOCSTRING

source


# LocalSearchSolvers._tabu_time!Method.
julia
_tabu_time!(options, time) = begin

DOCSTRING

source


# LocalSearchSolvers._tabu_timeMethod.
julia
_tabu_time(options) = begin

DOCSTRING

source


# LocalSearchSolvers._threads!Method.
julia
_threads!(options, threads) = begin

DOCSTRING

source


# LocalSearchSolvers._threadsMethod.
julia
_threads(options) = begin

DOCSTRING

source


# LocalSearchSolvers._time_limit!Method.
julia
_time_limit!(options, time::Time) = begin

DOCSTRING

source


# LocalSearchSolvers._time_limitMethod.
julia
_time_limit(options) = begin

DOCSTRING

source


# LocalSearchSolvers._to_unionMethod.
julia
_to_union(datatype)

Make a minimal Union type from a collection of data types.

source


# LocalSearchSolvers._value!Method.
julia
_value!(s::S, x, val) where S <: Union{_State, AbstractSolver}

Set the value of variable x to val.

source


# LocalSearchSolvers._valueMethod.
julia
_value(s::S, x) where S <: Union{_State, AbstractSolver}

Return the value of variable x.

source


# LocalSearchSolvers._values!Method.
julia
_values!(s::S, values) where S <: Union{_State, AbstractSolver}

Set the variables values.

source


# LocalSearchSolvers._valuesMethod.
julia
_vars_costs(s::S) where S <: Union{_State, AbstractSolver}

Access the variables costs.

source


# LocalSearchSolvers._var_cost!Method.
julia
_var_cost!(s::S, x, cost) where S <: Union{_State, AbstractSolver}

Set the cost of variable x.

source


# LocalSearchSolvers._var_costMethod.
julia
_var_cost(s::S, x) where S <: Union{_State, AbstractSolver}

Return the cost of variable x.

source


# LocalSearchSolvers._vars_costs!Method.
julia
_vars_costs!(s::S, costs) where S <: Union{_State, AbstractSolver}

Set the variables costs.

source


# LocalSearchSolvers._vars_costsMethod.
julia
_vars_costs(s::S) where S <: Union{_State, AbstractSolver}

Access the variables costs.

source


# LocalSearchSolvers._verboseMethod.
julia
_verbose(settings, str)

Temporary logging function. #TODO: use better log instead (LoggingExtra.jl)

source


# LocalSearchSolvers.add!Method.
julia
mts = - get_time_stamp(model)

return TimeStamps(mts, mts, mts, mts, mts, mts, mts) end

add!(m::M, x) where M <: Union{Model, AbstractSolver}
-add!(m::M, c) where M <: Union{Model, AbstractSolver}
-add!(m::M, o) where M <: Union{Model, AbstractSolver}

Add a variable x, a constraint c, or an objective o to m.

source


# LocalSearchSolvers.add_value!Method.
julia
add_value!(m::M, x, val) where M <: Union{Model, AbstractSolver}

Add val to x domain.

source


# LocalSearchSolvers.add_var_to_cons!Method.
julia
add_var_to_cons!(m::M, c, x) where M <: Union{Model, AbstractSolver}

Add x to the constraint c list of restricted variables.

source


# LocalSearchSolvers.constraint!Method.
julia
constraint!(m::M, func, vars) where M <: Union{Model, AbstractSolver}

Add a constraint with an error function func defined over variables vars.

source


# LocalSearchSolvers.constraintMethod.
julia
constraint(f, vars)

DOCSTRING

source


# LocalSearchSolvers.constrictionMethod.
julia
constriction(m::M, x) where M <: Union{Model, AbstractSolver}

Return the constriction of variable x.

source


# LocalSearchSolvers.decay_tabu!Method.
julia
_decay_tabu!(s::S) where S <: Union{_State, AbstractSolver}

Decay the tabu list.

source


# LocalSearchSolvers.decrease_tabu!Method.
julia
_decrease_tabu!(s::S, x) where S <: Union{_State, AbstractSolver}

Decrement the tabu value of variable x.

source


# LocalSearchSolvers.delete_tabu!Method.
julia
_delete_tabu!(s::S, x) where S <: Union{_State, AbstractSolver}

Delete the tabu entry of variable x.

source


# LocalSearchSolvers.delete_value!Method.
julia
delete_value(m::M, x, val) where M <: Union{Model, AbstractSolver}

Delete val from x domain.

source


# LocalSearchSolvers.delete_var_from_cons!Method.
julia
delete_var_from_cons(m::M, c, x) where M <: Union{Model, AbstractSolver}

Delete x from the constraint c list of restricted variables.

source


# LocalSearchSolvers.describeMethod.
julia
describe(m::M) where M <: Union{Model, AbstractSolver}

Describe the model.

source


# LocalSearchSolvers.domain_sizeMethod.
julia
domain_size(m::Model, x) = begin

DOCSTRING

source


# LocalSearchSolvers.drawMethod.
julia
draw(m::M, x) where M <: Union{Model, AbstractSolver}

Draw a random value of x domain.

source


# LocalSearchSolvers.empty_tabu!Method.
julia
_empty_tabu!(s::S) where S <: Union{_State, AbstractSolver}

Empty the tabu list.

source


# LocalSearchSolvers.get_cons_from_varMethod.
julia
get_cons_from_var(m::M, x) where M <: Union{Model, AbstractSolver}

Access the constraints restricting variable x.

source


# LocalSearchSolvers.get_constraintMethod.
julia
get_constraint(m::M, c) where M <: Union{Model, AbstractSolver}

Access the constraint c.

source


# LocalSearchSolvers.get_constraintsMethod.
julia
get_constraints(m::M) where M <: Union{Model, AbstractSolver}

Access the constraints of m.

source


# LocalSearchSolvers.get_domainMethod.
julia
get_domain(m::M, x) where M <: Union{Model, AbstractSolver}

Access the domain of variable x.

source


# LocalSearchSolvers.get_kindMethod.
julia
get_kind(m::M) where M <: Union{Model, AbstractSolver}

Access the kind of m, such as :sudoku or :generic (default).

source


# LocalSearchSolvers.get_nameMethod.
julia
get_name(m::M, x) where M <: Union{Model, AbstractSolver}

Access the name of variable x.

source


# LocalSearchSolvers.get_objectiveMethod.
julia
get_objective(m::M, o) where M <: Union{Model, AbstractSolver}

Access the objective o.

source


# LocalSearchSolvers.get_objectivesMethod.
julia
get_objectives(m::M) where M <: Union{Model, AbstractSolver}

Access the objectives of m.

source


# LocalSearchSolvers.get_time_stampMethod.
julia
get_time_stamp(m::M) where M <: Union{Model, AbstractSolver}

Access the time (since epoch) when the model was created. This time stamp is for internal performance measurement.

source


# LocalSearchSolvers.get_variableMethod.
julia
get_variable(m::M, x) where M <: Union{Model, AbstractSolver}

Access the variable x.

source


# LocalSearchSolvers.get_variablesMethod.
julia
get_variables(m::M) where M <: Union{Model, AbstractSolver}

Access the variables of m.

source


# LocalSearchSolvers.get_vars_from_consMethod.
julia
get_vars_from_cons(m::M, c) where M <: Union{Model, AbstractSolver}

Access the variables restricted by constraint c.

source


# LocalSearchSolvers.insert_tabu!Method.
julia
_insert_tabu!(s::S, x, tabu_time) where S <: Union{_State, AbstractSolver}

Insert the bariable x as tabu for tabu_time.

source


# LocalSearchSolvers.is_satMethod.
julia
is_sat(m::M) where M <: Union{Model, AbstractSolver}

Return true if m is a satisfaction model.

source


# LocalSearchSolvers.is_specializedMethod.
julia
is_specialized(m::M) where M <: Union{Model, AbstractSolver}

Return true if the model is already specialized.

source


# LocalSearchSolvers.length_consMethod.
julia
length_cons(m::M, c) where M <: Union{Model, AbstractSolver}

Return the length of constraint c.

source


# LocalSearchSolvers.length_consMethod.
julia
length_cons(m::M) where M <: Union{Model, AbstractSolver}

Return the number of constraints in m.

source


# LocalSearchSolvers.length_objsMethod.
julia
length_objs(m::M) where M <: Union{Model, AbstractSolver}

Return the number of objectives in m.

source


# LocalSearchSolvers.length_tabuMethod.
julia
_length_tabu!(s::S) where S <: Union{_State, AbstractSolver}

Return the length of the tabu list.

source


# LocalSearchSolvers.length_varMethod.
julia
length_var(m::M, x) where M <: Union{Model, AbstractSolver}

Return the domain length of variable x.

source


# LocalSearchSolvers.length_varsMethod.
julia
length_vars(m::M) where M <: Union{Model, AbstractSolver}

Return the number of variables in m.

source


# LocalSearchSolvers.max_domains_sizeMethod.
julia
max_domains_size(m::Model, vars) = begin

DOCSTRING

source


# LocalSearchSolvers.modelMethod.
julia
model()

Construct a _Model, empty by default. It is recommended to add the constraints, variables, and objectives from an empty _Model. The following keyword arguments are available,

  • vars=Dictionary{Int,Variable}(): collection of variables

  • cons=Dictionary{Int,Constraint}(): collection of constraints

  • objs=Dictionary{Int,Objective}(): collection of objectives

  • kind=:generic: the kind of problem modeled (useful for specialized methods such as pretty printing)

source


# LocalSearchSolvers.o_dist_extremaMethod.
julia
dist_extrema(values::T...) where {T <: Number}

Computes the distance between extrema in an ordered set.

source


# LocalSearchSolvers.o_mincutMethod.
julia
o_mincut(graph, values; interdiction = 0)

Compute the capacity of a cut (determined by the state of the solver) with a possible interdiction on the highest capacited links.

source


# LocalSearchSolvers.objective!Method.
julia
objective!(m::M, func) where M <: Union{Model, AbstractSolver}

Add an objective evaluated by func.

source


# LocalSearchSolvers.objectiveMethod.
julia
objective(func, name)

Construct an objective with a function func that should be applied to a collection of variables.

source


# LocalSearchSolvers.post_processMethod.
julia
post_process(s::MainSolver)

Launch a series of tasks to round-up a solving run, for instance, export a run's info.

source


# LocalSearchSolvers.remote_dispatch!Method.
julia
remote_dispatch!(solver)

Starts the LeadSolvers attached to the MainSolver.

source


# LocalSearchSolvers.remote_stop!Method.
julia
remote_stop!!(solver)

Fetch the pool of solutions from LeadSolvers and merge it into the MainSolver.

source


# LocalSearchSolvers.solutionMethod.
julia
solution(s)

Return the only/best known solution of a satisfaction/optimization model.

source


# LocalSearchSolvers.solve_for_loop!Method.
julia
solve_for_loop!(solver, stop, sat, iter)

First loop in the solving process that starts LeadSolvers from the MainSolver, and _SubSolvers from each MetaSolver.

source


# LocalSearchSolvers.solve_while_loop!Method.
julia
solve_while_loop!(s, )

Search the space of configurations.

source


# LocalSearchSolvers.specialize!Method.
julia
specialize!(solver)

Replace the model of solver by one with specialized types (variables, constraints, objectives).

source


# LocalSearchSolvers.specializeMethod.
julia
specialize(m::M) where M <: Union{Model, AbstractSolver}

Specialize the structure of a model to avoid dynamic type attribution at runtime.

source


# LocalSearchSolvers.statusMethod.
julia
status(solver)

Return the status of a MainSolver.

source


# LocalSearchSolvers.stop_while_loopMethod.
julia
stop_while_loop()

Check the stop conditions of the solve! while inner loop.

source


# LocalSearchSolvers.tabu_listMethod.
julia
_tabu(s::S) where S <: Union{_State, AbstractSolver}

Access the list of tabu variables.

source


# LocalSearchSolvers.tabu_valueMethod.
julia
_tabu(s::S, x) where S <: Union{_State, AbstractSolver}

Return the tabu value of variable x.

source


# LocalSearchSolvers.variable!Function.
julia
variable!(m::M, d) where M <: Union{Model, AbstractSolver}

Add a variable with domain d to m.

source


# LocalSearchSolvers.variableMethod.
julia
variable(values::AbstractVector{T}, name::AbstractString; domain = :set) where T <: Number
-variable(domain::AbstractDomain, name::AbstractString) where D <: AbstractDomain

Construct a variable with discrete domain. See the domain method for other options.

julia
d = domain([1,2,3,4], types = :indices)
-x1 = variable(d, "x1")
-x2 = variable([-89,56,28], "x2", domain = :indices)

source


- - - - \ No newline at end of file

ZW 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�zBE;A6`RoYnYVbGchb9$^iIU2 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 diff --git a/dev/assets/inter-roman-vietnamese.ClpjcLMQ.woff2 b/dev/assets/inter-roman-vietnamese.ClpjcLMQ.woff2 deleted file mode 100644 index 5a9f9cb9ca0cd78b6ea2f3e5c9d2838dc8895598..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8492 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 a!Vc~9U7SGB8$q3Ii#9CnAx#qS0RRAsKuhfa diff --git a/dev/assets/learning_aggregation.md.5RLMQ4Bd.js b/dev/assets/learning_aggregation.md.5RLMQ4Bd.js deleted file mode 100644 index 2ab6dab..0000000 --- a/dev/assets/learning_aggregation.md.5RLMQ4Bd.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as e,o as i,a7 as t}from"./chunks/framework.aA95Gx5L.js";const b=JSON.parse('{"title":"Aggregation Layer","description":"","frontmatter":{},"headers":[],"relativePath":"learning/aggregation.md","filePath":"learning/aggregation.md","lastUpdated":null}'),o={name:"learning/aggregation.md"},r=t('

+# ConstraintCommons.AutomatonType. + + + + +```julia +Automaton{S, T, F <: Union{S, Vector{S}, Set{S}}} <: AbstractAutomaton +``` + + +A minimal implementation of a deterministic automaton structure. + + +[source](https://github.com/JuliaConstraints/ConstraintCommons.jl/blob/v0.2.1/src/automata.jl#L9-L13) + +